Files
langgraph/test_studio/test_hitl.ipynb
2025-05-21 14:01:48 -07:00

70 KiB
Raw Permalink Blame History

In [ ]:
! pip install -U langchain langchain_openai langchain_core langgraph

Agent with HITL

In [1]:
from langchain.tools import tool
from langgraph.prebuilt import create_react_agent
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.prebuilt.interrupt import HumanInterruptConfig, InterruptToolNode

from langchain.chat_models import init_chat_model
llm = init_chat_model("openai:gpt-4.1", temperature=0)

@tool
def write_email(to: str, subject: str, content: str) -> str:
    """Write and send an email."""
    # Placeholder response - in real app would send email
    return f"Email sent to {to} with subject '{subject}' and content: {content}"

agent = create_react_agent(
    llm,
    tools=[write_email],
    prompt="You are a helpful email assistant.",
    post_model_hook=InterruptToolNode(
        write_email=HumanInterruptConfig(
              allow_accept=True,
              allow_edit=True,
              allow_ignore=True,
              allow_respond=True,
          )
    ),
    checkpointer=InMemorySaver(),
)
In [2]:
from IPython.display import Image
Image(agent.get_graph(xray=True).draw_mermaid_png())
Out [2]:

Accepting the tool call

In [13]:
msg = [{"role": "user", "content": "Draft an email response to my boss (boss@company.ai) about tomorrow's meeting on the Interrupt Conference"}]

import uuid
thread_id_2 = uuid.uuid4()
thread_config_2 = {"configurable": {"thread_id": thread_id_2}}

# Run the graph until a tool call that we choose to interrupt
print("Running the graph until the first interrupt...")
for chunk in agent.stream({"messages": msg}, config=thread_config_2):
    if '__interrupt__' in chunk:
        Interrupt_Object = chunk['__interrupt__'][0]
        print("\nINTERRUPT OBJECT:")
        print(f"Action Request: {Interrupt_Object.value[0]['action_request']}")
    else:
        print(chunk)
Running the graph until the first interrupt...
{'agent': {'messages': [AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_5kiEF7KNC5d2uzF5vWxJZJJM', 'function': {'arguments': '{"to":"boss@company.ai","subject":"Re: Tomorrow\'s Meeting","content":"Dear [Boss\'s Name],\\n\\nThank you for the reminder about tomorrow\'s meeting. I confirm my attendance and look forward to discussing the agenda items. Please let me know if there is anything specific you would like me to prepare or bring to the meeting.\\n\\nBest regards,\\n[Your Name]"}', 'name': 'write_email'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 91, 'prompt_tokens': 75, 'total_tokens': 166, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-2025-04-14', 'system_fingerprint': 'fp_2d9626f3cf', 'id': 'chatcmpl-BZixGJrtdvoltumannmwngZr1ohFj', 'service_tier': 'default', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run--8b3a1554-65f8-4e7a-9cad-f05d44422856-0', tool_calls=[{'name': 'write_email', 'args': {'to': 'boss@company.ai', 'subject': "Re: Tomorrow's Meeting", 'content': "Dear [Boss's Name],\n\nThank you for the reminder about tomorrow's meeting. I confirm my attendance and look forward to discussing the agenda items. Please let me know if there is anything specific you would like me to prepare or bring to the meeting.\n\nBest regards,\n[Your Name]"}, 'id': 'call_5kiEF7KNC5d2uzF5vWxJZJJM', 'type': 'tool_call'}], usage_metadata={'input_tokens': 75, 'output_tokens': 91, 'total_tokens': 166, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}

INTERRUPT OBJECT:
Action Request: {'action': 'write_email', 'args': {'to': 'boss@company.ai', 'subject': "Re: Tomorrow's Meeting", 'content': "Dear [Boss's Name],\n\nThank you for the reminder about tomorrow's meeting. I confirm my attendance and look forward to discussing the agenda items. Please let me know if there is anything specific you would like me to prepare or bring to the meeting.\n\nBest regards,\n[Your Name]"}}
In [14]:
from langgraph.types import Command

print(f"\nSimulating user accepting the {Interrupt_Object.value[0]['action_request']} tool call...")
for chunk in agent.stream(Command(resume=[{"type": "accept"}]), config=thread_config_2):
    print(chunk)
Simulating user accepting the {'action': 'write_email', 'args': {'to': 'boss@company.ai', 'subject': "Re: Tomorrow's Meeting", 'content': "Dear [Boss's Name],\n\nThank you for the reminder about tomorrow's meeting. I confirm my attendance and look forward to discussing the agenda items. Please let me know if there is anything specific you would like me to prepare or bring to the meeting.\n\nBest regards,\n[Your Name]"}} tool call...
{'post_model_hook': {'messages': [AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_5kiEF7KNC5d2uzF5vWxJZJJM', 'function': {'arguments': '{"to":"boss@company.ai","subject":"Re: Tomorrow\'s Meeting","content":"Dear [Boss\'s Name],\\n\\nThank you for the reminder about tomorrow\'s meeting. I confirm my attendance and look forward to discussing the agenda items. Please let me know if there is anything specific you would like me to prepare or bring to the meeting.\\n\\nBest regards,\\n[Your Name]"}', 'name': 'write_email'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 91, 'prompt_tokens': 75, 'total_tokens': 166, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-2025-04-14', 'system_fingerprint': 'fp_2d9626f3cf', 'id': 'chatcmpl-BZixGJrtdvoltumannmwngZr1ohFj', 'service_tier': 'default', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run--8b3a1554-65f8-4e7a-9cad-f05d44422856-0', tool_calls=[{'name': 'write_email', 'args': {'to': 'boss@company.ai', 'subject': "Re: Tomorrow's Meeting", 'content': "Dear [Boss's Name],\n\nThank you for the reminder about tomorrow's meeting. I confirm my attendance and look forward to discussing the agenda items. Please let me know if there is anything specific you would like me to prepare or bring to the meeting.\n\nBest regards,\n[Your Name]"}, 'id': 'call_5kiEF7KNC5d2uzF5vWxJZJJM', 'type': 'tool_call'}], usage_metadata={'input_tokens': 75, 'output_tokens': 91, 'total_tokens': 166, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}
{'tools': {'messages': [ToolMessage(content="Email sent to boss@company.ai with subject 'Re: Tomorrow's Meeting' and content: Dear [Boss's Name],\n\nThank you for the reminder about tomorrow's meeting. I confirm my attendance and look forward to discussing the agenda items. Please let me know if there is anything specific you would like me to prepare or bring to the meeting.\n\nBest regards,\n[Your Name]", name='write_email', id='5e704cf6-087c-46c3-a56d-25d8b76eceaf', tool_call_id='call_5kiEF7KNC5d2uzF5vWxJZJJM')]}}
{'agent': {'messages': [AIMessage(content="Here's a draft for your response:\n\nSubject: Re: Tomorrow's Meeting\n\nDear [Boss's Name],\n\nThank you for the reminder about tomorrow's meeting. I confirm my attendance and look forward to discussing the agenda items. Please let me know if there is anything specific you would like me to prepare or bring to the meeting.\n\nBest regards,  \n[Your Name]\n\nLet me know if you'd like to personalize or adjust this message further!", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 88, 'prompt_tokens': 250, 'total_tokens': 338, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-2025-04-14', 'system_fingerprint': 'fp_2d9626f3cf', 'id': 'chatcmpl-BZixKstGdPPIiiJo7gmBRv8gfatkF', 'service_tier': 'default', 'finish_reason': 'stop', 'logprobs': None}, id='run--39edb4bc-e81f-47f8-abdf-d0b2f31c2be1-0', usage_metadata={'input_tokens': 250, 'output_tokens': 88, 'total_tokens': 338, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}
{'post_model_hook': {'messages': [AIMessage(content="Here's a draft for your response:\n\nSubject: Re: Tomorrow's Meeting\n\nDear [Boss's Name],\n\nThank you for the reminder about tomorrow's meeting. I confirm my attendance and look forward to discussing the agenda items. Please let me know if there is anything specific you would like me to prepare or bring to the meeting.\n\nBest regards,  \n[Your Name]\n\nLet me know if you'd like to personalize or adjust this message further!", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 88, 'prompt_tokens': 250, 'total_tokens': 338, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-2025-04-14', 'system_fingerprint': 'fp_2d9626f3cf', 'id': 'chatcmpl-BZixKstGdPPIiiJo7gmBRv8gfatkF', 'service_tier': 'default', 'finish_reason': 'stop', 'logprobs': None}, id='run--39edb4bc-e81f-47f8-abdf-d0b2f31c2be1-0', usage_metadata={'input_tokens': 250, 'output_tokens': 88, 'total_tokens': 338, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}
In [15]:
state = agent.get_state(thread_config_2)
for m in state.values['messages']:
    m.pretty_print()
================================ Human Message =================================

Draft a response to my boss (boss@company.ai) about tomorrow's meeting.
================================== Ai Message ==================================
Tool Calls:
  write_email (call_5kiEF7KNC5d2uzF5vWxJZJJM)
 Call ID: call_5kiEF7KNC5d2uzF5vWxJZJJM
  Args:
    to: boss@company.ai
    subject: Re: Tomorrow's Meeting
    content: Dear [Boss's Name],

Thank you for the reminder about tomorrow's meeting. I confirm my attendance and look forward to discussing the agenda items. Please let me know if there is anything specific you would like me to prepare or bring to the meeting.

Best regards,
[Your Name]
================================= Tool Message =================================
Name: write_email

Email sent to boss@company.ai with subject 'Re: Tomorrow's Meeting' and content: Dear [Boss's Name],

Thank you for the reminder about tomorrow's meeting. I confirm my attendance and look forward to discussing the agenda items. Please let me know if there is anything specific you would like me to prepare or bring to the meeting.

Best regards,
[Your Name]
================================== Ai Message ==================================

Here's a draft for your response:

Subject: Re: Tomorrow's Meeting

Dear [Boss's Name],

Thank you for the reminder about tomorrow's meeting. I confirm my attendance and look forward to discussing the agenda items. Please let me know if there is anything specific you would like me to prepare or bring to the meeting.

Best regards,  
[Your Name]

Let me know if you'd like to personalize or adjust this message further!

Responding to the tool call

In [17]:
# Create a new thread for testing the respond action
thread_id_3 = uuid.uuid4()
thread_config_3 = {"configurable": {"thread_id": thread_id_3}}

# Run the graph until a tool call that we choose to interrupt
msg = [{"role": "user", "content": "Draft an email response to my boss (boss@company.ai) about tomorrow's meeting on the Interrupt Conference."}]
print("Running the graph until the first interrupt...")
for chunk in agent.stream({"messages": msg}, config=thread_config_3):
    if '__interrupt__' in chunk:
        Interrupt_Object = chunk['__interrupt__'][0]
        print("\nINTERRUPT OBJECT:")
        print(f"Action Request: {Interrupt_Object.value[0]['action_request']}")
    else:
        print(chunk)
Running the graph until the first interrupt...
{'agent': {'messages': [AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_IByJungo4tOleyF4lDEcBu7R', 'function': {'arguments': '{"to":"boss@company.ai","subject":"Re: Tomorrows Meeting on the Interrupt Conference","content":"Dear [Boss\'s Name],\\n\\nThank you for the reminder about tomorrows meeting regarding the Interrupt Conference. I have reviewed the agenda and am prepared to discuss the key points. Please let me know if there are any specific topics or materials you would like me to focus on or bring to the meeting.\\n\\nLooking forward to our discussion.\\n\\nBest regards,\\n[Your Name]"}', 'name': 'write_email'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 112, 'prompt_tokens': 80, 'total_tokens': 192, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-2025-04-14', 'system_fingerprint': 'fp_2d9626f3cf', 'id': 'chatcmpl-BZiyEpGskLW9SAlSUSitxGWghl52E', 'service_tier': 'default', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run--4d4b1ce5-5358-4e6e-a433-07e4b413c043-0', tool_calls=[{'name': 'write_email', 'args': {'to': 'boss@company.ai', 'subject': 'Re: Tomorrows Meeting on the Interrupt Conference', 'content': "Dear [Boss's Name],\n\nThank you for the reminder about tomorrows meeting regarding the Interrupt Conference. I have reviewed the agenda and am prepared to discuss the key points. Please let me know if there are any specific topics or materials you would like me to focus on or bring to the meeting.\n\nLooking forward to our discussion.\n\nBest regards,\n[Your Name]"}, 'id': 'call_IByJungo4tOleyF4lDEcBu7R', 'type': 'tool_call'}], usage_metadata={'input_tokens': 80, 'output_tokens': 112, 'total_tokens': 192, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}

INTERRUPT OBJECT:
Action Request: {'action': 'write_email', 'args': {'to': 'boss@company.ai', 'subject': 'Re: Tomorrows Meeting on the Interrupt Conference', 'content': "Dear [Boss's Name],\n\nThank you for the reminder about tomorrows meeting regarding the Interrupt Conference. I have reviewed the agenda and am prepared to discuss the key points. Please let me know if there are any specific topics or materials you would like me to focus on or bring to the meeting.\n\nLooking forward to our discussion.\n\nBest regards,\n[Your Name]"}}
In [18]:
# Now simulate user responding to the tool call with feedback
print("\nSimulating user responding to the tool call with feedback...")
for chunk in agent.stream(Command(resume={"type": "response", "args": "Shorter and less formal."}), config=thread_config_3):
    print(chunk)
Simulating user responding to the tool call with feedback...
{'post_model_hook': {'messages': [AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_IByJungo4tOleyF4lDEcBu7R', 'function': {'arguments': '{"to":"boss@company.ai","subject":"Re: Tomorrows Meeting on the Interrupt Conference","content":"Dear [Boss\'s Name],\\n\\nThank you for the reminder about tomorrows meeting regarding the Interrupt Conference. I have reviewed the agenda and am prepared to discuss the key points. Please let me know if there are any specific topics or materials you would like me to focus on or bring to the meeting.\\n\\nLooking forward to our discussion.\\n\\nBest regards,\\n[Your Name]"}', 'name': 'write_email'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 112, 'prompt_tokens': 80, 'total_tokens': 192, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-2025-04-14', 'system_fingerprint': 'fp_2d9626f3cf', 'id': 'chatcmpl-BZiyEpGskLW9SAlSUSitxGWghl52E', 'service_tier': 'default', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run--4d4b1ce5-5358-4e6e-a433-07e4b413c043-0', tool_calls=[{'name': 'write_email', 'args': {'to': 'boss@company.ai', 'subject': 'Re: Tomorrows Meeting on the Interrupt Conference', 'content': "Dear [Boss's Name],\n\nThank you for the reminder about tomorrows meeting regarding the Interrupt Conference. I have reviewed the agenda and am prepared to discuss the key points. Please let me know if there are any specific topics or materials you would like me to focus on or bring to the meeting.\n\nLooking forward to our discussion.\n\nBest regards,\n[Your Name]"}, 'id': 'call_IByJungo4tOleyF4lDEcBu7R', 'type': 'tool_call'}], usage_metadata={'input_tokens': 80, 'output_tokens': 112, 'total_tokens': 192, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}), ToolMessage(content='Shorter and less formal.', name='write_email', id='5eb49891-0d42-40ec-aa6b-a428853ee7f8', tool_call_id='call_IByJungo4tOleyF4lDEcBu7R', status='error')]}}
{'agent': {'messages': [AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_1MensMD3ArJUJqgBXv1AQAvQ', 'function': {'arguments': '{"to":"boss@company.ai","subject":"Re: Tomorrows Meeting on the Interrupt Conference","content":"Thanks for the heads up about tomorrows meeting on the Interrupt Conference. Ill be ready! Let me know if theres anything specific you want me to cover.\\n\\nThanks,\\n[Your Name]"}', 'name': 'write_email'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 74, 'prompt_tokens': 206, 'total_tokens': 280, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-2025-04-14', 'system_fingerprint': 'fp_2d9626f3cf', 'id': 'chatcmpl-BZiybdSZYy4AdPZqlnxNuRNqMpKOP', 'service_tier': 'default', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run--e87c93af-ca42-404a-b0ea-6fbce50d99c3-0', tool_calls=[{'name': 'write_email', 'args': {'to': 'boss@company.ai', 'subject': 'Re: Tomorrows Meeting on the Interrupt Conference', 'content': 'Thanks for the heads up about tomorrows meeting on the Interrupt Conference. Ill be ready! Let me know if theres anything specific you want me to cover.\n\nThanks,\n[Your Name]'}, 'id': 'call_1MensMD3ArJUJqgBXv1AQAvQ', 'type': 'tool_call'}], usage_metadata={'input_tokens': 206, 'output_tokens': 74, 'total_tokens': 280, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}
{'__interrupt__': (Interrupt(value=[{'action_request': {'action': 'write_email', 'args': {'to': 'boss@company.ai', 'subject': 'Re: Tomorrows Meeting on the Interrupt Conference', 'content': 'Thanks for the heads up about tomorrows meeting on the Interrupt Conference. Ill be ready! Let me know if theres anything specific you want me to cover.\n\nThanks,\n[Your Name]'}}, 'config': {'allow_accept': True, 'allow_edit': True, 'allow_ignore': True, 'allow_respond': True}, 'description': 'Please review tool call for `write_email` before execution.'}], resumable=True, ns=['post_model_hook:fe1a666b-0873-992f-01ba-a5ba1849aac6']),)}
In [19]:
print(f"\nSimulating user accepting the {Interrupt_Object.value[0]['action_request']} tool call...")
for chunk in agent.stream(Command(resume=[{"type": "accept"}]), config=thread_config_3):
    print(chunk)
Simulating user accepting the {'action': 'write_email', 'args': {'to': 'boss@company.ai', 'subject': 'Re: Tomorrows Meeting on the Interrupt Conference', 'content': "Dear [Boss's Name],\n\nThank you for the reminder about tomorrows meeting regarding the Interrupt Conference. I have reviewed the agenda and am prepared to discuss the key points. Please let me know if there are any specific topics or materials you would like me to focus on or bring to the meeting.\n\nLooking forward to our discussion.\n\nBest regards,\n[Your Name]"}} tool call...
{'post_model_hook': {'messages': [AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_1MensMD3ArJUJqgBXv1AQAvQ', 'function': {'arguments': '{"to":"boss@company.ai","subject":"Re: Tomorrows Meeting on the Interrupt Conference","content":"Thanks for the heads up about tomorrows meeting on the Interrupt Conference. Ill be ready! Let me know if theres anything specific you want me to cover.\\n\\nThanks,\\n[Your Name]"}', 'name': 'write_email'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 74, 'prompt_tokens': 206, 'total_tokens': 280, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-2025-04-14', 'system_fingerprint': 'fp_2d9626f3cf', 'id': 'chatcmpl-BZiybdSZYy4AdPZqlnxNuRNqMpKOP', 'service_tier': 'default', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run--e87c93af-ca42-404a-b0ea-6fbce50d99c3-0', tool_calls=[{'name': 'write_email', 'args': {'to': 'boss@company.ai', 'subject': 'Re: Tomorrows Meeting on the Interrupt Conference', 'content': 'Thanks for the heads up about tomorrows meeting on the Interrupt Conference. Ill be ready! Let me know if theres anything specific you want me to cover.\n\nThanks,\n[Your Name]'}, 'id': 'call_1MensMD3ArJUJqgBXv1AQAvQ', 'type': 'tool_call'}], usage_metadata={'input_tokens': 206, 'output_tokens': 74, 'total_tokens': 280, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}
{'tools': {'messages': [ToolMessage(content="Email sent to boss@company.ai with subject 'Re: Tomorrows Meeting on the Interrupt Conference' and content: Thanks for the heads up about tomorrows meeting on the Interrupt Conference. Ill be ready! Let me know if theres anything specific you want me to cover.\n\nThanks,\n[Your Name]", name='write_email', id='95919d1e-4318-47d3-bf01-d5022dbf6463', tool_call_id='call_1MensMD3ArJUJqgBXv1AQAvQ')]}}
{'agent': {'messages': [AIMessage(content="Here's a shorter and less formal response you can use:\n\nThanks for the heads up about tomorrows meeting on the Interrupt Conference. Ill be ready! Let me know if theres anything specific you want me to cover.\n\nThanks,\n[Your Name]", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 51, 'prompt_tokens': 350, 'total_tokens': 401, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-2025-04-14', 'system_fingerprint': 'fp_2d9626f3cf', 'id': 'chatcmpl-BZiz56f01zrr2kttIeXyHbYQ1XPRR', 'service_tier': 'default', 'finish_reason': 'stop', 'logprobs': None}, id='run--86ad576a-65a5-4575-8d76-dc3cfd5fe378-0', usage_metadata={'input_tokens': 350, 'output_tokens': 51, 'total_tokens': 401, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}
{'post_model_hook': {'messages': [AIMessage(content="Here's a shorter and less formal response you can use:\n\nThanks for the heads up about tomorrows meeting on the Interrupt Conference. Ill be ready! Let me know if theres anything specific you want me to cover.\n\nThanks,\n[Your Name]", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 51, 'prompt_tokens': 350, 'total_tokens': 401, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-2025-04-14', 'system_fingerprint': 'fp_2d9626f3cf', 'id': 'chatcmpl-BZiz56f01zrr2kttIeXyHbYQ1XPRR', 'service_tier': 'default', 'finish_reason': 'stop', 'logprobs': None}, id='run--86ad576a-65a5-4575-8d76-dc3cfd5fe378-0', usage_metadata={'input_tokens': 350, 'output_tokens': 51, 'total_tokens': 401, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}
In [20]:
# Let's check the state after responding
state = agent.get_state(thread_config_3)
for m in state.values['messages']:
    m.pretty_print()
================================ Human Message =================================

Draft an email response to my boss (boss@company.ai) about tomorrow's meeting on the Interrupt Conference.
================================== Ai Message ==================================
Tool Calls:
  write_email (call_IByJungo4tOleyF4lDEcBu7R)
 Call ID: call_IByJungo4tOleyF4lDEcBu7R
  Args:
    to: boss@company.ai
    subject: Re: Tomorrows Meeting on the Interrupt Conference
    content: Dear [Boss's Name],

Thank you for the reminder about tomorrows meeting regarding the Interrupt Conference. I have reviewed the agenda and am prepared to discuss the key points. Please let me know if there are any specific topics or materials you would like me to focus on or bring to the meeting.

Looking forward to our discussion.

Best regards,
[Your Name]
================================= Tool Message =================================
Name: write_email

Shorter and less formal.
================================== Ai Message ==================================
Tool Calls:
  write_email (call_1MensMD3ArJUJqgBXv1AQAvQ)
 Call ID: call_1MensMD3ArJUJqgBXv1AQAvQ
  Args:
    to: boss@company.ai
    subject: Re: Tomorrows Meeting on the Interrupt Conference
    content: Thanks for the heads up about tomorrows meeting on the Interrupt Conference. Ill be ready! Let me know if theres anything specific you want me to cover.

Thanks,
[Your Name]
================================= Tool Message =================================
Name: write_email

Email sent to boss@company.ai with subject 'Re: Tomorrows Meeting on the Interrupt Conference' and content: Thanks for the heads up about tomorrows meeting on the Interrupt Conference. Ill be ready! Let me know if theres anything specific you want me to cover.

Thanks,
[Your Name]
================================== Ai Message ==================================

Here's a shorter and less formal response you can use:

Thanks for the heads up about tomorrows meeting on the Interrupt Conference. Ill be ready! Let me know if theres anything specific you want me to cover.

Thanks,
[Your Name]

Editing the tool call

In [24]:
# Create a new thread for testing the edit action
thread_id_4 = uuid.uuid4()
thread_config_4 = {"configurable": {"thread_id": thread_id_4}}

# Run the graph until a tool call that we choose to interrupt
msg = [{"role": "user", "content": "Draft a response to my boss (boss@company.ai) about tomorrow's meeting on the Interrupt Conference. Call the tool write_email."}]
print("Running the graph until the first interrupt...")
for chunk in agent.stream({"messages": msg}, config=thread_config_4):
    if '__interrupt__' in chunk:
        Interrupt_Object = chunk['__interrupt__'][0]
        print("\nINTERRUPT OBJECT:")
        print(f"Action Request: {Interrupt_Object.value[0]['action_request']}")
    else:
        print(chunk)
Running the graph until the first interrupt...
{'agent': {'messages': [AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_nm339QV5eqaBLC1WU5xFmiQM', 'function': {'arguments': '{"to":"boss@company.ai","subject":"Re: Tomorrow\'s Meeting on the Interrupt Conference","content":"Hi,\\n\\nThank you for scheduling the meeting regarding the Interrupt Conference. I look forward to discussing the agenda and any preparations needed for the event. Please let me know if there are specific topics or materials I should review beforehand.\\n\\nBest regards,\\n\\n[Your Name]"}', 'name': 'write_email'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 89, 'prompt_tokens': 85, 'total_tokens': 174, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-2025-04-14', 'system_fingerprint': 'fp_2d9626f3cf', 'id': 'chatcmpl-BZj22DO010whYnbgcVhicrNAsKxrs', 'service_tier': 'default', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run--d7568673-1fb8-40ec-b72e-f838bfd767e8-0', tool_calls=[{'name': 'write_email', 'args': {'to': 'boss@company.ai', 'subject': "Re: Tomorrow's Meeting on the Interrupt Conference", 'content': 'Hi,\n\nThank you for scheduling the meeting regarding the Interrupt Conference. I look forward to discussing the agenda and any preparations needed for the event. Please let me know if there are specific topics or materials I should review beforehand.\n\nBest regards,\n\n[Your Name]'}, 'id': 'call_nm339QV5eqaBLC1WU5xFmiQM', 'type': 'tool_call'}], usage_metadata={'input_tokens': 85, 'output_tokens': 89, 'total_tokens': 174, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}

INTERRUPT OBJECT:
Action Request: {'action': 'write_email', 'args': {'to': 'boss@company.ai', 'subject': "Re: Tomorrow's Meeting on the Interrupt Conference", 'content': 'Hi,\n\nThank you for scheduling the meeting regarding the Interrupt Conference. I look forward to discussing the agenda and any preparations needed for the event. Please let me know if there are specific topics or materials I should review beforehand.\n\nBest regards,\n\n[Your Name]'}}
In [25]:
# Now simulate user editing the write_email tool call
print("\nSimulating user editing the write_email tool call...")
edited_email_args = {
    "action": "write_email",
    "args": {
        "to": "boss@company.ai",
        "subject": "Meeting tomorrow",
        "content": "Hi boss,\n\nI'll be at the Interrupt Conference meeting tomorrow and will bring my notes. Looking forward to discussing our plans!\n\nThanks,\nMe"
    }
}

for chunk in agent.stream(Command(resume={"type": "edit", "args": edited_email_args}), config=thread_config_4):
    print(chunk)
Simulating user editing the write_email tool call...
{'post_model_hook': {'messages': [AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_nm339QV5eqaBLC1WU5xFmiQM', 'function': {'arguments': '{"to":"boss@company.ai","subject":"Re: Tomorrow\'s Meeting on the Interrupt Conference","content":"Hi,\\n\\nThank you for scheduling the meeting regarding the Interrupt Conference. I look forward to discussing the agenda and any preparations needed for the event. Please let me know if there are specific topics or materials I should review beforehand.\\n\\nBest regards,\\n\\n[Your Name]"}', 'name': 'write_email'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 89, 'prompt_tokens': 85, 'total_tokens': 174, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-2025-04-14', 'system_fingerprint': 'fp_2d9626f3cf', 'id': 'chatcmpl-BZj22DO010whYnbgcVhicrNAsKxrs', 'service_tier': 'default', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run--d7568673-1fb8-40ec-b72e-f838bfd767e8-0', tool_calls=[{'args': {'to': 'boss@company.ai', 'subject': 'Meeting tomorrow', 'content': "Hi boss,\n\nI'll be at the Interrupt Conference meeting tomorrow and will bring my notes. Looking forward to discussing our plans!\n\nThanks,\nMe"}, 'name': 'write_email', 'id': 'call_nm339QV5eqaBLC1WU5xFmiQM', 'type': 'tool_call'}], usage_metadata={'input_tokens': 85, 'output_tokens': 89, 'total_tokens': 174, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}
{'tools': {'messages': [ToolMessage(content="Email sent to boss@company.ai with subject 'Meeting tomorrow' and content: Hi boss,\n\nI'll be at the Interrupt Conference meeting tomorrow and will bring my notes. Looking forward to discussing our plans!\n\nThanks,\nMe", name='write_email', id='bbef207d-f2ed-4977-ada8-188da0eae26d', tool_call_id='call_nm339QV5eqaBLC1WU5xFmiQM')]}}
{'agent': {'messages': [AIMessage(content="I've drafted and sent a response to your boss confirming your attendance at tomorrow's Interrupt Conference meeting and mentioning you'll bring your notes. If you'd like to adjust the message or add more details, let me know!", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 42, 'prompt_tokens': 193, 'total_tokens': 235, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-2025-04-14', 'system_fingerprint': 'fp_2d9626f3cf', 'id': 'chatcmpl-BZj286vw8MFss1KNWXIEYU65oyGuZ', 'service_tier': 'default', 'finish_reason': 'stop', 'logprobs': None}, id='run--31b1861b-a69b-41fd-b2b4-42b15846a91b-0', usage_metadata={'input_tokens': 193, 'output_tokens': 42, 'total_tokens': 235, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}
{'post_model_hook': {'messages': [AIMessage(content="I've drafted and sent a response to your boss confirming your attendance at tomorrow's Interrupt Conference meeting and mentioning you'll bring your notes. If you'd like to adjust the message or add more details, let me know!", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 42, 'prompt_tokens': 193, 'total_tokens': 235, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-2025-04-14', 'system_fingerprint': 'fp_2d9626f3cf', 'id': 'chatcmpl-BZj286vw8MFss1KNWXIEYU65oyGuZ', 'service_tier': 'default', 'finish_reason': 'stop', 'logprobs': None}, id='run--31b1861b-a69b-41fd-b2b4-42b15846a91b-0', usage_metadata={'input_tokens': 193, 'output_tokens': 42, 'total_tokens': 235, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}
In [26]:
# Let's check the state after editing
state = agent.get_state(thread_config_4)
for m in state.values['messages']:
    m.pretty_print()
================================ Human Message =================================

Draft a response to my boss (boss@company.ai) about tomorrow's meeting on the Interrupt Conference. Call the tool write_email.
================================== Ai Message ==================================
Tool Calls:
  write_email (call_nm339QV5eqaBLC1WU5xFmiQM)
 Call ID: call_nm339QV5eqaBLC1WU5xFmiQM
  Args:
    to: boss@company.ai
    subject: Meeting tomorrow
    content: Hi boss,

I'll be at the Interrupt Conference meeting tomorrow and will bring my notes. Looking forward to discussing our plans!

Thanks,
Me
================================= Tool Message =================================
Name: write_email

Email sent to boss@company.ai with subject 'Meeting tomorrow' and content: Hi boss,

I'll be at the Interrupt Conference meeting tomorrow and will bring my notes. Looking forward to discussing our plans!

Thanks,
Me
================================== Ai Message ==================================

I've drafted and sent a response to your boss confirming your attendance at tomorrow's Interrupt Conference meeting and mentioning you'll bring your notes. If you'd like to adjust the message or add more details, let me know!

Ignoring the tool call

In [28]:
# Create a new thread for testing the ignore action
thread_id_5 = uuid.uuid4()
thread_config_5 = {"configurable": {"thread_id": thread_id_5}}

# Run the graph until a tool call that we choose to interrupt
msg = [{"role": "user", "content": "Draft a response to my boss (boss@company.ai) about tomorrow's meeting on the Interrupt Conference. Call the tool write_email."}]
print("Running the graph until the first interrupt...")
for chunk in agent.stream({"messages": msg}, config=thread_config_5):
    if '__interrupt__' in chunk:
        Interrupt_Object = chunk['__interrupt__'][0]
        print("\nINTERRUPT OBJECT:")
        print(f"Action Request: {Interrupt_Object.value[0]['action_request']}")
    else:
        print(chunk)
Running the graph until the first interrupt...
{'agent': {'messages': [AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_kqtyP1N3Hxe0Eovxfuh7xWIl', 'function': {'arguments': '{"to":"boss@company.ai","subject":"Re: Tomorrow\'s Meeting on the Interrupt Conference","content":"Hi,\\n\\nThank you for scheduling the meeting regarding the Interrupt Conference. I look forward to discussing the agenda and any preparations needed for the event. Please let me know if there are specific topics or materials youd like me to review beforehand.\\n\\nBest regards,\\n\\n[Your Name]"}', 'name': 'write_email'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 92, 'prompt_tokens': 85, 'total_tokens': 177, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-2025-04-14', 'system_fingerprint': 'fp_2d9626f3cf', 'id': 'chatcmpl-BZj6oHQAIqdXr2SXd5HMkDx9S6DvQ', 'service_tier': 'default', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run--0dbe8a85-7032-403c-a7b5-edd5bcb1e21d-0', tool_calls=[{'name': 'write_email', 'args': {'to': 'boss@company.ai', 'subject': "Re: Tomorrow's Meeting on the Interrupt Conference", 'content': 'Hi,\n\nThank you for scheduling the meeting regarding the Interrupt Conference. I look forward to discussing the agenda and any preparations needed for the event. Please let me know if there are specific topics or materials youd like me to review beforehand.\n\nBest regards,\n\n[Your Name]'}, 'id': 'call_kqtyP1N3Hxe0Eovxfuh7xWIl', 'type': 'tool_call'}], usage_metadata={'input_tokens': 85, 'output_tokens': 92, 'total_tokens': 177, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}

INTERRUPT OBJECT:
Action Request: {'action': 'write_email', 'args': {'to': 'boss@company.ai', 'subject': "Re: Tomorrow's Meeting on the Interrupt Conference", 'content': 'Hi,\n\nThank you for scheduling the meeting regarding the Interrupt Conference. I look forward to discussing the agenda and any preparations needed for the event. Please let me know if there are specific topics or materials youd like me to review beforehand.\n\nBest regards,\n\n[Your Name]'}}
In [29]:
# Now simulate user ignoring the tool call
print("\nSimulating user ignoring the tool call...")
for chunk in agent.stream(Command(resume={"type": "ignore"}), config=thread_config_5):
    print(chunk)
Simulating user ignoring the tool call...
{'post_model_hook': {'messages': [AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_kqtyP1N3Hxe0Eovxfuh7xWIl', 'function': {'arguments': '{"to":"boss@company.ai","subject":"Re: Tomorrow\'s Meeting on the Interrupt Conference","content":"Hi,\\n\\nThank you for scheduling the meeting regarding the Interrupt Conference. I look forward to discussing the agenda and any preparations needed for the event. Please let me know if there are specific topics or materials youd like me to review beforehand.\\n\\nBest regards,\\n\\n[Your Name]"}', 'name': 'write_email'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 92, 'prompt_tokens': 85, 'total_tokens': 177, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-2025-04-14', 'system_fingerprint': 'fp_2d9626f3cf', 'id': 'chatcmpl-BZj6oHQAIqdXr2SXd5HMkDx9S6DvQ', 'service_tier': 'default', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run--0dbe8a85-7032-403c-a7b5-edd5bcb1e21d-0', tool_calls=[{'name': 'write_email', 'args': {'to': 'boss@company.ai', 'subject': "Re: Tomorrow's Meeting on the Interrupt Conference", 'content': 'Hi,\n\nThank you for scheduling the meeting regarding the Interrupt Conference. I look forward to discussing the agenda and any preparations needed for the event. Please let me know if there are specific topics or materials youd like me to review beforehand.\n\nBest regards,\n\n[Your Name]'}, 'id': 'call_kqtyP1N3Hxe0Eovxfuh7xWIl', 'type': 'tool_call'}], usage_metadata={'input_tokens': 85, 'output_tokens': 92, 'total_tokens': 177, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}), ToolMessage(content='User ignored the tool call for `write_email` with id call_kqtyP1N3Hxe0Eovxfuh7xWIl', name='write_email', id='4112bec6-47dd-4258-8d12-5b35de5181b5', tool_call_id='call_kqtyP1N3Hxe0Eovxfuh7xWIl')]}}
{'agent': {'messages': [AIMessage(content="Heres a draft response you can send to your boss about tomorrows meeting on the Interrupt Conference:\n\nSubject: Re: Tomorrow's Meeting on the Interrupt Conference\n\nHi,\n\nThank you for scheduling the meeting regarding the Interrupt Conference. I look forward to discussing the agenda and any preparations needed for the event. Please let me know if there are specific topics or materials youd like me to review beforehand.\n\nBest regards,\n\n[Your Name]\n\nLet me know if youd like to make any changes or if you want me to send it for you!", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 109, 'prompt_tokens': 215, 'total_tokens': 324, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-2025-04-14', 'system_fingerprint': 'fp_2d9626f3cf', 'id': 'chatcmpl-BZj6vq2l3vylQd8mCSx5PYmSJYj0F', 'service_tier': 'default', 'finish_reason': 'stop', 'logprobs': None}, id='run--e77e7082-9015-4534-b0e8-0cac49e5c9e6-0', usage_metadata={'input_tokens': 215, 'output_tokens': 109, 'total_tokens': 324, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}
{'post_model_hook': {'messages': [AIMessage(content="Heres a draft response you can send to your boss about tomorrows meeting on the Interrupt Conference:\n\nSubject: Re: Tomorrow's Meeting on the Interrupt Conference\n\nHi,\n\nThank you for scheduling the meeting regarding the Interrupt Conference. I look forward to discussing the agenda and any preparations needed for the event. Please let me know if there are specific topics or materials youd like me to review beforehand.\n\nBest regards,\n\n[Your Name]\n\nLet me know if youd like to make any changes or if you want me to send it for you!", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 109, 'prompt_tokens': 215, 'total_tokens': 324, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-2025-04-14', 'system_fingerprint': 'fp_2d9626f3cf', 'id': 'chatcmpl-BZj6vq2l3vylQd8mCSx5PYmSJYj0F', 'service_tier': 'default', 'finish_reason': 'stop', 'logprobs': None}, id='run--e77e7082-9015-4534-b0e8-0cac49e5c9e6-0', usage_metadata={'input_tokens': 215, 'output_tokens': 109, 'total_tokens': 324, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}
In [30]:
# Let's check the state after ignoring
state = agent.get_state(thread_config_5)
print("\nFinal state after ignore action:")
for m in state.values['messages']:
    m.pretty_print()
Final state after ignore action:
================================ Human Message =================================

Draft a response to my boss (boss@company.ai) about tomorrow's meeting on the Interrupt Conference. Call the tool write_email.
================================== Ai Message ==================================
Tool Calls:
  write_email (call_kqtyP1N3Hxe0Eovxfuh7xWIl)
 Call ID: call_kqtyP1N3Hxe0Eovxfuh7xWIl
  Args:
    to: boss@company.ai
    subject: Re: Tomorrow's Meeting on the Interrupt Conference
    content: Hi,

Thank you for scheduling the meeting regarding the Interrupt Conference. I look forward to discussing the agenda and any preparations needed for the event. Please let me know if there are specific topics or materials youd like me to review beforehand.

Best regards,

[Your Name]
================================= Tool Message =================================
Name: write_email

User ignored the tool call for `write_email` with id call_kqtyP1N3Hxe0Eovxfuh7xWIl
================================== Ai Message ==================================

Heres a draft response you can send to your boss about tomorrows meeting on the Interrupt Conference:

Subject: Re: Tomorrow's Meeting on the Interrupt Conference

Hi,

Thank you for scheduling the meeting regarding the Interrupt Conference. I look forward to discussing the agenda and any preparations needed for the event. Please let me know if there are specific topics or materials youd like me to review beforehand.

Best regards,

[Your Name]

Let me know if youd like to make any changes or if you want me to send it for you!
In [ ]: