ag2 0.9.10__py3-none-any.whl → 0.10.0__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.
Potentially problematic release.
This version of ag2 might be problematic. Click here for more details.
- {ag2-0.9.10.dist-info → ag2-0.10.0.dist-info}/METADATA +14 -7
- {ag2-0.9.10.dist-info → ag2-0.10.0.dist-info}/RECORD +42 -24
- autogen/a2a/__init__.py +36 -0
- autogen/a2a/agent_executor.py +105 -0
- autogen/a2a/client.py +280 -0
- autogen/a2a/errors.py +18 -0
- autogen/a2a/httpx_client_factory.py +79 -0
- autogen/a2a/server.py +221 -0
- autogen/a2a/utils.py +165 -0
- autogen/agentchat/__init__.py +3 -0
- autogen/agentchat/agent.py +0 -2
- autogen/agentchat/chat.py +5 -1
- autogen/agentchat/contrib/llava_agent.py +1 -13
- autogen/agentchat/conversable_agent.py +178 -73
- autogen/agentchat/group/group_tool_executor.py +46 -15
- autogen/agentchat/group/guardrails.py +41 -33
- autogen/agentchat/group/multi_agent_chat.py +53 -0
- autogen/agentchat/group/safeguards/api.py +19 -2
- autogen/agentchat/group/safeguards/enforcer.py +134 -40
- autogen/agentchat/groupchat.py +45 -33
- autogen/agentchat/realtime/experimental/realtime_swarm.py +1 -3
- autogen/interop/pydantic_ai/pydantic_ai.py +1 -1
- autogen/llm_config/client.py +3 -2
- autogen/oai/bedrock.py +0 -13
- autogen/oai/client.py +15 -8
- autogen/oai/client_utils.py +30 -0
- autogen/oai/cohere.py +0 -10
- autogen/remote/__init__.py +18 -0
- autogen/remote/agent.py +199 -0
- autogen/remote/agent_service.py +142 -0
- autogen/remote/errors.py +17 -0
- autogen/remote/httpx_client_factory.py +131 -0
- autogen/remote/protocol.py +37 -0
- autogen/remote/retry.py +102 -0
- autogen/remote/runtime.py +96 -0
- autogen/testing/__init__.py +12 -0
- autogen/testing/messages.py +45 -0
- autogen/testing/test_agent.py +111 -0
- autogen/version.py +1 -1
- {ag2-0.9.10.dist-info → ag2-0.10.0.dist-info}/WHEEL +0 -0
- {ag2-0.9.10.dist-info → ag2-0.10.0.dist-info}/licenses/LICENSE +0 -0
- {ag2-0.9.10.dist-info → ag2-0.10.0.dist-info}/licenses/NOTICE.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ag2
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.10.0
|
|
4
4
|
Summary: A programming framework for agentic AI
|
|
5
5
|
Project-URL: Homepage, https://ag2.ai/
|
|
6
6
|
Project-URL: Documentation, https://docs.ag2.ai
|
|
@@ -28,7 +28,7 @@ Classifier: Topic :: Software Development
|
|
|
28
28
|
Classifier: Topic :: Software Development :: Libraries
|
|
29
29
|
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
30
30
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
31
|
-
Requires-Python:
|
|
31
|
+
Requires-Python: >=3.10
|
|
32
32
|
Requires-Dist: anyio<5.0.0,>=3.0.0
|
|
33
33
|
Requires-Dist: diskcache
|
|
34
34
|
Requires-Dist: docker
|
|
@@ -38,6 +38,8 @@ Requires-Dist: pydantic<3,>=2.6.1
|
|
|
38
38
|
Requires-Dist: python-dotenv
|
|
39
39
|
Requires-Dist: termcolor
|
|
40
40
|
Requires-Dist: tiktoken
|
|
41
|
+
Provides-Extra: a2a
|
|
42
|
+
Requires-Dist: a2a-sdk[http-server]<0.4,>=0.3.7; extra == 'a2a'
|
|
41
43
|
Provides-Extra: anthropic
|
|
42
44
|
Requires-Dist: anthropic[vertex]>=0.23.1; extra == 'anthropic'
|
|
43
45
|
Provides-Extra: autobuild
|
|
@@ -72,11 +74,13 @@ Requires-Dist: crawl4ai<0.8,>=0.4.247; extra == 'crawl4ai'
|
|
|
72
74
|
Provides-Extra: deepseek
|
|
73
75
|
Requires-Dist: openai>=1.99.3; extra == 'deepseek'
|
|
74
76
|
Provides-Extra: dev
|
|
77
|
+
Requires-Dist: a2a-sdk[http-server]<0.4,>=0.3.7; extra == 'dev'
|
|
75
78
|
Requires-Dist: cairosvg; extra == 'dev'
|
|
76
79
|
Requires-Dist: codespell==2.4.1; extra == 'dev'
|
|
77
80
|
Requires-Dist: detect-secrets==1.5.0; extra == 'dev'
|
|
78
81
|
Requires-Dist: dirty-equals==0.9.0; extra == 'dev'
|
|
79
82
|
Requires-Dist: fastapi==0.116.1; extra == 'dev'
|
|
83
|
+
Requires-Dist: freezegun==1.5.5; extra == 'dev'
|
|
80
84
|
Requires-Dist: ipykernel==6.30.1; extra == 'dev'
|
|
81
85
|
Requires-Dist: jinja2==3.1.6; extra == 'dev'
|
|
82
86
|
Requires-Dist: mcp>=1.11.0; extra == 'dev'
|
|
@@ -90,7 +94,6 @@ Requires-Dist: mkdocs-material==9.6.19; extra == 'dev'
|
|
|
90
94
|
Requires-Dist: mkdocs-minify-plugin==0.8.0; extra == 'dev'
|
|
91
95
|
Requires-Dist: mkdocs-redirects==1.2.2; extra == 'dev'
|
|
92
96
|
Requires-Dist: mkdocstrings[python]==0.30.0; extra == 'dev'
|
|
93
|
-
Requires-Dist: mock==5.2.0; extra == 'dev'
|
|
94
97
|
Requires-Dist: mypy==1.17.1; extra == 'dev'
|
|
95
98
|
Requires-Dist: nbclient==0.10.2; extra == 'dev'
|
|
96
99
|
Requires-Dist: nbconvert==7.16.6; extra == 'dev'
|
|
@@ -117,6 +120,7 @@ Requires-Dist: types-requests; extra == 'dev'
|
|
|
117
120
|
Requires-Dist: types-ujson; extra == 'dev'
|
|
118
121
|
Requires-Dist: uv==0.8.15; extra == 'dev'
|
|
119
122
|
Provides-Extra: docs
|
|
123
|
+
Requires-Dist: a2a-sdk[http-server]<0.4,>=0.3.7; extra == 'docs'
|
|
120
124
|
Requires-Dist: cairosvg; extra == 'docs'
|
|
121
125
|
Requires-Dist: jinja2==3.1.6; extra == 'docs'
|
|
122
126
|
Requires-Dist: mcp>=1.11.0; extra == 'docs'
|
|
@@ -175,9 +179,10 @@ Provides-Extra: groq
|
|
|
175
179
|
Requires-Dist: groq>=0.9.0; extra == 'groq'
|
|
176
180
|
Provides-Extra: interop
|
|
177
181
|
Requires-Dist: crewai[tools]<1,>=0.76; (python_version >= '3.10' and python_version < '3.13') and extra == 'interop'
|
|
182
|
+
Requires-Dist: fasta2a; extra == 'interop'
|
|
178
183
|
Requires-Dist: langchain-community<1,>=0.3.12; extra == 'interop'
|
|
179
184
|
Requires-Dist: litellm<=1.76.3; extra == 'interop'
|
|
180
|
-
Requires-Dist: pydantic-ai
|
|
185
|
+
Requires-Dist: pydantic-ai>=1.0.12; extra == 'interop'
|
|
181
186
|
Requires-Dist: weaviate-client<5,>=4; (python_version >= '3.10' and python_version < '3.13') and extra == 'interop'
|
|
182
187
|
Provides-Extra: interop-crewai
|
|
183
188
|
Requires-Dist: crewai[tools]<1,>=0.76; (python_version >= '3.10' and python_version < '3.13') and extra == 'interop-crewai'
|
|
@@ -186,7 +191,8 @@ Requires-Dist: weaviate-client<5,>=4; (python_version >= '3.10' and python_versi
|
|
|
186
191
|
Provides-Extra: interop-langchain
|
|
187
192
|
Requires-Dist: langchain-community<1,>=0.3.12; extra == 'interop-langchain'
|
|
188
193
|
Provides-Extra: interop-pydantic-ai
|
|
189
|
-
Requires-Dist:
|
|
194
|
+
Requires-Dist: fasta2a; extra == 'interop-pydantic-ai'
|
|
195
|
+
Requires-Dist: pydantic-ai>=1.0.12; extra == 'interop-pydantic-ai'
|
|
190
196
|
Provides-Extra: jupyter-executor
|
|
191
197
|
Requires-Dist: ipykernel>=6.29.0; extra == 'jupyter-executor'
|
|
192
198
|
Requires-Dist: jupyter-client>=8.6.0; extra == 'jupyter-executor'
|
|
@@ -301,9 +307,9 @@ Requires-Dist: chromadb; extra == 'teachable'
|
|
|
301
307
|
Provides-Extra: test
|
|
302
308
|
Requires-Dist: dirty-equals==0.9.0; extra == 'test'
|
|
303
309
|
Requires-Dist: fastapi==0.116.1; extra == 'test'
|
|
310
|
+
Requires-Dist: freezegun==1.5.5; extra == 'test'
|
|
304
311
|
Requires-Dist: ipykernel==6.30.1; extra == 'test'
|
|
305
312
|
Requires-Dist: mcp>=1.11.0; extra == 'test'
|
|
306
|
-
Requires-Dist: mock==5.2.0; extra == 'test'
|
|
307
313
|
Requires-Dist: nbconvert==7.16.6; extra == 'test'
|
|
308
314
|
Requires-Dist: nbformat==5.10.4; extra == 'test'
|
|
309
315
|
Requires-Dist: pandas==2.3.2; extra == 'test'
|
|
@@ -317,11 +323,12 @@ Requires-Dist: fastapi<1,>=0.115.0; extra == 'twilio'
|
|
|
317
323
|
Requires-Dist: twilio>=9.3.2; extra == 'twilio'
|
|
318
324
|
Requires-Dist: uvicorn<1,>=0.30.6; extra == 'twilio'
|
|
319
325
|
Provides-Extra: types
|
|
326
|
+
Requires-Dist: a2a-sdk[http-server]<0.4,>=0.3.7; extra == 'types'
|
|
320
327
|
Requires-Dist: dirty-equals==0.9.0; extra == 'types'
|
|
321
328
|
Requires-Dist: fastapi==0.116.1; extra == 'types'
|
|
329
|
+
Requires-Dist: freezegun==1.5.5; extra == 'types'
|
|
322
330
|
Requires-Dist: ipykernel==6.30.1; extra == 'types'
|
|
323
331
|
Requires-Dist: mcp>=1.11.0; extra == 'types'
|
|
324
|
-
Requires-Dist: mock==5.2.0; extra == 'types'
|
|
325
332
|
Requires-Dist: mypy==1.17.1; extra == 'types'
|
|
326
333
|
Requires-Dist: nbconvert==7.16.6; extra == 'types'
|
|
327
334
|
Requires-Dist: nbformat==5.10.4; extra == 'types'
|
|
@@ -13,19 +13,26 @@ autogen/retrieve_utils.py,sha256=omqOebRN95IJUrvukJR9e7wno4vB1m3sf_gHv4ormN0,200
|
|
|
13
13
|
autogen/runtime_logging.py,sha256=PV4xLXLEscBWVcdGLecN1f8gZqpvqK0E2SH0Y5numUM,4701
|
|
14
14
|
autogen/token_count_utils.py,sha256=k50Vii75GhjkiYuw0gaWd7PjtiR-ZucNcN0xSJkBRKo,10859
|
|
15
15
|
autogen/types.py,sha256=-C23PYj5EdwPZxcL3r0wFLAsQTXyVReghsdKV5b9jO4,982
|
|
16
|
-
autogen/version.py,sha256=
|
|
16
|
+
autogen/version.py,sha256=ygtxiiXGPJvnpNFQtZCKcrNxJ1Luy5BiYoB4BcfXIKg,194
|
|
17
17
|
autogen/_website/__init__.py,sha256=c8B9TpO07x9neD0zsJWj6AaEdlcP-WvxrvVOGWLtamk,143
|
|
18
18
|
autogen/_website/generate_api_references.py,sha256=cMzgnapuahybxmGHbddukJA3oZxj1uIktDdOyP4rGzU,14772
|
|
19
19
|
autogen/_website/generate_mkdocs.py,sha256=z4mBUBF-EJH1JwLOL727ExclSFx_mVOleggSVpqyrEA,43170
|
|
20
20
|
autogen/_website/notebook_processor.py,sha256=VK4bUWz0RvkbpxPN91Nit2h2h7SOamNqyjuKjif7P4M,16500
|
|
21
21
|
autogen/_website/process_notebooks.py,sha256=3MW1oWdBh1id5OpFI_4SoJ2EEfmrNDD0xMkTC2Tcp8Y,25902
|
|
22
22
|
autogen/_website/utils.py,sha256=5345c12pOXyEcLS1pciVJY4g7wDs_fGTAZ4HsDswGow,14704
|
|
23
|
-
autogen/
|
|
24
|
-
autogen/
|
|
23
|
+
autogen/a2a/__init__.py,sha256=F_1b_seEOxZ1XI5TS4-dDp8KpBWaCJMfAyuYt6hO9Ac,1031
|
|
24
|
+
autogen/a2a/agent_executor.py,sha256=jE1wsshCHP8mzcp3ufUD76Wy5fP-UwBYB0QLDIDrvEQ,3813
|
|
25
|
+
autogen/a2a/client.py,sha256=bxfi_34Lsdnkhn311PqVXJVzMa6yRVB_-KulwD8wLLI,11036
|
|
26
|
+
autogen/a2a/errors.py,sha256=ydsDYnjjZLSGqVIlNITEFLPoWV-Ctffl1w7e3-r0WQc,446
|
|
27
|
+
autogen/a2a/httpx_client_factory.py,sha256=XuK_rNEw47uqATsK9T7prgtLFbThL-nBbGzyPax3PkM,3213
|
|
28
|
+
autogen/a2a/server.py,sha256=Bd2z4nKOv5qMfbgaYcVCSojl--esA7l9_kuV922YCeU,8137
|
|
29
|
+
autogen/a2a/utils.py,sha256=c0v21fPOTMVQ9aVJc5JT3SKG69MWHyt3iRr3MS4llrc,4762
|
|
30
|
+
autogen/agentchat/__init__.py,sha256=LkVdKOYXz6LX-tzEpeCZHOSPlWtCkMT07XX8lKjf8OE,1439
|
|
31
|
+
autogen/agentchat/agent.py,sha256=M9XNAX6u20tL_oLrEWMxFXFaqWpaJVWHjpzWTfy7xpY,5723
|
|
25
32
|
autogen/agentchat/assistant_agent.py,sha256=dP8gcG96BihPW34pvTlxMogRa0zONnQHwzxhQuQ2Jdg,5779
|
|
26
|
-
autogen/agentchat/chat.py,sha256=
|
|
27
|
-
autogen/agentchat/conversable_agent.py,sha256=
|
|
28
|
-
autogen/agentchat/groupchat.py,sha256=
|
|
33
|
+
autogen/agentchat/chat.py,sha256=cdSb-SLJ0Mh_8QSx6zs9pM0jyND57p5DKjkynCpXxnE,14562
|
|
34
|
+
autogen/agentchat/conversable_agent.py,sha256=gyaALkmdDqcIz76kc5z27pahioGPdgh2GJ5lJyoGgts,200069
|
|
35
|
+
autogen/agentchat/groupchat.py,sha256=eHb4SJSq7gTkXt5ggW622Rayz556Fda2h_AYXTuMA54,91915
|
|
29
36
|
autogen/agentchat/user_proxy_agent.py,sha256=cFxJiRryh-648X07tJrItibdbHwBuFEQ2Yox1hLgDt4,7585
|
|
30
37
|
autogen/agentchat/utils.py,sha256=eWLFoB2qQBUW44PQiWJ5SRxT1w1UXxwL28JsjOwGqg0,8206
|
|
31
38
|
autogen/agentchat/contrib/__init__.py,sha256=tOTe4nwbKj7elHpftAy3zS_embMDzncrKL98XKhY6-c,168
|
|
@@ -33,7 +40,7 @@ autogen/agentchat/contrib/agent_optimizer.py,sha256=TXNHD9-myPKXwurd_pjQ_rpRj0oh
|
|
|
33
40
|
autogen/agentchat/contrib/gpt_assistant_agent.py,sha256=mms6DK0s91Y-iF_-GKY_WfWzLzz5hY2Q0TJOCYezNU0,24999
|
|
34
41
|
autogen/agentchat/contrib/img_utils.py,sha256=NQ0yAbY5zugnl00ZVqBgNKyBYwiguEOFxtVTlSMQIfM,15115
|
|
35
42
|
autogen/agentchat/contrib/llamaindex_conversable_agent.py,sha256=DD-JbrRnrsPKpLJPxtel7tS904giS1LTQmuFraDsCig,4533
|
|
36
|
-
autogen/agentchat/contrib/llava_agent.py,sha256=
|
|
43
|
+
autogen/agentchat/contrib/llava_agent.py,sha256=9yTg1fUDu5lqi-58Im50buNmeXLQybPsfh5wZQeUf6M,6628
|
|
37
44
|
autogen/agentchat/contrib/math_user_proxy_agent.py,sha256=Icw5nLbZwmzXsoGmFSE8KhTCknWOtJSkAdh78M9Wj8E,19678
|
|
38
45
|
autogen/agentchat/contrib/multimodal_conversable_agent.py,sha256=zgFHgiaBitUJuJ3V6zGja42fyN4-otVceIK_Sx-1Ddg,5112
|
|
39
46
|
autogen/agentchat/contrib/qdrant_retrieve_user_proxy_agent.py,sha256=WhKltVJkK_X7Y_eHTgXq4m9IthktVa3zgOt0vPOqV2U,19398
|
|
@@ -130,12 +137,12 @@ autogen/agentchat/group/context_condition.py,sha256=UwIOBqPzwi0emfkmseavTJJ6f0VA
|
|
|
130
137
|
autogen/agentchat/group/context_expression.py,sha256=nzAVoI7RW0O1iuMyWpFZrVjGnHaQUsq8e83vXzzo06k,10012
|
|
131
138
|
autogen/agentchat/group/context_str.py,sha256=Jv8v8oNFymZGmahWpARdBrXBkmZUZWBDsfMyKwzTtHw,1238
|
|
132
139
|
autogen/agentchat/group/context_variables.py,sha256=1GkOokaaYX-Xc5b9ZylytjQxjhLAyY8MW3quPBJuoFM,5562
|
|
133
|
-
autogen/agentchat/group/group_tool_executor.py,sha256=
|
|
140
|
+
autogen/agentchat/group/group_tool_executor.py,sha256=NkwKBO96wGhVz6aYrjtkqVXQFLcHMqUVdmxgkVpEvuQ,10692
|
|
134
141
|
autogen/agentchat/group/group_utils.py,sha256=Y4KOZbqM81lqFmqg9K5xnbjr4YYBfk3iMkm1GK8tygs,27534
|
|
135
|
-
autogen/agentchat/group/guardrails.py,sha256=
|
|
142
|
+
autogen/agentchat/group/guardrails.py,sha256=F3aVn7ht-WCgz0uLC9f4Os8_yIEG0lgQ2XFrCi1GMKY,6324
|
|
136
143
|
autogen/agentchat/group/handoffs.py,sha256=IOUCOtCFAfhITZhh01HK3ehRMdoBgmgU4gwlLn48ofQ,11633
|
|
137
144
|
autogen/agentchat/group/llm_condition.py,sha256=wfuEET1VhyVVGedYxcyuhX_Vus6uZHxUl_SPpu4YIsc,2951
|
|
138
|
-
autogen/agentchat/group/multi_agent_chat.py,sha256=
|
|
145
|
+
autogen/agentchat/group/multi_agent_chat.py,sha256=EdwDmLjRMsDrmHijDLVK5BK3Tg2t_FrZUsyjcvlF_Po,10289
|
|
139
146
|
autogen/agentchat/group/on_condition.py,sha256=o7wVXlUQ2G5Z3Mbm_awWQlYnnG6x9_HcqSiY7Arw0NQ,2195
|
|
140
147
|
autogen/agentchat/group/on_context_condition.py,sha256=Lh6m7kFt3dos1JLja3WPmH_9qTYhIkpM6hIL6T6YgU0,2032
|
|
141
148
|
autogen/agentchat/group/reply_result.py,sha256=DItDGQdaUucCuOIw8kGQDpwt9Li80xvt6Phmo2_14Xk,705
|
|
@@ -147,8 +154,8 @@ autogen/agentchat/group/patterns/pattern.py,sha256=RMEPnMavpl7NP84hoaIZAwyQtxjHy
|
|
|
147
154
|
autogen/agentchat/group/patterns/random.py,sha256=Zte7JVN9illCqNRi3MkOGqSvKtJXmPaefB5bbTgyScI,3347
|
|
148
155
|
autogen/agentchat/group/patterns/round_robin.py,sha256=fYzkSoP7pi14Njvf5ZcKYBTymRglMo2BrB96HWzrC_o,3875
|
|
149
156
|
autogen/agentchat/group/safeguards/__init__.py,sha256=FzXqb1WMhDdOlFDwL3RmkfIQ5kjjg885l2YSvwHXcws,668
|
|
150
|
-
autogen/agentchat/group/safeguards/api.py,sha256=
|
|
151
|
-
autogen/agentchat/group/safeguards/enforcer.py,sha256=
|
|
157
|
+
autogen/agentchat/group/safeguards/api.py,sha256=zhbH3AqdK7nenvyWQpaVixBMjdlC9E6HdA8fmteBL9Q,9858
|
|
158
|
+
autogen/agentchat/group/safeguards/enforcer.py,sha256=UOSzH1T11VMM46ccq0-0wqRZvH7JfDXW49qAzhQMdhI,52661
|
|
152
159
|
autogen/agentchat/group/safeguards/events.py,sha256=qHUo9Yi8gyPxtJIh6EmB8s_TQvUxl5a1UhVMezwZZZ0,4092
|
|
153
160
|
autogen/agentchat/group/safeguards/validator.py,sha256=8B-i5VgKVfmCgmB0nhMLESM2DEC5hjOQUcjXlfTKyp4,22855
|
|
154
161
|
autogen/agentchat/group/targets/__init__.py,sha256=AJNSbl9iMe2hiDmZojTp8h889o5OYN3V7f2_2nr8px4,145
|
|
@@ -163,7 +170,7 @@ autogen/agentchat/realtime/experimental/function_observer.py,sha256=WOA27ZfhvWMN
|
|
|
163
170
|
autogen/agentchat/realtime/experimental/realtime_agent.py,sha256=HzNuAfIL5KxnqDa1ML2sLvHp_bS6UfzgRSgWxMEYzXg,5671
|
|
164
171
|
autogen/agentchat/realtime/experimental/realtime_events.py,sha256=zmRr3pwPJpme5VZEADIz5vg9IZoT3Z1NAc3vt1RdWLk,1083
|
|
165
172
|
autogen/agentchat/realtime/experimental/realtime_observer.py,sha256=Y_UULA9CgxqKZo9dgBds0iipjx7cZ9MghrH4HcKd57o,3045
|
|
166
|
-
autogen/agentchat/realtime/experimental/realtime_swarm.py,sha256=
|
|
173
|
+
autogen/agentchat/realtime/experimental/realtime_swarm.py,sha256=Bv_2WEReD84y2xnOUpxtiu0awLtcKyGqHoAysjFxQtA,18000
|
|
167
174
|
autogen/agentchat/realtime/experimental/websockets.py,sha256=bj9b5eq80L3KlGWPP6nn7uyfT_Z47kQqtIRbQkeE5SI,667
|
|
168
175
|
autogen/agentchat/realtime/experimental/audio_adapters/__init__.py,sha256=rd0pEy91LYq0JMvIk8Fv7ZKIQLK7oZbVdgVAwNZDCmQ,315
|
|
169
176
|
autogen/agentchat/realtime/experimental/audio_adapters/twilio_audio_adapter.py,sha256=jBr5I3j6Z2jF6J-PNTvvAW24L0NvJpCul4M_fVP4S-g,6091
|
|
@@ -270,7 +277,7 @@ autogen/interop/langchain/langchain_tool.py,sha256=KOlCvor9tQfx6BILC9O1Qmo4SS4XE
|
|
|
270
277
|
autogen/interop/litellm/__init__.py,sha256=0K9NkQEBXKZI6UVNwD4daTumQL-uhMrAJE33wiSYmkI,237
|
|
271
278
|
autogen/interop/litellm/litellm_config_factory.py,sha256=JuxNRMM4HwYebmOfs-jnH1Cf5uD3SM968pyVtW_49Cw,6272
|
|
272
279
|
autogen/interop/pydantic_ai/__init__.py,sha256=w9tqh96x43Ipq2loD_F-kqwws2RFRs7-98mPxWG-Mjc,238
|
|
273
|
-
autogen/interop/pydantic_ai/pydantic_ai.py,sha256=
|
|
280
|
+
autogen/interop/pydantic_ai/pydantic_ai.py,sha256=QZqxn9dqxtXxzyEe2NQxguMhgiqxv0MNdybn2oh2Ql4,6747
|
|
274
281
|
autogen/io/__init__.py,sha256=c5iZkM24B9j3K0yPQ0HYJnvAdNMqhlRZVXqcfdnGFX4,600
|
|
275
282
|
autogen/io/base.py,sha256=yBFUwpZxOFa4F5_dv4ZWoN8iiEy3oH6xgWoo-TK-bg0,4705
|
|
276
283
|
autogen/io/console.py,sha256=6dYGWntAMgbVX2An14pcs5YyusFsUGeF_-tgR5IMOC0,1892
|
|
@@ -281,7 +288,7 @@ autogen/io/processors/__init__.py,sha256=8-znkWyHiESpMktD4cU_id-HPLE7JD7gArj0y-7
|
|
|
281
288
|
autogen/io/processors/base.py,sha256=60oltHFRWIjZsxzzzK5evPx1M-H0lHZVNVkmItiTNSQ,685
|
|
282
289
|
autogen/io/processors/console_event_processor.py,sha256=sdrVG8LmW2ZUMKoa8bhCpPz1NImz4dFcMaXj1VFlkYg,2214
|
|
283
290
|
autogen/llm_config/__init__.py,sha256=P_jAlr_bz-xr8P0eLeUJ9aF7ruNW3bQ1b1d6lfaYP68,257
|
|
284
|
-
autogen/llm_config/client.py,sha256=
|
|
291
|
+
autogen/llm_config/client.py,sha256=3RANhMmES5du41qTigco-K2cFFf12Gmj-CGvfDP5Iwg,2488
|
|
285
292
|
autogen/llm_config/config.py,sha256=A8N7Rf24cwXAWT-xr0K73IvrBCELyydkvX5gVKRKJAM,16725
|
|
286
293
|
autogen/llm_config/entry.py,sha256=BaZ-o4ASeSN22BAwN9UgXQnJ_lXqLRylbn5vhZkr8YY,6190
|
|
287
294
|
autogen/llm_config/types.py,sha256=alUNKdycgWPo524D0UzvYE25vqs5fjZaN0-z5znSl8w,1174
|
|
@@ -311,11 +318,11 @@ autogen/messages/client_messages.py,sha256=1OsKmdQSkt2gaAAz60Vf683oVJtLEkztLeowQ
|
|
|
311
318
|
autogen/messages/print_message.py,sha256=XoAAOh08MiFBX82OLylweJSlba6Rj1DYfdHRmEMVDbs,1390
|
|
312
319
|
autogen/oai/__init__.py,sha256=KcO_XkHR5B5P9jv5cLXsO1ybIiZ-fNvoagqn5CARonU,1741
|
|
313
320
|
autogen/oai/anthropic.py,sha256=rstyTbGn9lSjpRUxNZWTwkx5qvjgRpf98PJg8CQgOuc,29230
|
|
314
|
-
autogen/oai/bedrock.py,sha256=
|
|
321
|
+
autogen/oai/bedrock.py,sha256=kNP5pMqqjeXmR7m-TBbyti1swDSbPO3owoTQDbdqTwY,25682
|
|
315
322
|
autogen/oai/cerebras.py,sha256=emRF_2xy3gakapyEHYKvZEDvvALFR9AaBK9JeQpH1Tk,12350
|
|
316
|
-
autogen/oai/client.py,sha256=
|
|
317
|
-
autogen/oai/client_utils.py,sha256=
|
|
318
|
-
autogen/oai/cohere.py,sha256=
|
|
323
|
+
autogen/oai/client.py,sha256=xM0jNzhfcnTk1HYJ5IwwWdYYoro52V7DGdOPAktnCQk,67586
|
|
324
|
+
autogen/oai/client_utils.py,sha256=6nrrCsuDy8_JK1zbRCElhPujOiDMnEhLL7uVIa1F9Cc,8771
|
|
325
|
+
autogen/oai/cohere.py,sha256=VKmmQmAaCwcrcRCaljnoJBl1jQeo0P8VIMfOmjHcvFQ,19579
|
|
319
326
|
autogen/oai/gemini.py,sha256=8XWEcqwFIH9lHv8xcMTuxEbcr-GLLEKeFO1mr4Pui88,43762
|
|
320
327
|
autogen/oai/gemini_types.py,sha256=GGt0o1ozWdLobiZMzdtxmpDKKDW-bwgxOQkw5XvJPKI,5861
|
|
321
328
|
autogen/oai/groq.py,sha256=J9YlpiYbKGOl5zsoInLdZfbFQqCUVXAAS666BRvkw48,12621
|
|
@@ -332,6 +339,17 @@ autogen/oai/oai_models/chat_completion_message.py,sha256=60C32Bj4UIGfCzO8CU8Vrtr
|
|
|
332
339
|
autogen/oai/oai_models/chat_completion_message_tool_call.py,sha256=L0SzWLQq7MWW4hykArAuyZS_Tqz_AFuj18YKBQmYI_k,1771
|
|
333
340
|
autogen/oai/oai_models/chat_completion_token_logprob.py,sha256=gC5o8BgScmAn9mBkCdWPgs4G6Es7xWp3spJC5aOxGCs,2031
|
|
334
341
|
autogen/oai/oai_models/completion_usage.py,sha256=-37tfKln6QO-fwC4Smo_mxnjOiNrM_K1Ck26WHhvIP0,1968
|
|
342
|
+
autogen/remote/__init__.py,sha256=j39qEJIb3I4mCBYQ9ButvbSDcrh4-qJEuZWJkP8Z91c,511
|
|
343
|
+
autogen/remote/agent.py,sha256=Q2waHRtrEas-VsHmF-uYon2l5jlWf8-rYAX82FIB16c,7670
|
|
344
|
+
autogen/remote/agent_service.py,sha256=_urzWoxfTcdEvT5WjLvexKbdQrMCUGTA35Mf2zU_q8k,6278
|
|
345
|
+
autogen/remote/errors.py,sha256=e6qr7k-3mI8afCgnBtplZYsb5al1q6rYytwjVUTttvk,491
|
|
346
|
+
autogen/remote/httpx_client_factory.py,sha256=RbO3-d15ygiC744O4GLl-qX2uICqvsSUXXWWi8mGCrY,4822
|
|
347
|
+
autogen/remote/protocol.py,sha256=ILmcZtno9Com4BmtCBnKEPxFriI9EB4LEr5Fewh5kpw,1045
|
|
348
|
+
autogen/remote/retry.py,sha256=8RLm8ABbDE8ZQXO6wRndQxRDeIuNUnCkTaVLL8ag10U,2859
|
|
349
|
+
autogen/remote/runtime.py,sha256=nW4N_7RO2CS8gzP9fqAXuWhiU4q-8XuZE9e6SBJ00yk,3194
|
|
350
|
+
autogen/testing/__init__.py,sha256=e9yi2_Eplb5x59o-f-YR9RUd2sHukgCFHIK04BM7YZo,293
|
|
351
|
+
autogen/testing/messages.py,sha256=v9TaGiWkZclntSGAzbVK1LEC5nMHJrkPJUtcnLGVlIc,1513
|
|
352
|
+
autogen/testing/test_agent.py,sha256=i433We7sGIoqvJDX8o8dZ8GyoUSp7UdJwRiL836td7w,3671
|
|
335
353
|
autogen/tools/__init__.py,sha256=guevGJut7uN2pGpPn9mODaVsTSfeHrGpjjjIEWRBqVo,554
|
|
336
354
|
autogen/tools/dependency_injection.py,sha256=APcLOiajJkpjoicu3wUovjbb0pmidj4M8UUkdq5LsEE,8217
|
|
337
355
|
autogen/tools/function_utils.py,sha256=n_C2H6Y0cG-oQw7YsTH6egQnFwRgEq0MLoe1Jt9vp4I,13762
|
|
@@ -388,8 +406,8 @@ autogen/tools/experimental/wikipedia/wikipedia.py,sha256=phtwNOW5KcvXq-1-3yYjm6E
|
|
|
388
406
|
templates/main.jinja2,sha256=mu7z_4NjI1XMEwQx9KaFQixi4ImfwY0FZQaYUJVBnSc,1765
|
|
389
407
|
templates/client_template/main.jinja2,sha256=9_1pmPNLlPZpfcE0KqXJ6uBVzQtmFqWbxs2xyzCOfxY,2115
|
|
390
408
|
templates/config_template/config.jinja2,sha256=A-p-YBsnEm1iftBIhuIBfIyCY-qw34KWcxalmM6KPWc,167
|
|
391
|
-
ag2-0.
|
|
392
|
-
ag2-0.
|
|
393
|
-
ag2-0.
|
|
394
|
-
ag2-0.
|
|
395
|
-
ag2-0.
|
|
409
|
+
ag2-0.10.0.dist-info/METADATA,sha256=NgS-U8xR1F_VGQI6u2-NPb9BRYe2B5WABpyKrFuBPXY,36090
|
|
410
|
+
ag2-0.10.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
411
|
+
ag2-0.10.0.dist-info/licenses/LICENSE,sha256=GEFQVNayAR-S_rQD5l8hPdgvgyktVdy4Bx5-v90IfRI,11384
|
|
412
|
+
ag2-0.10.0.dist-info/licenses/NOTICE.md,sha256=07iCPQGbth4pQrgkSgZinJGT5nXddkZ6_MGYcBd2oiY,1134
|
|
413
|
+
ag2-0.10.0.dist-info/RECORD,,
|
autogen/a2a/__init__.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
try:
|
|
5
|
+
from a2a.types import AgentCard
|
|
6
|
+
except ImportError as e:
|
|
7
|
+
raise ImportError("a2a-sdk is not installed. Please install it with:\npip install ag2[a2a]") from e
|
|
8
|
+
|
|
9
|
+
import warnings
|
|
10
|
+
|
|
11
|
+
warnings.warn(
|
|
12
|
+
(
|
|
13
|
+
"AG2 Implementation for A2A support is in experimental mode "
|
|
14
|
+
"and is subjected to breaking changes. Once it's stable enough the "
|
|
15
|
+
"experimental mode will be removed. Your feedback is welcome."
|
|
16
|
+
),
|
|
17
|
+
ImportWarning,
|
|
18
|
+
stacklevel=2,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
from autogen.remote.httpx_client_factory import HttpxClientFactory
|
|
22
|
+
|
|
23
|
+
from .agent_executor import AutogenAgentExecutor
|
|
24
|
+
from .client import A2aRemoteAgent
|
|
25
|
+
from .httpx_client_factory import MockClient
|
|
26
|
+
from .server import A2aAgentServer, CardSettings
|
|
27
|
+
|
|
28
|
+
__all__ = (
|
|
29
|
+
"A2aAgentServer",
|
|
30
|
+
"A2aRemoteAgent",
|
|
31
|
+
"AgentCard",
|
|
32
|
+
"AutogenAgentExecutor",
|
|
33
|
+
"CardSettings",
|
|
34
|
+
"HttpxClientFactory",
|
|
35
|
+
"MockClient",
|
|
36
|
+
)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from datetime import datetime, timezone
|
|
6
|
+
|
|
7
|
+
from a2a.server.agent_execution import AgentExecutor, RequestContext
|
|
8
|
+
from a2a.server.events import EventQueue
|
|
9
|
+
from a2a.types import TaskArtifactUpdateEvent, TaskState, TaskStatus, TaskStatusUpdateEvent
|
|
10
|
+
from a2a.utils import new_task
|
|
11
|
+
from a2a.utils.message import new_agent_text_message
|
|
12
|
+
|
|
13
|
+
from autogen import ConversableAgent
|
|
14
|
+
from autogen.doc_utils import export_module
|
|
15
|
+
from autogen.remote.agent_service import AgentService
|
|
16
|
+
|
|
17
|
+
from .utils import request_message_from_a2a, response_message_to_a2a
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@export_module("autogen.a2a")
|
|
21
|
+
class AutogenAgentExecutor(AgentExecutor):
|
|
22
|
+
"""An agent executor that bridges Autogen ConversableAgents with A2A protocols.
|
|
23
|
+
|
|
24
|
+
This class wraps an Autogen ConversableAgent to enable it to be executed within
|
|
25
|
+
the A2A framework, handling message processing, task management, and event publishing.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(self, agent: ConversableAgent) -> None:
|
|
29
|
+
self.agent = AgentService(agent)
|
|
30
|
+
|
|
31
|
+
async def execute(self, context: RequestContext, event_queue: EventQueue) -> None:
|
|
32
|
+
assert context.message
|
|
33
|
+
|
|
34
|
+
task = context.current_task
|
|
35
|
+
if not task:
|
|
36
|
+
task = new_task(context.message)
|
|
37
|
+
task.status.timestamp = datetime.now(timezone.utc).isoformat()
|
|
38
|
+
# publish the task status submitted event
|
|
39
|
+
await event_queue.enqueue_event(task)
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
result = await self.agent(request_message_from_a2a(context.message))
|
|
43
|
+
|
|
44
|
+
except Exception as e:
|
|
45
|
+
# publish the task status failed event
|
|
46
|
+
await event_queue.enqueue_event(
|
|
47
|
+
TaskStatusUpdateEvent(
|
|
48
|
+
task_id=task.id,
|
|
49
|
+
status=TaskStatus(
|
|
50
|
+
state=TaskState.failed,
|
|
51
|
+
message=new_agent_text_message(
|
|
52
|
+
str(e),
|
|
53
|
+
task_id=task.id,
|
|
54
|
+
context_id=context.context_id,
|
|
55
|
+
),
|
|
56
|
+
timestamp=datetime.now(timezone.utc).isoformat(),
|
|
57
|
+
),
|
|
58
|
+
context_id=context.context_id,
|
|
59
|
+
final=True,
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
return
|
|
63
|
+
|
|
64
|
+
artifact, messages = response_message_to_a2a(result, context.context_id, task.id)
|
|
65
|
+
|
|
66
|
+
# publish local chat history events
|
|
67
|
+
for message in messages:
|
|
68
|
+
await event_queue.enqueue_event(
|
|
69
|
+
TaskStatusUpdateEvent(
|
|
70
|
+
task_id=task.id,
|
|
71
|
+
status=TaskStatus(
|
|
72
|
+
state=TaskState.working,
|
|
73
|
+
message=message,
|
|
74
|
+
timestamp=datetime.now(timezone.utc).isoformat(),
|
|
75
|
+
),
|
|
76
|
+
context_id=context.context_id,
|
|
77
|
+
final=False,
|
|
78
|
+
)
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# publish the task result event
|
|
82
|
+
await event_queue.enqueue_event(
|
|
83
|
+
TaskArtifactUpdateEvent(
|
|
84
|
+
task_id=task.id,
|
|
85
|
+
last_chunk=True,
|
|
86
|
+
context_id=context.context_id,
|
|
87
|
+
artifact=artifact,
|
|
88
|
+
)
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# publish the task status completed event
|
|
92
|
+
await event_queue.enqueue_event(
|
|
93
|
+
TaskStatusUpdateEvent(
|
|
94
|
+
task_id=task.id,
|
|
95
|
+
status=TaskStatus(
|
|
96
|
+
state=TaskState.completed,
|
|
97
|
+
timestamp=datetime.now(timezone.utc).isoformat(),
|
|
98
|
+
),
|
|
99
|
+
context_id=context.context_id,
|
|
100
|
+
final=True,
|
|
101
|
+
)
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
async def cancel(self, context: RequestContext, event_queue: EventQueue) -> None:
|
|
105
|
+
pass
|
autogen/a2a/client.py
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import logging
|
|
7
|
+
from pprint import pformat
|
|
8
|
+
from typing import Any, cast
|
|
9
|
+
from uuid import uuid4
|
|
10
|
+
|
|
11
|
+
import httpx
|
|
12
|
+
from a2a.client import A2ACardResolver, A2AClientHTTPError, Client, ClientConfig, ClientEvent
|
|
13
|
+
from a2a.client import ClientFactory as A2AClientFactory
|
|
14
|
+
from a2a.types import AgentCard, Message, Task, TaskIdParams, TaskQueryParams, TaskState
|
|
15
|
+
from a2a.utils.constants import AGENT_CARD_WELL_KNOWN_PATH, EXTENDED_AGENT_CARD_PATH, PREV_AGENT_CARD_WELL_KNOWN_PATH
|
|
16
|
+
|
|
17
|
+
from autogen import ConversableAgent
|
|
18
|
+
from autogen.agentchat.group import ContextVariables
|
|
19
|
+
from autogen.doc_utils import export_module
|
|
20
|
+
from autogen.oai.client import OpenAIWrapper
|
|
21
|
+
from autogen.remote.httpx_client_factory import ClientFactory, EmptyClientFactory
|
|
22
|
+
from autogen.remote.protocol import RequestMessage, ResponseMessage
|
|
23
|
+
|
|
24
|
+
from .errors import A2aAgentNotFoundError, A2aClientError
|
|
25
|
+
from .utils import request_message_to_a2a, response_message_from_a2a_artifacts, response_message_from_a2a_message
|
|
26
|
+
|
|
27
|
+
logger = logging.getLogger(__name__)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@export_module("autogen.a2a")
|
|
31
|
+
class A2aRemoteAgent(ConversableAgent):
|
|
32
|
+
"""`a2a-sdk`-based client for handling asynchronous communication with an A2A server.
|
|
33
|
+
|
|
34
|
+
It has fully-compatible with original `ConversableAgent` API, so you can easily integrate
|
|
35
|
+
remote A2A agents to existing collaborations.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
url: The URL of the A2A server to connect to.
|
|
39
|
+
name: A unique identifier for this client instance.
|
|
40
|
+
silent: whether to print the message sent. If None, will use the value of silent in each function.
|
|
41
|
+
client: An optional HTTPX client instance factory.
|
|
42
|
+
client_config: A2A Client configuration options.
|
|
43
|
+
max_reconnects: Maximum number of reconnection attempts before giving up.
|
|
44
|
+
polling_interval: Time in seconds between polling operations. Works for A2A Servers doesn't support streaming.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
def __init__(
|
|
48
|
+
self,
|
|
49
|
+
url: str,
|
|
50
|
+
name: str,
|
|
51
|
+
*,
|
|
52
|
+
silent: bool | None = None,
|
|
53
|
+
client: ClientFactory | None = None,
|
|
54
|
+
client_config: ClientConfig | None = None,
|
|
55
|
+
max_reconnects: int = 3,
|
|
56
|
+
polling_interval: float = 0.5,
|
|
57
|
+
) -> None:
|
|
58
|
+
self.url = url
|
|
59
|
+
|
|
60
|
+
self._httpx_client_factory = client or EmptyClientFactory()
|
|
61
|
+
self._max_reconnects = max_reconnects
|
|
62
|
+
self._polling_interval = polling_interval
|
|
63
|
+
|
|
64
|
+
super().__init__(name, silent=silent)
|
|
65
|
+
|
|
66
|
+
self.__llm_config: dict[str, Any] = {}
|
|
67
|
+
|
|
68
|
+
self._client_config = client_config or ClientConfig()
|
|
69
|
+
self.__agent_card: AgentCard | None = None
|
|
70
|
+
|
|
71
|
+
self.replace_reply_func(
|
|
72
|
+
ConversableAgent.generate_oai_reply,
|
|
73
|
+
A2aRemoteAgent.generate_remote_reply,
|
|
74
|
+
)
|
|
75
|
+
self.replace_reply_func(
|
|
76
|
+
ConversableAgent.a_generate_oai_reply,
|
|
77
|
+
A2aRemoteAgent.a_generate_remote_reply,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
def generate_remote_reply(
|
|
81
|
+
self,
|
|
82
|
+
messages: list[dict[str, Any]] | None = None,
|
|
83
|
+
sender: ConversableAgent | None = None,
|
|
84
|
+
config: OpenAIWrapper | None = None,
|
|
85
|
+
) -> tuple[bool, dict[str, Any] | None]:
|
|
86
|
+
raise NotImplementedError(f"{self.__class__.__name__} does not support synchronous reply generation")
|
|
87
|
+
|
|
88
|
+
async def a_generate_remote_reply(
|
|
89
|
+
self,
|
|
90
|
+
messages: list[dict[str, Any]] | None = None,
|
|
91
|
+
sender: ConversableAgent | None = None,
|
|
92
|
+
config: OpenAIWrapper | None = None,
|
|
93
|
+
) -> tuple[bool, dict[str, Any] | None]:
|
|
94
|
+
if messages is None:
|
|
95
|
+
messages = self._oai_messages[sender]
|
|
96
|
+
|
|
97
|
+
if not self.__agent_card:
|
|
98
|
+
self.__agent_card = await self._get_agent_card()
|
|
99
|
+
|
|
100
|
+
initial_message = request_message_to_a2a(
|
|
101
|
+
request_message=RequestMessage(
|
|
102
|
+
messages=messages,
|
|
103
|
+
context=self.context_variables.data,
|
|
104
|
+
client_tools=self.__llm_config.get("tools", []),
|
|
105
|
+
),
|
|
106
|
+
context_id=uuid4().hex,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
self._client_config.httpx_client = self._httpx_client_factory()
|
|
110
|
+
async with self._client_config.httpx_client:
|
|
111
|
+
agent_client = A2AClientFactory(self._client_config).create(self.__agent_card)
|
|
112
|
+
|
|
113
|
+
if self.__agent_card.capabilities.streaming:
|
|
114
|
+
reply = await self._ask_streaming(agent_client, initial_message)
|
|
115
|
+
return self._apply_reply(reply, sender)
|
|
116
|
+
|
|
117
|
+
else:
|
|
118
|
+
reply = await self._ask_polling(agent_client, initial_message)
|
|
119
|
+
return self._apply_reply(reply, sender)
|
|
120
|
+
|
|
121
|
+
def _apply_reply(
|
|
122
|
+
self, reply: ResponseMessage | None, sender: ConversableAgent | None
|
|
123
|
+
) -> tuple[bool, dict[str, Any] | None]:
|
|
124
|
+
if not reply:
|
|
125
|
+
return True, None
|
|
126
|
+
|
|
127
|
+
if sender and reply.context:
|
|
128
|
+
context_variables = ContextVariables(reply.context)
|
|
129
|
+
self.context_variables.update(context_variables.to_dict())
|
|
130
|
+
sender.context_variables.update(context_variables.to_dict())
|
|
131
|
+
|
|
132
|
+
return True, reply.messages[-1]
|
|
133
|
+
|
|
134
|
+
async def _ask_streaming(self, client: Client, message: Message) -> ResponseMessage | None:
|
|
135
|
+
connection_attemps = 1
|
|
136
|
+
try:
|
|
137
|
+
async for event in client.send_message(message):
|
|
138
|
+
result, task = self._process_event(event)
|
|
139
|
+
if not task:
|
|
140
|
+
return result
|
|
141
|
+
except httpx.ConnectError as e:
|
|
142
|
+
if task and connection_attemps < self._max_reconnects:
|
|
143
|
+
pass
|
|
144
|
+
|
|
145
|
+
if not self.__agent_card:
|
|
146
|
+
raise A2aClientError("Failed to connect to the agent: agent card not found") from e
|
|
147
|
+
raise A2aClientError(f"Failed to connect to the agent: {pformat(self.__agent_card.model_dump())}") from e
|
|
148
|
+
|
|
149
|
+
task = cast(Task, task)
|
|
150
|
+
while connection_attemps < self._max_reconnects:
|
|
151
|
+
try:
|
|
152
|
+
async for event in client.resubscribe(TaskIdParams(id=task.id)):
|
|
153
|
+
result, task = self._process_event(event)
|
|
154
|
+
if not task:
|
|
155
|
+
return result
|
|
156
|
+
|
|
157
|
+
except httpx.ConnectError as e:
|
|
158
|
+
connection_attemps += 1
|
|
159
|
+
if connection_attemps < self._max_reconnects:
|
|
160
|
+
pass
|
|
161
|
+
|
|
162
|
+
if not self.__agent_card:
|
|
163
|
+
raise A2aClientError("Failed to connect to the agent: agent card not found") from e
|
|
164
|
+
raise A2aClientError(
|
|
165
|
+
f"Failed to connect to the agent: {pformat(self.__agent_card.model_dump())}"
|
|
166
|
+
) from e
|
|
167
|
+
|
|
168
|
+
return None
|
|
169
|
+
|
|
170
|
+
async def _ask_polling(self, client: Client, message: Message) -> ResponseMessage | None:
|
|
171
|
+
try:
|
|
172
|
+
async for event in client.send_message(message):
|
|
173
|
+
result, started_task = self._process_event(event)
|
|
174
|
+
if not started_task:
|
|
175
|
+
return result
|
|
176
|
+
break
|
|
177
|
+
except httpx.ConnectError as e:
|
|
178
|
+
if not self.__agent_card:
|
|
179
|
+
raise A2aClientError("Failed to connect to the agent: agent card not found") from e
|
|
180
|
+
raise A2aClientError(f"Failed to connect to the agent: {pformat(self.__agent_card.model_dump())}") from e
|
|
181
|
+
|
|
182
|
+
started_task, connection_attemps = cast(Task, started_task), 0
|
|
183
|
+
while connection_attemps < self._max_reconnects:
|
|
184
|
+
while True:
|
|
185
|
+
try:
|
|
186
|
+
task = await client.get_task(TaskQueryParams(id=started_task.id))
|
|
187
|
+
|
|
188
|
+
except httpx.ConnectError as e:
|
|
189
|
+
connection_attemps += 1
|
|
190
|
+
if connection_attemps < self._max_reconnects:
|
|
191
|
+
pass
|
|
192
|
+
|
|
193
|
+
if not self.__agent_card:
|
|
194
|
+
raise A2aClientError("Failed to connect to the agent: agent card not found") from e
|
|
195
|
+
raise A2aClientError(
|
|
196
|
+
f"Failed to connect to the agent: {pformat(self.__agent_card.model_dump())}"
|
|
197
|
+
) from e
|
|
198
|
+
|
|
199
|
+
else:
|
|
200
|
+
if _is_task_completed(task):
|
|
201
|
+
return response_message_from_a2a_artifacts(task.artifacts)
|
|
202
|
+
|
|
203
|
+
await asyncio.sleep(self._polling_interval)
|
|
204
|
+
|
|
205
|
+
return None
|
|
206
|
+
|
|
207
|
+
def _process_event(self, event: ClientEvent | Message) -> tuple[ResponseMessage | None, Task | None]:
|
|
208
|
+
if isinstance(event, Message):
|
|
209
|
+
return response_message_from_a2a_message(event), None
|
|
210
|
+
|
|
211
|
+
task, _ = event
|
|
212
|
+
if _is_task_completed(task):
|
|
213
|
+
return response_message_from_a2a_artifacts(task.artifacts), None
|
|
214
|
+
|
|
215
|
+
return None, task
|
|
216
|
+
|
|
217
|
+
def update_tool_signature(
|
|
218
|
+
self,
|
|
219
|
+
tool_sig: str | dict[str, Any],
|
|
220
|
+
is_remove: bool,
|
|
221
|
+
silent_override: bool = False,
|
|
222
|
+
) -> None:
|
|
223
|
+
self.__llm_config = self._update_tool_config(
|
|
224
|
+
self.__llm_config,
|
|
225
|
+
tool_sig=tool_sig,
|
|
226
|
+
is_remove=is_remove,
|
|
227
|
+
silent_override=silent_override,
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
async def _get_agent_card(
|
|
231
|
+
self,
|
|
232
|
+
auth_http_kwargs: dict[str, Any] | None = None,
|
|
233
|
+
) -> AgentCard:
|
|
234
|
+
resolver = A2ACardResolver(httpx_client=self._httpx_client_factory(), base_url=self.url)
|
|
235
|
+
|
|
236
|
+
card: AgentCard | None = None
|
|
237
|
+
|
|
238
|
+
try:
|
|
239
|
+
logger.info(f"Attempting to fetch public agent card from: {self.url}{AGENT_CARD_WELL_KNOWN_PATH}")
|
|
240
|
+
|
|
241
|
+
try:
|
|
242
|
+
card = await resolver.get_agent_card(relative_card_path=AGENT_CARD_WELL_KNOWN_PATH)
|
|
243
|
+
except A2AClientHTTPError as e_public:
|
|
244
|
+
if e_public.status_code == 404:
|
|
245
|
+
logger.info(
|
|
246
|
+
f"Attempting to fetch public agent card from: {self.url}{PREV_AGENT_CARD_WELL_KNOWN_PATH}"
|
|
247
|
+
)
|
|
248
|
+
card = await resolver.get_agent_card(relative_card_path=PREV_AGENT_CARD_WELL_KNOWN_PATH)
|
|
249
|
+
else:
|
|
250
|
+
raise e_public
|
|
251
|
+
|
|
252
|
+
if card.supports_authenticated_extended_card:
|
|
253
|
+
try:
|
|
254
|
+
card = await resolver.get_agent_card(
|
|
255
|
+
relative_card_path=EXTENDED_AGENT_CARD_PATH,
|
|
256
|
+
http_kwargs=auth_http_kwargs,
|
|
257
|
+
)
|
|
258
|
+
except Exception as e_extended:
|
|
259
|
+
logger.warning(
|
|
260
|
+
f"Failed to fetch extended agent card: {e_extended}. Will proceed with public card.",
|
|
261
|
+
exc_info=True,
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
except Exception as e:
|
|
265
|
+
raise A2aAgentNotFoundError(self.name) from e
|
|
266
|
+
|
|
267
|
+
return card
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def _is_task_completed(task: Task) -> bool:
|
|
271
|
+
if task.status.state is TaskState.failed:
|
|
272
|
+
raise A2aClientError(f"Task failed: {pformat(task.model_dump())}")
|
|
273
|
+
|
|
274
|
+
if task.status.state is TaskState.rejected:
|
|
275
|
+
raise A2aClientError(f"Task rejected: {pformat(task.model_dump())}")
|
|
276
|
+
|
|
277
|
+
return task.status.state in (
|
|
278
|
+
TaskState.completed,
|
|
279
|
+
TaskState.canceled,
|
|
280
|
+
)
|