realtimex-agent-a2a-agent 0.4.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- realtimex_agent_a2a_agent/__init__.py +5 -0
- realtimex_agent_a2a_agent/agent copy.py +729 -0
- realtimex_agent_a2a_agent/agent.py +755 -0
- realtimex_agent_a2a_agent/callbacks/tool_execution.py +249 -0
- realtimex_agent_a2a_agent/cli.py +228 -0
- realtimex_agent_a2a_agent/npx.sh +5 -0
- realtimex_agent_a2a_agent/tools.py +14 -0
- realtimex_agent_a2a_agent-0.4.2.dist-info/METADATA +20 -0
- realtimex_agent_a2a_agent-0.4.2.dist-info/RECORD +11 -0
- realtimex_agent_a2a_agent-0.4.2.dist-info/WHEEL +4 -0
- realtimex_agent_a2a_agent-0.4.2.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
from uuid import uuid4
|
|
2
|
+
import json
|
|
3
|
+
import time
|
|
4
|
+
import os
|
|
5
|
+
import redis
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
from any_agent.callbacks import Callback, Context
|
|
9
|
+
from any_agent.tracing.attributes import GenAI
|
|
10
|
+
|
|
11
|
+
pool = redis.ConnectionPool(host='127.0.0.1', port=6379, db=1)
|
|
12
|
+
r = redis.Redis(connection_pool=pool)
|
|
13
|
+
|
|
14
|
+
class ShowToolCalling(Callback):
|
|
15
|
+
def before_tool_execution(self, context: Context, *args, **kwargs) -> Context:
|
|
16
|
+
span = context.current_span
|
|
17
|
+
|
|
18
|
+
operation_name = span.attributes.get(GenAI.OPERATION_NAME, "")
|
|
19
|
+
|
|
20
|
+
if operation_name != "execute_tool":
|
|
21
|
+
return context
|
|
22
|
+
|
|
23
|
+
tool_name = span.attributes.get(GenAI.TOOL_NAME, "")
|
|
24
|
+
tool_input = span.attributes.get(GenAI.TOOL_ARGS, "{}")
|
|
25
|
+
tool_call_id = span.attributes.get("gen_ai.tool.call.id","")
|
|
26
|
+
|
|
27
|
+
toolName = tool_name
|
|
28
|
+
toolIcon = "pencil-ruler"
|
|
29
|
+
mainTask = "Tool is executing..."
|
|
30
|
+
|
|
31
|
+
if tool_name.startswith("call_"):
|
|
32
|
+
toolIcon = "bot"
|
|
33
|
+
toolName = f"Call sub-agent {tool_name.replace('call_','')}"
|
|
34
|
+
mainTask = "Sub-agent is working..."
|
|
35
|
+
|
|
36
|
+
if tool_name == "final_answer":
|
|
37
|
+
return context
|
|
38
|
+
|
|
39
|
+
block_id = str(uuid4())
|
|
40
|
+
context.shared[f"show_tool_calling_block_id_{tool_call_id}"] = block_id
|
|
41
|
+
context.shared[f"show_tool_calling_start_time_{tool_call_id}"] = round(time.time() * 1000)
|
|
42
|
+
|
|
43
|
+
current_session_id = None
|
|
44
|
+
if "_current_session_id" in context.shared:
|
|
45
|
+
current_session_id = context.shared['_current_session_id']
|
|
46
|
+
|
|
47
|
+
print("current_session_id", current_session_id)
|
|
48
|
+
|
|
49
|
+
message_content = {
|
|
50
|
+
"uuid": str(uuid4()),
|
|
51
|
+
"type": "responseData",
|
|
52
|
+
"dataType": "toolUse",
|
|
53
|
+
"data": {
|
|
54
|
+
"toolName": toolName,
|
|
55
|
+
"toolIcon": toolIcon,
|
|
56
|
+
"mainTask" : mainTask,
|
|
57
|
+
"input": [tool_input],
|
|
58
|
+
"content": "",
|
|
59
|
+
"meta": {"blockId":block_id, "status": "processing", "durationMs": 0 }
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if message_content:
|
|
64
|
+
# print(f"<message>{json.dumps(message_content)}</message>")
|
|
65
|
+
pub = r.publish(
|
|
66
|
+
current_session_id,
|
|
67
|
+
f'.message {json.dumps(message_content)}'
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
return context
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def after_tool_execution(self, context: Context, *args, **kwargs) -> Context:
|
|
75
|
+
span = context.current_span
|
|
76
|
+
|
|
77
|
+
operation_name = span.attributes.get(GenAI.OPERATION_NAME, "")
|
|
78
|
+
|
|
79
|
+
if operation_name != "execute_tool":
|
|
80
|
+
return context
|
|
81
|
+
|
|
82
|
+
tool_name = span.attributes.get(GenAI.TOOL_NAME, "")
|
|
83
|
+
tool_input = span.attributes.get(GenAI.TOOL_ARGS, "{}")
|
|
84
|
+
tool_call_id = span.attributes.get("gen_ai.tool.call.id","")
|
|
85
|
+
|
|
86
|
+
toolName = tool_name
|
|
87
|
+
toolIcon = "pencil-ruler"
|
|
88
|
+
mainTask = "Tool executed completely."
|
|
89
|
+
|
|
90
|
+
if tool_name.startswith("call_"):
|
|
91
|
+
toolIcon = "bot"
|
|
92
|
+
toolName = f"Call sub-agent {tool_name.replace('call_','')}"
|
|
93
|
+
mainTask = "Sub-agent has completed the task."
|
|
94
|
+
|
|
95
|
+
# if tool_name == "final_answer":
|
|
96
|
+
# return context
|
|
97
|
+
|
|
98
|
+
if f"show_tool_calling_block_id_{tool_call_id}" in context.shared:
|
|
99
|
+
block_id = context.shared[f"show_tool_calling_block_id_{tool_call_id}"]
|
|
100
|
+
else:
|
|
101
|
+
block_id = str(uuid4())
|
|
102
|
+
|
|
103
|
+
execution_time = 0
|
|
104
|
+
if f"show_tool_calling_start_time_{tool_call_id}" in context.shared:
|
|
105
|
+
execution_time = round(time.time() * 1000) - context.shared[f"show_tool_calling_start_time_{tool_call_id}"]
|
|
106
|
+
else:
|
|
107
|
+
execution_time = 1000
|
|
108
|
+
|
|
109
|
+
current_session_id = None
|
|
110
|
+
if "_current_session_id" in context.shared:
|
|
111
|
+
current_session_id = context.shared['_current_session_id']
|
|
112
|
+
|
|
113
|
+
# print("current_session_id", current_session_id)
|
|
114
|
+
|
|
115
|
+
# context.shared[f"show_tool_calling_start_time_{tool_call_id}"] = round(time.time() * 1000)
|
|
116
|
+
ui_components = []
|
|
117
|
+
flow_as_output = False
|
|
118
|
+
flow_output_data = None
|
|
119
|
+
|
|
120
|
+
message_content = None
|
|
121
|
+
if output := span.attributes.get(GenAI.OUTPUT, None):
|
|
122
|
+
output_type = span.attributes.get(GenAI.OUTPUT_TYPE, "text")
|
|
123
|
+
|
|
124
|
+
if toolName == "final_answer":
|
|
125
|
+
# message_content = {
|
|
126
|
+
# "uuid": str(uuid4()),
|
|
127
|
+
# "type": "responseData",
|
|
128
|
+
# "content": output,
|
|
129
|
+
# "dataType": "markdown",
|
|
130
|
+
# "data": {"content": output, "language": None},
|
|
131
|
+
# }
|
|
132
|
+
# pub = r.publish(
|
|
133
|
+
# current_session_id,
|
|
134
|
+
# f'.message {json.dumps(message_content)}'
|
|
135
|
+
# )
|
|
136
|
+
return context
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
if output_type == "json":
|
|
140
|
+
output_data = json.loads(output)
|
|
141
|
+
|
|
142
|
+
if "ui-components" in output_data:
|
|
143
|
+
if output_data["ui-components"]:
|
|
144
|
+
for ui_component in output_data["ui-components"]:
|
|
145
|
+
ui_component["uuid"] = str(uuid4())
|
|
146
|
+
ui_component["type"] = "responseData"
|
|
147
|
+
ui_components.append(ui_component)
|
|
148
|
+
|
|
149
|
+
del output_data['ui-components']
|
|
150
|
+
|
|
151
|
+
if "flow_as_output" in output_data:
|
|
152
|
+
if output_data["flow_as_output"]:
|
|
153
|
+
flow_as_output = True
|
|
154
|
+
if "output" in output_data:
|
|
155
|
+
flow_output_data = str(output_data["output"])
|
|
156
|
+
|
|
157
|
+
message_content = {
|
|
158
|
+
"uuid": str(uuid4()),
|
|
159
|
+
"type": "responseData",
|
|
160
|
+
"dataType": "toolUse",
|
|
161
|
+
"data": {
|
|
162
|
+
"toolName": toolName,
|
|
163
|
+
"toolIcon": toolIcon,
|
|
164
|
+
"mainTask" : mainTask,
|
|
165
|
+
"input": [tool_input],
|
|
166
|
+
"content": {
|
|
167
|
+
"dataType": "json",
|
|
168
|
+
"data": {
|
|
169
|
+
"content": output_data,
|
|
170
|
+
"language": None
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
"meta": {"blockId":block_id, "status": "completed", "durationMs": execution_time }
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
else:
|
|
179
|
+
message_content = {
|
|
180
|
+
"uuid": str(uuid4()),
|
|
181
|
+
"type": "responseData",
|
|
182
|
+
"dataType": "toolUse",
|
|
183
|
+
"data": {
|
|
184
|
+
"toolName": toolName,
|
|
185
|
+
"toolIcon": toolIcon,
|
|
186
|
+
"mainTask" : mainTask,
|
|
187
|
+
"input": [tool_input],
|
|
188
|
+
"content": {
|
|
189
|
+
"dataType": "markdown",
|
|
190
|
+
"data": {
|
|
191
|
+
"content": output,
|
|
192
|
+
"language": None
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
"meta": {"blockId":block_id, "status": "completed", "durationMs": execution_time }
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
else:
|
|
199
|
+
message_content = {
|
|
200
|
+
"uuid": str(uuid4()),
|
|
201
|
+
"type": "responseData",
|
|
202
|
+
"dataType": "toolUse",
|
|
203
|
+
"data": {
|
|
204
|
+
"toolName": toolName,
|
|
205
|
+
"toolIcon": toolIcon,
|
|
206
|
+
"mainTask" : mainTask,
|
|
207
|
+
"input": [tool_input],
|
|
208
|
+
"content": {
|
|
209
|
+
"dataType": "markdown",
|
|
210
|
+
"data": {
|
|
211
|
+
"content": "No outputs.",
|
|
212
|
+
"language": None
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
"meta": {"blockId":block_id, "status": "completed", "durationMs": execution_time }
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if message_content:
|
|
220
|
+
# print(f"<message>{json.dumps(message_content)}</message>")
|
|
221
|
+
pub = r.publish(
|
|
222
|
+
current_session_id,
|
|
223
|
+
f'.message {json.dumps(message_content)}'
|
|
224
|
+
)
|
|
225
|
+
if len(ui_components) > 0:
|
|
226
|
+
for ui_component in ui_components:
|
|
227
|
+
pub = r.publish(
|
|
228
|
+
current_session_id,
|
|
229
|
+
f'.message {json.dumps(ui_component)}'
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
if flow_as_output:
|
|
233
|
+
pass
|
|
234
|
+
# message_content = {
|
|
235
|
+
# "uuid": str(uuid4()),
|
|
236
|
+
# "type": "responseData",
|
|
237
|
+
# "dataType": "markdown",
|
|
238
|
+
# "data": {
|
|
239
|
+
# "content": flow_output_data,
|
|
240
|
+
# "language": None
|
|
241
|
+
# }
|
|
242
|
+
# }
|
|
243
|
+
# pub = r.publish(
|
|
244
|
+
# current_session_id,
|
|
245
|
+
# f'.message {json.dumps(message_content)}'
|
|
246
|
+
# )
|
|
247
|
+
# raise RuntimeError("Reached Return Direct Tool.")
|
|
248
|
+
|
|
249
|
+
return context
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
def print_time(text):
|
|
3
|
+
# Get the current date and time
|
|
4
|
+
now = datetime.now()
|
|
5
|
+
|
|
6
|
+
# Extract and print only the time
|
|
7
|
+
current_time = now.strftime("%H:%M:%S")
|
|
8
|
+
print(f"{text}: ", current_time)
|
|
9
|
+
|
|
10
|
+
print_time("begin")
|
|
11
|
+
|
|
12
|
+
from .agent import RealTimeXAgent
|
|
13
|
+
|
|
14
|
+
import json
|
|
15
|
+
import os
|
|
16
|
+
import asyncio
|
|
17
|
+
import httpx
|
|
18
|
+
import sys
|
|
19
|
+
# from inputimeout import inputimeout, TimeoutOccurred
|
|
20
|
+
import threading
|
|
21
|
+
|
|
22
|
+
from any_agent.serving import A2AServingConfig
|
|
23
|
+
from any_agent import AgentConfig, AnyAgent
|
|
24
|
+
|
|
25
|
+
from a2a.client import A2ACardResolver, A2AClient
|
|
26
|
+
from a2a.types import AgentCard
|
|
27
|
+
|
|
28
|
+
from uuid import uuid4
|
|
29
|
+
|
|
30
|
+
from a2a.types import MessageSendParams, SendMessageRequest, TaskState
|
|
31
|
+
|
|
32
|
+
print_time("after import")
|
|
33
|
+
|
|
34
|
+
# Create the httpx client
|
|
35
|
+
httpx_client = httpx.AsyncClient()
|
|
36
|
+
|
|
37
|
+
import nest_asyncio
|
|
38
|
+
|
|
39
|
+
nest_asyncio.apply()
|
|
40
|
+
|
|
41
|
+
async def run():
|
|
42
|
+
print_time("begin run")
|
|
43
|
+
# Prepare kwargs
|
|
44
|
+
# print(sys.argv)
|
|
45
|
+
payload = json.loads(sys.argv[1])
|
|
46
|
+
# kwargs = {"workspace_slug": "test", "query": "hi", "messages": [{"role": "user", "content": "hi"}], "user_id": "user_14", "session_id": "500b4358-5d85-415d-acf0-8b12b4d896cc", "db_url": "sqlite:///C:\\Users\\Web team\\.realtimex.ai\\Resources/test_accounting_sessions.db", "default_model": "gpt-4o-mini", "litellm_api_key": "sk-tYJFmnnGzFpI9Tr1735989A9252944A9A8960c95FcCaD9Bc", "litellm_api_base": "https://llm.realtimex.ai/v1", "aci_linked_account_owner_id": "3e0bb6de-d64e-41f4-8cc7-f01a00398826", "aci_api_key": "b3bc24bb36ec940309e0dc31e22578f711b64038c7091ae92d59890dd03480a0", "agent_id": "63a42f8d-239d-4e2e-82bd-016d54110a90", "agent_data": {"name": "test-agent", "description": "Default RealTimeX Agent", "instructions": "You are the agent - please keep going until the user's query is completely resolved, before ending your turn and yielding back to the user. Only terminate your turn when you are sure that the problem is solved, or if you need more info from the user to solve the problem.\n\nALWAYS ask required inputs from user to make sure to have correct inputs while calling functions.\n\nIf you are not sure about anything pertaining to the user's request, use your tools to read files and gather the relevant information: do NOT guess or make up an answer.\n\nYou MUST plan extensively before each function call, and reflect extensively on the outcomes of the previous function calls. DO NOT do this entire process by making function calls only, as this can impair your ability to solve the problem and think insightfully.\n\nRELATED MEMORIES:\n{##MEMORIES##}\n\nRELATED KNOWLEDGES:\n{##KNOWLEDGES##}", "execution_config": {"cmd": ["uvx", "realtimex-agent-a2a-agent"], "data": {}, "models": {"provider": "realtimexai", "default_model": "gpt-3.5-turbo"}, "framework": "tinyagent"}, "recommended_agent_flows": [], "recommended_aci_mcp_apps": []}, "thread_id": None, "knowledges": [], "memory_id": "aab7f86e-8f94-46a2-9f16-5bf0c58902dc", "memory_path": "C:\\Users\\Web team\\.realtimex.ai\\memories", "realtimex_access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJORlVmWGlMZHlxVmtSdGFJUlFGVGlZVXZBWXUwdXpSSXp2OEZaTGpnbGdnIn0.eyJleHAiOjE3NTYyODE2ODgsImlhdCI6MTc1NjI4MDc4OCwiYXV0aF90aW1lIjoxNzU2MTczNTA4LCJqdGkiOiI5NWRkYmFlNy03YmFjLTRlMzgtYTBlNi1kNDg0ODJkNWM2YjUiLCJpc3MiOiJodHRwczovL2FjY291bnRzLnJlYWx0aW1leC5jby9hdXRoL3JlYWxtcy9yZWFsdGltZXgiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiMGNhYTM5ZmItYzRiOS00MzYzLTljMmMtYWZjNDQ4ZDUyZjkwIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoicmVhbHRpbWV4LWFwcCIsIm5vbmNlIjoiY2Y0NGE3ZDctYjAyMy00NmQyLTllODktNDgyNmU0MGUxZDdmIiwic2Vzc2lvbl9zdGF0ZSI6IjEzOTRlZmRmLWEyZmMtNDgzMS1hM2FlLTBkYzgwNTMzZWVlNiIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiKiJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiIsImRlZmF1bHQtcm9sZXMtcnR3b3JrLWluYyJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoib3BlbmlkIG9mZmxpbmVfYWNjZXNzIGVtYWlsIHByb2ZpbGUiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwibmFtZSI6IlBodW9uZyBOZ3V5ZW4iLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJwaHVvbmdubTE1OTMiLCJnaXZlbl9uYW1lIjoiUGh1b25nIiwiZmFtaWx5X25hbWUiOiJOZ3V5ZW4iLCJlbWFpbCI6InBodW9uZ25tMTU5M0BnbWFpbC5jb20ifQ.jYWqbKAvXND5fACOBCsi6PPJkU7yDGwnqgJ-qSn0Wz2hSzRYl4Gymc2HSlLASO4aDO24Ar7Ob4R26xpAyfkXMjFWHR94MxajK9CZlVfV4NOpVCRXq1R--3aNA1oNWu-FbRMDKNQIJDd1se2fjJfMa79C9yVXlUs2R_-1ktTHjBnblsWkkh2p8frGNKsLq_kacXpV4YGe5IAf96z5XfYJKTV2ykVFPV67f5-brlNfXLBx88I0ZGY41K_VCkoL0wsHUB1FlBjHzfomsRfHrjMzrIFvx1B6tIV-kLOnjeuDZdysmtjR0L7w4gKsXxRl2bV8B0lWqHknytEnvciMZduDEQ"}
|
|
47
|
+
|
|
48
|
+
a2a_port = sys.argv[2]
|
|
49
|
+
|
|
50
|
+
system_prompt = None
|
|
51
|
+
agent_framework = None
|
|
52
|
+
agent_description = None
|
|
53
|
+
default_model = None
|
|
54
|
+
provider_name = None
|
|
55
|
+
llm_setting = None
|
|
56
|
+
|
|
57
|
+
agent_id = payload["agent_id"]
|
|
58
|
+
agent_data = payload["agent_data"]
|
|
59
|
+
user_id = payload["user_id"]
|
|
60
|
+
workspace_slug = payload["workspace_slug"]
|
|
61
|
+
thread_id = payload["thread_id"]
|
|
62
|
+
knowledges = payload["knowledges"]
|
|
63
|
+
memory_id = payload["memory_id"]
|
|
64
|
+
memory_path = payload["memory_path"]
|
|
65
|
+
execution_id = payload["session_id"]
|
|
66
|
+
message = payload["query"]
|
|
67
|
+
messages = payload["messages"]
|
|
68
|
+
aci_linked_account_owner_id = payload["aci_linked_account_owner_id"]
|
|
69
|
+
aci_agent_first_api_key = payload["aci_api_key"]
|
|
70
|
+
realtimex_access_token = payload["realtimex_access_token"]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
if "agent_description" in payload:
|
|
74
|
+
agent_description = payload["agent_description"]
|
|
75
|
+
if "agent_framework" in payload:
|
|
76
|
+
agent_framework = payload["agent_framework"]
|
|
77
|
+
if "system_prompt" in payload:
|
|
78
|
+
system_prompt = payload["system_prompt"]
|
|
79
|
+
if "llm_setting" in payload:
|
|
80
|
+
llm_setting = payload["llm_setting"]
|
|
81
|
+
|
|
82
|
+
default_openai_base_url = payload["litellm_api_base"]
|
|
83
|
+
default_openai_api_key = payload["litellm_api_key"]
|
|
84
|
+
|
|
85
|
+
# Load MCP tools
|
|
86
|
+
|
|
87
|
+
# Create agent
|
|
88
|
+
agent = RealTimeXAgent(current_session_id=execution_id)
|
|
89
|
+
|
|
90
|
+
await agent.load_default_agent(agent_id, agent_data, payload)
|
|
91
|
+
|
|
92
|
+
server_url = await agent.serve_as_a2a(
|
|
93
|
+
a2a_serving_config={"port":a2a_port,"stream_tool_usage":True}
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
print(f"<server-url>{server_url}</server-url>")
|
|
97
|
+
|
|
98
|
+
# input("Waiting...")
|
|
99
|
+
|
|
100
|
+
# async with httpx.AsyncClient() as client:
|
|
101
|
+
# while True:
|
|
102
|
+
# try:
|
|
103
|
+
# await client.get(server_url, timeout=1.0)
|
|
104
|
+
# print(f"Server is ready at {server_url}")
|
|
105
|
+
|
|
106
|
+
# agent_card: AgentCard = await A2ACardResolver(
|
|
107
|
+
# httpx_client,
|
|
108
|
+
# base_url=server_url,
|
|
109
|
+
# ).get_agent_card(http_kwargs=None)
|
|
110
|
+
# # print(agent_card.model_dump_json(indent=2))
|
|
111
|
+
|
|
112
|
+
# client = A2AClient(httpx_client=httpx_client, agent_card=agent_card)
|
|
113
|
+
|
|
114
|
+
# send_message_payload = {
|
|
115
|
+
# "message": {
|
|
116
|
+
# "role": "user",
|
|
117
|
+
# "parts": [{"kind": "text", "text": f"{message}"}],
|
|
118
|
+
# "messageId": uuid4().hex,
|
|
119
|
+
# # "contextId": "bce7de7a-5050-4b74-822c-af0e13073036", # Same context to continue conversation
|
|
120
|
+
# # "taskId": "159e8a1b-788c-47ef-998d-9419b8f5fb5a", # type: ignore[union-attr]
|
|
121
|
+
# },
|
|
122
|
+
# }
|
|
123
|
+
# request = SendMessageRequest(
|
|
124
|
+
# id=str(uuid4()), params=MessageSendParams(**send_message_payload)
|
|
125
|
+
# )
|
|
126
|
+
# response = await client.send_message(request, http_kwargs={"timeout": 300.0})
|
|
127
|
+
# print("response",response)
|
|
128
|
+
# # response = json.loads(response.root.result.status.message.parts[0].root.text)
|
|
129
|
+
# # # print(response["result"])
|
|
130
|
+
# # print("response",response)
|
|
131
|
+
# response_message = response.root.result.status.message
|
|
132
|
+
# response_text = json.loads(response_message.parts[0].root.text)["result"]
|
|
133
|
+
# response_state = response.root.result.status.state
|
|
134
|
+
# context_id = response.root.result.context_id
|
|
135
|
+
# task_id = response.root.result.id
|
|
136
|
+
|
|
137
|
+
# message_content = {
|
|
138
|
+
# "uuid": str(uuid4()),
|
|
139
|
+
# "type": "responseData",
|
|
140
|
+
# "content": response_text,
|
|
141
|
+
# "dataType": "markdown",
|
|
142
|
+
# "data": {"content": response_text, "language": None},
|
|
143
|
+
# }
|
|
144
|
+
|
|
145
|
+
# print(f"<message>{json.dumps(message_content)}</message>")
|
|
146
|
+
# print(f"<signal>session-end</signal>")
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
# # while response_state == TaskState.input_required:
|
|
151
|
+
# while True:
|
|
152
|
+
# # user_input = input(response_text)
|
|
153
|
+
# user_input = input('Enter message: ')
|
|
154
|
+
# if user_input is None:
|
|
155
|
+
# break
|
|
156
|
+
|
|
157
|
+
# if response_state == TaskState.completed:
|
|
158
|
+
# send_message_payload = {
|
|
159
|
+
# "message": {
|
|
160
|
+
# "role": "user",
|
|
161
|
+
# "parts": [{"kind": "text", "text": f"{user_input}"}],
|
|
162
|
+
# "messageId": uuid4().hex,
|
|
163
|
+
# "contextId": response.root.result.context_id, # Same context to continue conversation
|
|
164
|
+
# },
|
|
165
|
+
# }
|
|
166
|
+
# else:
|
|
167
|
+
# send_message_payload = {
|
|
168
|
+
# "message": {
|
|
169
|
+
# "role": "user",
|
|
170
|
+
# "parts": [{"kind": "text", "text": f"{user_input}"}],
|
|
171
|
+
# "messageId": uuid4().hex,
|
|
172
|
+
# "contextId": response.root.result.context_id, # Same context to continue conversation
|
|
173
|
+
# "taskId": response.root.result.id, # type: ignore[union-attr]
|
|
174
|
+
# },
|
|
175
|
+
# }
|
|
176
|
+
|
|
177
|
+
# request = SendMessageRequest(
|
|
178
|
+
# id=str(uuid4()), params=MessageSendParams(**send_message_payload)
|
|
179
|
+
# )
|
|
180
|
+
# response = await client.send_message(request, http_kwargs={"timeout": 300.0})
|
|
181
|
+
|
|
182
|
+
# print("send_message_payload",send_message_payload)
|
|
183
|
+
# print("response",response)
|
|
184
|
+
|
|
185
|
+
# response_message = response.root.result.status.message
|
|
186
|
+
# response_text = json.loads(response_message.parts[0].root.text)["result"]
|
|
187
|
+
# response_state = response.root.result.status.state
|
|
188
|
+
|
|
189
|
+
# message_content = {
|
|
190
|
+
# "uuid": str(uuid4()),
|
|
191
|
+
# "type": "responseData",
|
|
192
|
+
# "content": response_text,
|
|
193
|
+
# "dataType": "markdown",
|
|
194
|
+
# "data": {"content": response_text, "language": None},
|
|
195
|
+
# }
|
|
196
|
+
|
|
197
|
+
# print(f"<message>{json.dumps(message_content)}</message>")
|
|
198
|
+
# print(f"<signal>session-end</signal>")
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
# # print(response)
|
|
204
|
+
# # Close the httpx client when done
|
|
205
|
+
# await httpx_client.aclose()
|
|
206
|
+
|
|
207
|
+
# break
|
|
208
|
+
# except (httpx.RequestError, httpx.TimeoutException):
|
|
209
|
+
# await asyncio.sleep(poll_interval)
|
|
210
|
+
# attempts += 1
|
|
211
|
+
# if attempts >= max_attempts:
|
|
212
|
+
# msg = f"Could not connect to {server_url}. Tried {max_attempts} times with {poll_interval} second interval."
|
|
213
|
+
# raise ConnectionError(msg)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
async with httpx.AsyncClient() as client:
|
|
217
|
+
while True:
|
|
218
|
+
try:
|
|
219
|
+
await client.get(server_url, timeout=1.0)
|
|
220
|
+
print(f"<signal>server-listening</signal>")
|
|
221
|
+
except (httpx.RequestError, httpx.TimeoutException):
|
|
222
|
+
print(f"<signal>server-stopped</signal>")
|
|
223
|
+
await asyncio.sleep(30)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def main():
|
|
227
|
+
print_time("begin main")
|
|
228
|
+
asyncio.run(run())
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
def send_email(body:str, to_email:str, from_email: str = "me") -> str:
|
|
2
|
+
"""Send Email to someone.
|
|
3
|
+
|
|
4
|
+
Args:
|
|
5
|
+
from_email (str): The sender
|
|
6
|
+
to_email (str): The receiver email
|
|
7
|
+
body (str): The body of email
|
|
8
|
+
|
|
9
|
+
Returns:
|
|
10
|
+
The string to say hello.
|
|
11
|
+
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
return f"Email has been sent to {to_email}"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: realtimex-agent-a2a-agent
|
|
3
|
+
Version: 0.4.2
|
|
4
|
+
Summary: Add your description here
|
|
5
|
+
Author: rta_phuongnguyen
|
|
6
|
+
Author-email: rta_phuongnguyen <phuongnguyen@rtanalytics.vn>
|
|
7
|
+
Requires-Dist: realtimex-any-agent
|
|
8
|
+
Requires-Dist: ollama
|
|
9
|
+
Requires-Dist: google-genai
|
|
10
|
+
Requires-Dist: realtimex-any-agent[a2a]
|
|
11
|
+
Requires-Dist: realtimex-any-agent[langchain]
|
|
12
|
+
Requires-Dist: realtimex-any-agent[deepagents]
|
|
13
|
+
Requires-Dist: nest-asyncio
|
|
14
|
+
Requires-Dist: openai
|
|
15
|
+
Requires-Dist: aci-mcp==1.0.0b13
|
|
16
|
+
Requires-Dist: mem0ai==0.1.116
|
|
17
|
+
Requires-Dist: redis
|
|
18
|
+
Requires-Python: >=3.11
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
realtimex_agent_a2a_agent/__init__.py,sha256=8X_E69_hK92hxiMs2rIoxoq3eSV6aPkS5TQt0oCEVWI,69
|
|
2
|
+
realtimex_agent_a2a_agent/agent copy.py,sha256=HScIX5FQIA2vTlM7ZA9rgySNHv1S3sAfDoTV_tAgRJ4,28811
|
|
3
|
+
realtimex_agent_a2a_agent/agent.py,sha256=BGHMdaHNI_UbDetL5PFY2IpmGZ7lgvX7Ssaz4Qffnn8,30147
|
|
4
|
+
realtimex_agent_a2a_agent/callbacks/tool_execution.py,sha256=Z4NxV7ZurjoKIhZBXWd62tWRhmHWsXOvn3iQPav8n3Y,9045
|
|
5
|
+
realtimex_agent_a2a_agent/cli.py,sha256=EgpAatNJid4MFYR392uFULQBVGRxxHxUUj8r05vmMzk,12129
|
|
6
|
+
realtimex_agent_a2a_agent/npx.sh,sha256=NZipbZxBEcEahWjWVnNaFHBwYNyvT6At-wLm0dkRNto,81
|
|
7
|
+
realtimex_agent_a2a_agent/tools.py,sha256=tHMl1Y2cYEn9dNu_zvg59-k2h6FpUMNXcpmYIb_xTiI,339
|
|
8
|
+
realtimex_agent_a2a_agent-0.4.2.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
|
|
9
|
+
realtimex_agent_a2a_agent-0.4.2.dist-info/entry_points.txt,sha256=Y0LpZt4GtWoM-0Kpn3H_ehehwttkMHGHXbj-nXzF1Nc,82
|
|
10
|
+
realtimex_agent_a2a_agent-0.4.2.dist-info/METADATA,sha256=vb44Rs1wG6GlRZoJNfno8mxisdoLceOmrQKY_l8pSzw,608
|
|
11
|
+
realtimex_agent_a2a_agent-0.4.2.dist-info/RECORD,,
|