forked from CopilotKit/CopilotKit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathagent.py
More file actions
135 lines (102 loc) · 5.47 KB
/
Copy pathagent.py
File metadata and controls
135 lines (102 loc) · 5.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
"""Test Human in the Loop Agent"""
from typing import Any, cast
from langgraph.graph import StateGraph, END
from langgraph.graph import MessagesState
from langgraph.checkpoint.memory import MemorySaver
from langchain_core.runnables import RunnableConfig
from langchain_core.messages import HumanMessage, ToolMessage, AIMessage
# from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field
from copilotkit.langchain import (
copilotkit_customize_config, copilotkit_exit, copilotkit_emit_message
)
def get_model():
"""
Get a model based on the environment variable.
"""
# model = os.getenv("MODEL", "openai")
return ChatOpenAI(temperature=0, model="gpt-4o")
# return ChatGoogleGenerativeAI(temperature=0, model="gemini-1.5-pro")
# if model == "openai":
# return ChatOpenAI(temperature=0, model="gpt-4o")
# if model == "anthropic":
# return ChatAnthropic(
# temperature=0,
# model_name="claude-3-5-sonnet-20240620",
# timeout=None,
# stop=None
# )
# raise ValueError("Invalid model specified")
class EmailAgentState(MessagesState):
"""Email Agent State"""
email: str
class EmailTool(BaseModel):
"""
Write an email.
"""
email_draft: str = Field(description="The draft of the email to be written.")
async def draft_email_node(state: EmailAgentState, config: RunnableConfig):
"""
Write an email.
"""
config = copilotkit_customize_config(
config,
emit_tool_calls=True,
)
instructions = "You write emails."
email_model = get_model().bind_tools(
[cast(Any, EmailTool)],
tool_choice="EmailTool"
)
messages = state["messages"]
# if len(messages) > 2:
# messages = messages[:-4]
# print("MESSAGES:")
# for message in messages:
# print(type(message))
# print(message)
# print("----")
response = await email_model.ainvoke([
*messages,
HumanMessage(
content=instructions
)
], config)
# content='' additional_kwargs={'function_call': {'name': 'EmailTool', 'arguments': '{"email_draft": "Dear Sam Altman,\\\\n\\\\nI hope this email finds you well.\\\\n\\\\nI am writing to request a meeting with you to discuss [topic of discussion]. I am [your title/position] at [your company/organization] and I am particularly interested in [area of interest related to OpenAI].\\\\n\\\\nI am available on [list of dates/times]. Please let me know if any of these times work for you or suggest an alternative.\\\\n\\\\nThank you for your time and consideration.\\\\n\\\\nSincerely,\\\\n[Your Name]"}'}} response_metadata={'safety_ratings': [], 'finish_reason': 'STOP'} id='run-69254734-7c90-4743-adab-5e1d8cfe3099' tool_calls=[{'name': 'EmailTool', 'args': {'email_draft': 'Dear Sam Altman,\\n\\nI hope this email finds you well.\\n\\nI am writing to request a meeting with you to discuss [topic of discussion]. I am [your title/position] at [your company/organization] and I am particularly interested in [area of interest related to OpenAI].\\n\\nI am available on [list of dates/times]. Please let me know if any of these times work for you or suggest an alternative.\\n\\nThank you for your time and consideration.\\n\\nSincerely,\\n[Your Name]'}, 'id': '87607866-4201-4d52-bf8e-0cfd182e55bb', 'type': 'tool_call'}] usage_metadata={'input_tokens': 66, 'output_tokens': 122, 'total_tokens': 188, 'input_token_details': {'cache_read': 0}}
# content='' additional_kwargs={} response_metadata={} id='run-1152f360-5a0b-4cb8-8065-0bb14c40f01f' tool_calls=[{'name': 'EmailTool', 'args': {'email_draft': 'Dear Sam Altman,\\n\\nI hope this email finds you well.\\n\\nI am writing to request a meeting with you to discuss [topic of discussion]. I am [your title/position] at [your company/organization] and I believe that a meeting between us would be mutually beneficial.\\n\\nI am available to meet at your earliest convenience. Please let me know what time works best for you.\\n\\nThank you for your time and consideration.\\n\\nSincerely,\\n[Your Name]'}, 'id': 'run-1152f360-5a0b-4cb8-8065-0bb14c40f01f', 'type': 'tool_call'}]
print(response)
tool_calls = cast(Any, response).tool_calls
# the email content is the argument passed to the email tool
email = tool_calls[0]["args"]["email_draft"]
return {
"email": email,
}
async def send_email_node(state: EmailAgentState, config: RunnableConfig):
"""
Send an email.
"""
config = copilotkit_customize_config(
config,
emit_messages=True,
)
await copilotkit_exit(config)
# get the last message and cast to ToolMessage
last_message = cast(ToolMessage, state["messages"][-1])
message_to_add = ""
if last_message.content == "CANCEL":
message_to_add = "❌ Cancelled sending email."
else:
message_to_add = "✅ Sent email."
await copilotkit_emit_message(config, message_to_add)
return {
"messages": state["messages"] + [AIMessage(content=message_to_add)],
}
workflow = StateGraph(EmailAgentState)
workflow.add_node("draft_email_node", draft_email_node)
workflow.add_node("send_email_node", send_email_node)
workflow.set_entry_point("draft_email_node")
workflow.add_edge("draft_email_node", "send_email_node")
workflow.add_edge("send_email_node", END)
memory = MemorySaver()
graph = workflow.compile(checkpointer=memory, interrupt_after=["draft_email_node"])