solace-agent-mesh 1.0.9__py3-none-any.whl → 1.3.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 solace-agent-mesh might be problematic. Click here for more details.

Files changed (220) hide show
  1. solace_agent_mesh/agent/adk/adk_llm.txt +182 -42
  2. solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +171 -0
  3. solace_agent_mesh/agent/adk/callbacks.py +165 -104
  4. solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +0 -18
  5. solace_agent_mesh/agent/adk/models/models_llm.txt +104 -55
  6. solace_agent_mesh/agent/adk/runner.py +25 -17
  7. solace_agent_mesh/agent/adk/services.py +3 -3
  8. solace_agent_mesh/agent/adk/setup.py +11 -0
  9. solace_agent_mesh/agent/adk/stream_parser.py +8 -1
  10. solace_agent_mesh/agent/adk/tool_wrapper.py +10 -3
  11. solace_agent_mesh/agent/agent_llm.txt +355 -18
  12. solace_agent_mesh/agent/protocol/event_handlers.py +460 -317
  13. solace_agent_mesh/agent/protocol/protocol_llm.txt +54 -7
  14. solace_agent_mesh/agent/sac/app.py +2 -2
  15. solace_agent_mesh/agent/sac/component.py +211 -517
  16. solace_agent_mesh/agent/sac/sac_llm.txt +133 -63
  17. solace_agent_mesh/agent/testing/testing_llm.txt +25 -58
  18. solace_agent_mesh/agent/tools/peer_agent_tool.py +15 -11
  19. solace_agent_mesh/agent/tools/tools_llm.txt +234 -69
  20. solace_agent_mesh/agent/utils/artifact_helpers.py +35 -1
  21. solace_agent_mesh/agent/utils/utils_llm.txt +90 -105
  22. solace_agent_mesh/assets/docs/404.html +3 -3
  23. solace_agent_mesh/assets/docs/assets/js/6e0db977.39a79ca9.js +1 -0
  24. solace_agent_mesh/assets/docs/assets/js/{75384d09.ccd480c4.js → 75384d09.bf78fbdb.js} +1 -1
  25. solace_agent_mesh/assets/docs/assets/js/90dd9cf6.88f385ea.js +1 -0
  26. solace_agent_mesh/assets/docs/assets/js/f284c35a.fb68323a.js +1 -0
  27. solace_agent_mesh/assets/docs/assets/js/main.08d30374.js +2 -0
  28. solace_agent_mesh/assets/docs/assets/js/runtime~main.458efb1d.js +1 -0
  29. solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +4 -4
  30. solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +4 -4
  31. solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +4 -4
  32. solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +4 -4
  33. solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +4 -4
  34. solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +4 -4
  35. solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +4 -4
  36. solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +4 -4
  37. solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +4 -4
  38. solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +4 -4
  39. solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/index.html +4 -4
  40. solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +4 -4
  41. solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +4 -4
  42. solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +4 -4
  43. solace_agent_mesh/assets/docs/docs/documentation/migration-guides/a2a-upgrade-to-0.3.0/a2a-gateway-upgrade-to-0.3.0/index.html +105 -0
  44. solace_agent_mesh/assets/docs/docs/documentation/migration-guides/a2a-upgrade-to-0.3.0/a2a-technical-migration-map/index.html +53 -0
  45. solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +4 -4
  46. solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +4 -4
  47. solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +4 -4
  48. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +4 -4
  49. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +4 -4
  50. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rag-integration/index.html +4 -4
  51. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +4 -4
  52. solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +4 -4
  53. solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +4 -4
  54. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +4 -4
  55. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +4 -4
  56. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +4 -4
  57. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +4 -4
  58. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +4 -4
  59. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +4 -4
  60. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +4 -4
  61. solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +4 -4
  62. solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +4 -4
  63. solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +4 -4
  64. solace_agent_mesh/assets/docs/lunr-index-1757433031159.json +1 -0
  65. solace_agent_mesh/assets/docs/lunr-index.json +1 -1
  66. solace_agent_mesh/assets/docs/search-doc-1757433031159.json +1 -0
  67. solace_agent_mesh/assets/docs/search-doc.json +1 -1
  68. solace_agent_mesh/assets/docs/sitemap.xml +1 -1
  69. solace_agent_mesh/cli/__init__.py +1 -1
  70. solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +125 -48
  71. solace_agent_mesh/cli/commands/eval_cmd.py +14 -0
  72. solace_agent_mesh/cli/commands/init_cmd/__init__.py +53 -31
  73. solace_agent_mesh/cli/commands/init_cmd/database_step.py +91 -0
  74. solace_agent_mesh/cli/commands/init_cmd/env_step.py +19 -8
  75. solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +80 -25
  76. solace_agent_mesh/cli/commands/init_cmd/web_init_step.py +32 -10
  77. solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +74 -15
  78. solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +0 -2
  79. solace_agent_mesh/cli/commands/run_cmd.py +5 -3
  80. solace_agent_mesh/cli/utils.py +68 -12
  81. solace_agent_mesh/client/webui/frontend/static/assets/authCallback-vY5eu2lI.js +1 -0
  82. solace_agent_mesh/client/webui/frontend/static/assets/client-BeBkzgWW.js +25 -0
  83. solace_agent_mesh/client/webui/frontend/static/assets/main-Bjys1KQs.js +339 -0
  84. solace_agent_mesh/client/webui/frontend/static/assets/main-C03yrETa.css +1 -0
  85. solace_agent_mesh/client/webui/frontend/static/assets/vendor-CE0AeXyK.js +395 -0
  86. solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -2
  87. solace_agent_mesh/client/webui/frontend/static/index.html +4 -3
  88. solace_agent_mesh/common/a2a/__init__.py +213 -0
  89. solace_agent_mesh/common/a2a/a2a_llm.txt +182 -0
  90. solace_agent_mesh/common/a2a/artifact.py +328 -0
  91. solace_agent_mesh/common/a2a/events.py +183 -0
  92. solace_agent_mesh/common/a2a/message.py +307 -0
  93. solace_agent_mesh/common/a2a/protocol.py +513 -0
  94. solace_agent_mesh/common/a2a/task.py +127 -0
  95. solace_agent_mesh/common/a2a/translation.py +653 -0
  96. solace_agent_mesh/common/a2a/types.py +54 -0
  97. solace_agent_mesh/common/a2a_spec/a2a.json +2576 -0
  98. solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +407 -0
  99. solace_agent_mesh/common/a2a_spec/schemas/agent_progress_update.json +18 -0
  100. solace_agent_mesh/common/a2a_spec/schemas/artifact_creation_progress.json +31 -0
  101. solace_agent_mesh/common/a2a_spec/schemas/llm_invocation.json +18 -0
  102. solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +235 -0
  103. solace_agent_mesh/common/a2a_spec/schemas/tool_invocation_start.json +26 -0
  104. solace_agent_mesh/common/a2a_spec/schemas/tool_result.json +25 -0
  105. solace_agent_mesh/common/agent_registry.py +1 -1
  106. solace_agent_mesh/common/common_llm.txt +192 -70
  107. solace_agent_mesh/common/data_parts.py +99 -0
  108. solace_agent_mesh/common/middleware/middleware_llm.txt +17 -17
  109. solace_agent_mesh/common/sac/__init__.py +0 -0
  110. solace_agent_mesh/common/sac/sac_llm.txt +71 -0
  111. solace_agent_mesh/common/sac/sam_component_base.py +252 -0
  112. solace_agent_mesh/common/services/providers/providers_llm.txt +51 -84
  113. solace_agent_mesh/common/services/services_llm.txt +206 -26
  114. solace_agent_mesh/common/utils/artifact_utils.py +29 -0
  115. solace_agent_mesh/common/utils/embeds/embeds_llm.txt +176 -80
  116. solace_agent_mesh/common/utils/embeds/resolver.py +1 -0
  117. solace_agent_mesh/common/utils/utils_llm.txt +323 -42
  118. solace_agent_mesh/config_portal/backend/common.py +2 -2
  119. solace_agent_mesh/config_portal/backend/plugin_catalog/constants.py +1 -1
  120. solace_agent_mesh/config_portal/frontend/static/client/assets/_index-bFMKlzKf.js +98 -0
  121. solace_agent_mesh/config_portal/frontend/static/client/assets/{manifest-d845808d.js → manifest-89db7c30.js} +1 -1
  122. solace_agent_mesh/config_portal/frontend/static/client/index.html +1 -1
  123. solace_agent_mesh/core_a2a/core_a2a_llm.txt +10 -8
  124. solace_agent_mesh/core_a2a/service.py +20 -44
  125. solace_agent_mesh/evaluation/message_organizer.py +35 -56
  126. solace_agent_mesh/evaluation/run.py +26 -5
  127. solace_agent_mesh/evaluation/subscriber.py +35 -10
  128. solace_agent_mesh/evaluation/summary_builder.py +27 -34
  129. solace_agent_mesh/gateway/base/app.py +27 -1
  130. solace_agent_mesh/gateway/base/base_llm.txt +177 -72
  131. solace_agent_mesh/gateway/base/component.py +294 -523
  132. solace_agent_mesh/gateway/gateway_llm.txt +299 -58
  133. solace_agent_mesh/gateway/http_sse/ARCHITECTURE_GUIDE.md +676 -0
  134. solace_agent_mesh/gateway/http_sse/alembic/env.py +85 -0
  135. solace_agent_mesh/gateway/http_sse/alembic/script.py.mako +28 -0
  136. solace_agent_mesh/gateway/http_sse/alembic/versions/b1c2d3e4f5g6_add_database_indexes.py +83 -0
  137. solace_agent_mesh/gateway/http_sse/alembic/versions/d5b3f8f2e9a0_create_initial_database.py +58 -0
  138. solace_agent_mesh/gateway/http_sse/alembic.ini +147 -0
  139. solace_agent_mesh/gateway/http_sse/api/__init__.py +11 -0
  140. solace_agent_mesh/gateway/http_sse/api/controllers/__init__.py +9 -0
  141. solace_agent_mesh/gateway/http_sse/api/controllers/session_controller.py +355 -0
  142. solace_agent_mesh/gateway/http_sse/api/controllers/task_controller.py +279 -0
  143. solace_agent_mesh/gateway/http_sse/api/controllers/user_controller.py +35 -0
  144. solace_agent_mesh/gateway/http_sse/api/dto/__init__.py +10 -0
  145. solace_agent_mesh/gateway/http_sse/api/dto/requests/__init__.py +37 -0
  146. solace_agent_mesh/gateway/http_sse/api/dto/requests/session_requests.py +49 -0
  147. solace_agent_mesh/gateway/http_sse/api/dto/requests/task_requests.py +66 -0
  148. solace_agent_mesh/gateway/http_sse/api/dto/responses/__init__.py +43 -0
  149. solace_agent_mesh/gateway/http_sse/api/dto/responses/session_responses.py +68 -0
  150. solace_agent_mesh/gateway/http_sse/api/dto/responses/task_responses.py +74 -0
  151. solace_agent_mesh/gateway/http_sse/app.py +31 -1
  152. solace_agent_mesh/gateway/http_sse/application/__init__.py +3 -0
  153. solace_agent_mesh/gateway/http_sse/application/services/__init__.py +3 -0
  154. solace_agent_mesh/gateway/http_sse/application/services/session_service.py +135 -0
  155. solace_agent_mesh/gateway/http_sse/component.py +371 -236
  156. solace_agent_mesh/gateway/http_sse/components/components_llm.txt +29 -29
  157. solace_agent_mesh/gateway/http_sse/dependencies.py +142 -39
  158. solace_agent_mesh/gateway/http_sse/domain/entities/__init__.py +3 -0
  159. solace_agent_mesh/gateway/http_sse/domain/entities/session.py +90 -0
  160. solace_agent_mesh/gateway/http_sse/domain/repositories/__init__.py +3 -0
  161. solace_agent_mesh/gateway/http_sse/domain/repositories/session_repository.py +54 -0
  162. solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +272 -36
  163. solace_agent_mesh/gateway/http_sse/infrastructure/__init__.py +4 -0
  164. solace_agent_mesh/gateway/http_sse/infrastructure/dependency_injection/__init__.py +3 -0
  165. solace_agent_mesh/gateway/http_sse/infrastructure/dependency_injection/container.py +123 -0
  166. solace_agent_mesh/gateway/http_sse/infrastructure/persistence/__init__.py +4 -0
  167. solace_agent_mesh/gateway/http_sse/infrastructure/persistence/database_persistence_service.py +16 -0
  168. solace_agent_mesh/gateway/http_sse/infrastructure/persistence/database_service.py +119 -0
  169. solace_agent_mesh/gateway/http_sse/infrastructure/persistence/models.py +31 -0
  170. solace_agent_mesh/gateway/http_sse/infrastructure/persistence_service.py +12 -0
  171. solace_agent_mesh/gateway/http_sse/infrastructure/repositories/__init__.py +3 -0
  172. solace_agent_mesh/gateway/http_sse/infrastructure/repositories/session_repository.py +174 -0
  173. solace_agent_mesh/gateway/http_sse/main.py +293 -91
  174. solace_agent_mesh/gateway/http_sse/routers/agents.py +1 -1
  175. solace_agent_mesh/gateway/http_sse/routers/artifacts.py +137 -56
  176. solace_agent_mesh/gateway/http_sse/routers/config.py +3 -1
  177. solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +231 -5
  178. solace_agent_mesh/gateway/http_sse/routers/tasks.py +199 -171
  179. solace_agent_mesh/gateway/http_sse/routers/visualization.py +7 -7
  180. solace_agent_mesh/gateway/http_sse/services/agent_service.py +1 -1
  181. solace_agent_mesh/gateway/http_sse/services/services_llm.txt +89 -135
  182. solace_agent_mesh/gateway/http_sse/services/task_service.py +2 -5
  183. solace_agent_mesh/gateway/http_sse/session_manager.py +64 -30
  184. solace_agent_mesh/gateway/http_sse/shared/__init__.py +9 -0
  185. solace_agent_mesh/gateway/http_sse/shared/auth_utils.py +29 -0
  186. solace_agent_mesh/gateway/http_sse/shared/enums.py +45 -0
  187. solace_agent_mesh/gateway/http_sse/shared/types.py +45 -0
  188. solace_agent_mesh/solace_agent_mesh_llm.txt +362 -0
  189. solace_agent_mesh/templates/gateway_component_template.py +149 -98
  190. solace_agent_mesh/templates/shared_config.yaml +4 -5
  191. solace_agent_mesh/templates/webui.yaml +8 -10
  192. {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/METADATA +9 -6
  193. {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/RECORD +197 -141
  194. solace_agent_mesh/assets/docs/assets/js/f284c35a.731836ad.js +0 -1
  195. solace_agent_mesh/assets/docs/assets/js/main.3d0e7879.js +0 -2
  196. solace_agent_mesh/assets/docs/assets/js/runtime~main.05d19492.js +0 -1
  197. solace_agent_mesh/assets/docs/lunr-index-1757091012487.json +0 -1
  198. solace_agent_mesh/assets/docs/search-doc-1757091012487.json +0 -1
  199. solace_agent_mesh/client/webui/frontend/static/assets/authCallback-BmF2l6vg.js +0 -1
  200. solace_agent_mesh/client/webui/frontend/static/assets/client-D881Dttc.js +0 -49
  201. solace_agent_mesh/client/webui/frontend/static/assets/main-D0FnP_W4.css +0 -1
  202. solace_agent_mesh/client/webui/frontend/static/assets/main-Do32sFPX.js +0 -708
  203. solace_agent_mesh/common/a2a_protocol.py +0 -564
  204. solace_agent_mesh/common/client/__init__.py +0 -4
  205. solace_agent_mesh/common/client/card_resolver.py +0 -21
  206. solace_agent_mesh/common/client/client.py +0 -85
  207. solace_agent_mesh/common/client/client_llm.txt +0 -133
  208. solace_agent_mesh/common/server/__init__.py +0 -4
  209. solace_agent_mesh/common/server/server.py +0 -122
  210. solace_agent_mesh/common/server/server_llm.txt +0 -169
  211. solace_agent_mesh/common/server/task_manager.py +0 -291
  212. solace_agent_mesh/common/server/utils.py +0 -28
  213. solace_agent_mesh/common/types.py +0 -411
  214. solace_agent_mesh/config_portal/frontend/static/client/assets/_index-Bym6YkMd.js +0 -98
  215. solace_agent_mesh/gateway/http_sse/routers/sessions.py +0 -80
  216. solace_agent_mesh/gateway/http_sse/routers/users.py +0 -59
  217. /solace_agent_mesh/assets/docs/assets/js/{main.3d0e7879.js.LICENSE.txt → main.08d30374.js.LICENSE.txt} +0 -0
  218. {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/WHEEL +0 -0
  219. {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/entry_points.txt +0 -0
  220. {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/licenses/LICENSE +0 -0
@@ -1 +1 @@
1
- window.__remixManifest={"entry":{"module":"/assets/entry.client-mvZjNKiz.js","imports":["/assets/index-DzNKzXrc.js","/assets/components-Rk0n-9cK.js"],"css":[]},"routes":{"root":{"id":"root","path":"","hasAction":false,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/root-BWvk5-gF.js","imports":["/assets/index-DzNKzXrc.js","/assets/components-Rk0n-9cK.js"],"css":["/assets/root-DxRwaWiE.css"]},"routes/_index":{"id":"routes/_index","parentId":"root","index":true,"hasAction":false,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/_index-Bym6YkMd.js","imports":["/assets/index-DzNKzXrc.js"],"css":[]}},"url":"/assets/manifest-d845808d.js","version":"d845808d"};
1
+ window.__remixManifest={"entry":{"module":"/assets/entry.client-mvZjNKiz.js","imports":["/assets/index-DzNKzXrc.js","/assets/components-Rk0n-9cK.js"],"css":[]},"routes":{"root":{"id":"root","path":"","hasAction":false,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/root-BWvk5-gF.js","imports":["/assets/index-DzNKzXrc.js","/assets/components-Rk0n-9cK.js"],"css":["/assets/root-DxRwaWiE.css"]},"routes/_index":{"id":"routes/_index","parentId":"root","index":true,"hasAction":false,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasErrorBoundary":false,"module":"/assets/_index-bFMKlzKf.js","imports":["/assets/index-DzNKzXrc.js"],"css":[]}},"url":"/assets/manifest-89db7c30.js","version":"89db7c30"};
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/assets/root-DxRwaWiE.css"/><link rel="preconnect" href="https://fonts.googleapis.com"/><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous"/><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&amp;display=swap"/></head><body><p>Loading...</p><link rel="modulepreload" href="/assets/manifest-d845808d.js"/><link rel="modulepreload" href="/assets/entry.client-mvZjNKiz.js"/><link rel="modulepreload" href="/assets/index-DzNKzXrc.js"/><link rel="modulepreload" href="/assets/components-Rk0n-9cK.js"/><link rel="modulepreload" href="/assets/root-BWvk5-gF.js"/><script>window.__remixContext = {"basename":"/","future":{"v3_fetcherPersist":false,"v3_relativeSplatPath":false,"v3_throwAbortReason":false,"v3_routeConfig":false,"v3_singleFetch":false,"v3_lazyRouteDiscovery":false,"unstable_optimizeDeps":false},"isSpaMode":true,"state":{"loaderData":{"root":null,"routes/_index":null},"actionData":null,"errors":null}};</script><script type="module" async="">import "/assets/manifest-d845808d.js";
2
+ <html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/assets/root-DxRwaWiE.css"/><link rel="preconnect" href="https://fonts.googleapis.com"/><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous"/><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&amp;display=swap"/></head><body><p>Loading...</p><link rel="modulepreload" href="/assets/manifest-89db7c30.js"/><link rel="modulepreload" href="/assets/entry.client-mvZjNKiz.js"/><link rel="modulepreload" href="/assets/index-DzNKzXrc.js"/><link rel="modulepreload" href="/assets/components-Rk0n-9cK.js"/><link rel="modulepreload" href="/assets/root-BWvk5-gF.js"/><script>window.__remixContext = {"basename":"/","future":{"v3_fetcherPersist":false,"v3_relativeSplatPath":false,"v3_throwAbortReason":false,"v3_routeConfig":false,"v3_singleFetch":false,"v3_lazyRouteDiscovery":false,"unstable_optimizeDeps":false},"isSpaMode":true,"state":{"loaderData":{"root":null,"routes/_index":null},"actionData":null,"errors":null}};</script><script type="module" async="">import "/assets/manifest-89db7c30.js";
3
3
  import * as route0 from "/assets/root-BWvk5-gF.js";
4
4
 
5
5
  window.__remixRouteModules = {"root":route0};
@@ -11,18 +11,18 @@ The `core_a2a` directory provides a reusable service layer for core Agent-to-Age
11
11
 
12
12
  ### __init__.py
13
13
  **Purpose:** Package initialization for the core A2A service layer
14
- **Import:** `import core_a2a`
14
+ **Import:** `import solace_agent_mesh.core_a2a`
15
15
 
16
16
  No public classes, functions, or constants defined.
17
17
 
18
18
  ### service.py
19
19
  **Purpose:** Provides the main CoreA2AService class for handling A2A protocol operations
20
- **Import:** `from core_a2a.service import CoreA2AService`
20
+ **Import:** `from solace_agent_mesh.core_a2a.service import CoreA2AService`
21
21
 
22
22
  **Classes:**
23
23
  - `CoreA2AService(agent_registry: AgentRegistry, namespace: str)` - Main service class for A2A operations
24
- - `submit_task(agent_name: str, a2a_message: A2AMessage, session_id: str, client_id: str, reply_to_topic: str, user_id: str = "default_user", a2a_user_scopes: Optional[List[str]] = None, metadata_override: Optional[Dict[str, Any]] = None) -> Tuple[str, Dict, Dict]` - Constructs topic, payload, and user properties for non-streaming task requests
25
- - `submit_streaming_task(agent_name: str, a2a_message: A2AMessage, session_id: str, client_id: str, reply_to_topic: str, status_to_topic: str, user_id: str = "default_user", a2a_user_scopes: Optional[List[str]] = None, metadata_override: Optional[Dict[str, Any]] = None) -> Tuple[str, Dict, Dict]` - Constructs topic, payload, and user properties for streaming task requests
24
+ - `submit_task(agent_name: str, a2a_message: A2AMessage, session_id: str, client_id: str, reply_to_topic: str, user_id: str = "default_user", a2a_user_config: Optional[Dict[str, Any]] = None, metadata_override: Optional[Dict[str, Any]] = None) -> Tuple[str, Dict, Dict]` - Constructs topic, payload, and user properties for non-streaming task requests
25
+ - `submit_streaming_task(agent_name: str, a2a_message: A2AMessage, session_id: str, client_id: str, reply_to_topic: str, status_to_topic: str, user_id: str = "default_user", a2a_user_config: Optional[Dict[str, Any]] = None, metadata_override: Optional[Dict[str, Any]] = None) -> Tuple[str, Dict, Dict]` - Constructs topic, payload, and user properties for streaming task requests
26
26
  - `cancel_task(agent_name: str, task_id: str, client_id: str, user_id: str = "default_user") -> Tuple[str, Dict, Dict]` - Constructs topic, payload, and user properties for task cancellation
27
27
  - `get_agent(agent_name: str) -> Optional[AgentCard]` - Retrieves a specific agent card by name from the registry
28
28
  - `get_all_agents() -> List[AgentCard]` - Retrieves all currently discovered agent cards from the registry
@@ -40,9 +40,9 @@ None
40
40
  **Usage Examples:**
41
41
  ```python
42
42
  # Import required dependencies
43
- from core_a2a.service import CoreA2AService
44
- from common.agent_registry import AgentRegistry
45
- from common.types import A2AMessage, AgentCard
43
+ from solace_agent_mesh.core_a2a.service import CoreA2AService
44
+ from solace_agent_mesh.common.agent_registry import AgentRegistry
45
+ from a2a.types import A2AMessage, AgentCard
46
46
 
47
47
  # Initialize the service
48
48
  agent_registry = AgentRegistry()
@@ -85,4 +85,6 @@ all_agents = service.get_all_agents()
85
85
  # Process discovery message
86
86
  agent_card = AgentCard(name="new_agent", description="A new agent")
87
87
  service.process_discovery_message(agent_card)
88
- ```
88
+ ```
89
+
90
+ # content_hash: fcc947b32fa06db11f6cdf1064dfd9a68ee152373677a574602c182fc8c62f56
@@ -8,16 +8,11 @@ from typing import Dict, Optional, Any, List, Tuple
8
8
 
9
9
  from solace_ai_connector.common.log import log
10
10
 
11
- from ..common.types import (
12
- SendTaskRequest,
13
- SendTaskStreamingRequest,
14
- CancelTaskRequest,
15
- TaskIdParams,
16
- TaskSendParams,
11
+ from a2a.types import (
17
12
  Message as A2AMessage,
18
13
  AgentCard,
19
14
  )
20
- from ..common.a2a_protocol import get_agent_request_topic
15
+ from ..common import a2a
21
16
  from ..common.agent_registry import AgentRegistry
22
17
 
23
18
 
@@ -89,25 +84,17 @@ class CoreA2AService:
89
84
  raise ValueError("Missing required parameters for submit_task")
90
85
 
91
86
  try:
92
- params = TaskSendParams(
93
- id=task_id,
94
- sessionId=session_id,
87
+ if not a2a_message.contextId:
88
+ a2a_message.contextId = session_id
89
+
90
+ request = a2a.create_send_message_request(
95
91
  message=a2a_message,
96
- acceptedOutputModes=["text", "data", "file"],
92
+ task_id=task_id,
93
+ metadata=metadata_override,
97
94
  )
95
+ payload = request.model_dump(by_alias=True, exclude_none=True)
98
96
 
99
- current_metadata = params.metadata or {}
100
- if metadata_override:
101
- current_metadata.update(metadata_override)
102
- log.debug(
103
- "%s Merged metadata_override: %s", log_prefix, metadata_override
104
- )
105
- params.metadata = current_metadata if current_metadata else None
106
-
107
- request = SendTaskRequest(params=params)
108
- payload = request.model_dump(exclude_none=True)
109
-
110
- target_topic = get_agent_request_topic(self.namespace, agent_name)
97
+ target_topic = a2a.get_agent_request_topic(self.namespace, agent_name)
111
98
 
112
99
  user_properties = {
113
100
  "replyTo": reply_to_topic,
@@ -189,26 +176,17 @@ class CoreA2AService:
189
176
  raise ValueError("Missing required parameters for submit_streaming_task")
190
177
 
191
178
  try:
179
+ if not a2a_message.contextId:
180
+ a2a_message.contextId = session_id
192
181
 
193
- params = TaskSendParams(
194
- id=task_id,
195
- sessionId=session_id,
182
+ request = a2a.create_send_streaming_message_request(
196
183
  message=a2a_message,
197
- acceptedOutputModes=["text", "data", "file"],
184
+ task_id=task_id,
185
+ metadata=metadata_override,
198
186
  )
187
+ payload = request.model_dump(by_alias=True, exclude_none=True)
199
188
 
200
- current_metadata = params.metadata or {}
201
- if metadata_override:
202
- current_metadata.update(metadata_override)
203
- log.debug(
204
- "%s Merged metadata_override: %s", log_prefix, metadata_override
205
- )
206
- params.metadata = current_metadata if current_metadata else None
207
-
208
- request = SendTaskStreamingRequest(params=params)
209
- payload = request.model_dump(exclude_none=True)
210
-
211
- target_topic = get_agent_request_topic(self.namespace, agent_name)
189
+ target_topic = a2a.get_agent_request_topic(self.namespace, agent_name)
212
190
 
213
191
  user_properties = {
214
192
  "replyTo": reply_to_topic,
@@ -273,12 +251,10 @@ class CoreA2AService:
273
251
  raise ValueError("Missing required parameters for cancel_task")
274
252
 
275
253
  try:
276
- params = TaskIdParams(id=task_id)
277
-
278
- request = CancelTaskRequest(params=params)
279
- payload = request.model_dump(exclude_none=True)
254
+ request = a2a.create_cancel_task_request(task_id=task_id)
255
+ payload = request.model_dump(by_alias=True, exclude_none=True)
280
256
 
281
- target_topic = get_agent_request_topic(self.namespace, agent_name)
257
+ target_topic = a2a.get_agent_request_topic(self.namespace, agent_name)
282
258
 
283
259
  user_properties = {
284
260
  "clientId": client_id,
@@ -106,16 +106,22 @@ class TaskIdExtractor:
106
106
  Extract task ID using multiple strategies in order of preference.
107
107
  Returns (parent_task_id, sub_task_id) tuple.
108
108
  """
109
+ if not isinstance(message.payload, dict):
110
+ return None, None
111
+
109
112
  strategies = [
110
- self._extract_from_payload_metadata,
111
- self._extract_from_payload_params,
112
- self._extract_from_payload_result,
113
+ self._extract_from_subtask_delegation,
114
+ self._extract_from_toplevel_id,
115
+ self._extract_from_result_object,
113
116
  self._extract_from_topic,
114
117
  ]
115
118
 
116
119
  for strategy in strategies:
117
120
  try:
118
- task_id, sub_task_id = strategy(message)
121
+ if strategy.__name__ == "_extract_from_topic":
122
+ task_id, sub_task_id = strategy(message)
123
+ else:
124
+ task_id, sub_task_id = strategy(message.payload)
119
125
  if task_id:
120
126
  return task_id, sub_task_id
121
127
  except Exception as e:
@@ -124,67 +130,40 @@ class TaskIdExtractor:
124
130
 
125
131
  return None, None
126
132
 
127
- def _extract_from_payload_metadata(
128
- self, message: TaskMessage
133
+ def _extract_from_subtask_delegation(
134
+ self, payload: dict
129
135
  ) -> Tuple[Optional[str], Optional[str]]:
130
- """Strategy 1: Extract from payload metadata (parent-child relationship)."""
131
- payload = message.payload
132
-
133
- if not isinstance(payload, dict):
134
- return None, None
135
-
136
+ """Strategy 1: Check for sub-task delegation (agent-to-agent calls)."""
136
137
  params = payload.get("params", {})
137
- if not isinstance(params, dict):
138
- return None, None
139
-
140
- metadata = params.get("metadata", {})
141
- if not isinstance(metadata, dict):
142
- return None, None
143
-
144
- parent_task_id = metadata.get("parentTaskId")
145
- sub_task_id = params.get("id")
146
-
147
- if parent_task_id and sub_task_id:
148
- return parent_task_id, sub_task_id
149
-
138
+ if isinstance(params, dict):
139
+ message_param = params.get("message", {})
140
+ if isinstance(message_param, dict):
141
+ metadata = message_param.get("metadata", {})
142
+ if isinstance(metadata, dict):
143
+ parent_task_id = metadata.get("parentTaskId")
144
+ sub_task_id = payload.get("id")
145
+ if parent_task_id and sub_task_id:
146
+ return parent_task_id, sub_task_id
150
147
  return None, None
151
148
 
152
- def _extract_from_payload_params(
153
- self, message: TaskMessage
149
+ def _extract_from_toplevel_id(
150
+ self, payload: dict
154
151
  ) -> Tuple[Optional[str], Optional[str]]:
155
- """Strategy 2: Extract from payload params (direct task ID)."""
156
- payload = message.payload
157
-
158
- if not isinstance(payload, dict):
159
- return None, None
160
-
161
- params = payload.get("params", {})
162
- if not isinstance(params, dict):
163
- return None, None
164
-
165
- task_id = params.get("id")
166
- if task_id and isinstance(task_id, str) and task_id.startswith("task-"):
152
+ """Strategy 2: Get the primary task ID from the top-level 'id' field."""
153
+ task_id = payload.get("id")
154
+ if task_id and isinstance(task_id, str):
167
155
  return task_id, None
168
-
169
156
  return None, None
170
157
 
171
- def _extract_from_payload_result(
172
- self, message: TaskMessage
158
+ def _extract_from_result_object(
159
+ self, payload: dict
173
160
  ) -> Tuple[Optional[str], Optional[str]]:
174
- """Strategy 3: Extract from payload result."""
175
- payload = message.payload
176
-
177
- if not isinstance(payload, dict):
178
- return None, None
179
-
161
+ """Strategy 3: Fallback for status updates which also have taskId nested."""
180
162
  result = payload.get("result", {})
181
- if not isinstance(result, dict):
182
- return None, None
183
-
184
- task_id = result.get("id")
185
- if task_id and isinstance(task_id, str) and task_id.startswith("task-"):
186
- return task_id, None
187
-
163
+ if isinstance(result, dict):
164
+ task_id = result.get("taskId")
165
+ if task_id and isinstance(task_id, str):
166
+ return task_id, None
188
167
  return None, None
189
168
 
190
169
  def _extract_from_topic(
@@ -197,7 +176,7 @@ class TaskIdExtractor:
197
176
 
198
177
  # Extract the last part of the topic path
199
178
  task_id = topic.split("/")[-1]
200
- if task_id.startswith("task-"):
179
+ if task_id.startswith("gdk-task-"):
201
180
  return task_id, None
202
181
 
203
182
  return None, None
@@ -33,7 +33,7 @@ class EvaluationConfig:
33
33
  """Centralized configuration with validation and defaults."""
34
34
 
35
35
  # Constants
36
- DEFAULT_STARTUP_WAIT_TIME = 20
36
+ DEFAULT_STARTUP_WAIT_TIME = 60
37
37
  DEFAULT_TEST_TIMEOUT = 60
38
38
 
39
39
  def __init__(self, config_data: Dict[str, Any]):
@@ -108,13 +108,34 @@ class ProcessManager:
108
108
  command, stdout=sys.stdout, stderr=sys.stderr, cwd=project_root
109
109
  )
110
110
 
111
- print(
112
- f"Waiting for server to start... ({self.config.DEFAULT_STARTUP_WAIT_TIME} seconds)"
113
- )
114
- time.sleep(self.config.DEFAULT_STARTUP_WAIT_TIME)
111
+ print("Waiting for server to become healthy...")
112
+ self._wait_for_server_ready()
115
113
 
116
114
  return self.process, self.namespace
117
115
 
116
+ def _wait_for_server_ready(self):
117
+ """Poll the health endpoint until the server is ready."""
118
+ start_time = time.time()
119
+ health_url = f"{self.config.API_BASE_URL.replace('/api/v2', '')}/health"
120
+
121
+ while time.time() - start_time < self.config.DEFAULT_STARTUP_WAIT_TIME:
122
+ try:
123
+ response = requests.get(health_url)
124
+ if response.status_code == 200:
125
+ print("Server is healthy.")
126
+ time.sleep(1) # Wait an extra second as requested
127
+ return
128
+ except requests.ConnectionError:
129
+ # Server is not yet available, wait and retry
130
+ time.sleep(1)
131
+ except Exception as e:
132
+ print(f"An unexpected error occurred during health check: {e}")
133
+ time.sleep(1)
134
+
135
+ raise RuntimeError(
136
+ f"Server did not become healthy within {self.config.DEFAULT_STARTUP_WAIT_TIME} seconds."
137
+ )
138
+
118
139
  def stop_services(self, subscriber: Optional[Subscriber] = None):
119
140
  """Clean up running processes."""
120
141
  if subscriber:
@@ -120,9 +120,14 @@ class SubscriptionConfig:
120
120
  "/gateway/response/",
121
121
  ]
122
122
  )
123
+ blocked_topic_infixes: List[str] = field(
124
+ default_factory=lambda: [
125
+ "/discovery/"
126
+ ]
127
+ )
123
128
  message_timeout: int = 1000
124
129
  filter_non_final_status: bool = True
125
- remove_config_keys: bool = True
130
+ remove_config_keys: bool = False
126
131
 
127
132
  def __post_init__(self):
128
133
  """Validate subscription configuration."""
@@ -142,7 +147,10 @@ class SubscriptionConfig:
142
147
 
143
148
  def is_topic_allowed(self, topic: str) -> bool:
144
149
  """Check if a topic is allowed based on configured infixes."""
145
- return any(infix in topic for infix in self.allowed_topic_infixes)
150
+ # return any(infix in topic for infix in self.allowed_topic_infixes)
151
+ if any(infix in topic for infix in self.blocked_topic_infixes):
152
+ return False
153
+ return True
146
154
 
147
155
 
148
156
  @dataclass
@@ -300,20 +308,37 @@ class MessageProcessor:
300
308
  if not self.config.filter_non_final_status:
301
309
  return False
302
310
 
303
- if "/gateway/status/" not in topic:
304
- return False
305
-
306
311
  try:
307
- if isinstance(payload, dict):
308
- result = payload.get("result", {})
309
- if isinstance(result, dict):
310
- # Filter out non-final status messages
311
- return not result.get("final", True)
312
+ # Filter only for llm_invocation
313
+ if self._find_part_type(payload, "llm_invocation"):
314
+ return True
315
+
316
+ # Filter only for llm_response
317
+ if self._find_part_type(payload, "llm_response"):
318
+ return True
319
+
320
+ # Filter out agent progress update messages
321
+ if self._find_part_type(payload, "agent_progress_update"):
322
+ return True
312
323
  except Exception:
313
324
  pass
314
325
 
315
326
  return False
316
327
 
328
+ def _find_part_type(self, data: Any, type_to_find: str) -> bool:
329
+ """Recursively search for a part with a specific type."""
330
+ if isinstance(data, dict):
331
+ if data.get("type") == type_to_find:
332
+ return True
333
+ for key, value in data.items():
334
+ if self._find_part_type(value, type_to_find):
335
+ return True
336
+ elif isinstance(data, list):
337
+ for item in data:
338
+ if self._find_part_type(item, type_to_find):
339
+ return True
340
+ return False
341
+
317
342
  def _determine_message_type(self, topic: str) -> str:
318
343
  """Determine the type of message based on topic."""
319
344
  if "/agent/request/" in topic:
@@ -57,7 +57,7 @@ class RunSummary:
57
57
  query: str = ""
58
58
  target_agent: str = ""
59
59
  namespace: str = ""
60
- session_id: str = ""
60
+ context_id: str = ""
61
61
  final_status: str = ""
62
62
  final_message: str = ""
63
63
  time_metrics: TimeMetrics = field(default_factory=TimeMetrics)
@@ -74,7 +74,7 @@ class RunSummary:
74
74
  "query": self.query,
75
75
  "target_agent": self.target_agent,
76
76
  "namespace": self.namespace,
77
- "session_id": self.session_id,
77
+ "context_id": self.context_id,
78
78
  "final_status": self.final_status,
79
79
  "final_message": self.final_message,
80
80
  "start_time": self.time_metrics.start_time,
@@ -105,9 +105,6 @@ class RunSummary:
105
105
  "artifact_name": art.artifact_name,
106
106
  "directory": art.directory,
107
107
  "versions": art.versions,
108
- "created_by_tool": art.created_by_tool,
109
- "created_by_call_id": art.created_by_call_id,
110
- "creation_timestamp": art.creation_timestamp,
111
108
  }
112
109
  for art in self.output_artifacts
113
110
  ],
@@ -311,12 +308,13 @@ class MessageProcessor:
311
308
  return None, None
312
309
 
313
310
  @staticmethod
314
- def extract_session_id(first_message: Dict[str, Any]) -> Optional[str]:
315
- """Extract session ID from the first message."""
311
+ def extract_context_id(first_message: Dict[str, Any]) -> Optional[str]:
312
+ """Extract context ID from the first message."""
316
313
  try:
317
314
  payload = first_message.get("payload", {})
318
315
  params = payload.get("params", {})
319
- return params.get("sessionId")
316
+ message = params.get("message", {})
317
+ return message.get("contextId")
320
318
  except KeyError:
321
319
  return None
322
320
 
@@ -357,27 +355,22 @@ class MessageProcessor:
357
355
  result = payload.get("result", {})
358
356
  status = result.get("status", {})
359
357
  message_data = status.get("message", {})
360
- metadata = message_data.get("metadata", {})
361
- data = metadata.get("data", {})
362
- content = data.get("content", {})
363
- parts = content.get("parts", [])
358
+ parts = message_data.get("parts", [])
364
359
 
365
360
  for part in parts:
366
- function_call = part.get("function_call", {})
367
- if not function_call:
368
- continue
369
-
370
- call_id = function_call.get("id")
371
- if call_id and call_id not in processed_tool_calls:
372
- tool_call = ToolCall(
373
- call_id=call_id,
374
- agent=result.get("metadata", {}).get("agent_name", ""),
375
- tool_name=function_call.get("name", ""),
376
- arguments=function_call.get("args", {}),
377
- timestamp=status.get("timestamp", ""),
378
- )
379
- tool_calls.append(tool_call)
380
- processed_tool_calls.add(call_id)
361
+ data = part.get("data", {})
362
+ if data.get("type") == "tool_invocation_start":
363
+ call_id = data.get("function_call_id")
364
+ if call_id and call_id not in processed_tool_calls:
365
+ tool_call = ToolCall(
366
+ call_id=call_id,
367
+ agent=result.get("metadata", {}).get("agent_name", ""),
368
+ tool_name=data.get("tool_name", ""),
369
+ arguments=data.get("tool_args", {}),
370
+ timestamp=status.get("timestamp", ""),
371
+ )
372
+ tool_calls.append(tool_call)
373
+ processed_tool_calls.add(call_id)
381
374
 
382
375
  except (KeyError, IndexError):
383
376
  continue
@@ -392,11 +385,11 @@ class ArtifactService:
392
385
  self.base_path = base_path
393
386
  self.user_identity = user_identity
394
387
 
395
- def get_artifact_info(self, namespace: str, session_id: str) -> List[ArtifactInfo]:
388
+ def get_artifact_info(self, namespace: str, context_id: str) -> List[ArtifactInfo]:
396
389
  """Retrieve information about artifacts from the session directory."""
397
390
  artifact_info = []
398
391
  session_dir = os.path.join(
399
- self.base_path, namespace, self.user_identity, session_id
392
+ self.base_path, namespace, self.user_identity, context_id
400
393
  )
401
394
 
402
395
  if not os.path.isdir(session_dir):
@@ -652,9 +645,9 @@ class SummaryBuilder:
652
645
  "Could not find target agent and namespace in the first message."
653
646
  )
654
647
 
655
- session_id = self.message_processor.extract_session_id(first_message)
656
- if session_id:
657
- summary.session_id = session_id
648
+ context_id = self.message_processor.extract_context_id(first_message)
649
+ if context_id:
650
+ summary.context_id = context_id
658
651
 
659
652
  # Extract final status information
660
653
  final_status, final_message = self.message_processor.extract_final_status_info(
@@ -699,7 +692,7 @@ class SummaryBuilder:
699
692
 
700
693
  def _add_artifact_information(self, summary: RunSummary, test_case: Dict[str, Any]):
701
694
  """Add artifact information if configuration is available."""
702
- if not summary.namespace or not summary.session_id:
695
+ if not summary.namespace or not summary.context_id:
703
696
  return
704
697
 
705
698
  try:
@@ -710,7 +703,7 @@ class SummaryBuilder:
710
703
 
711
704
  # Get and categorize artifacts
712
705
  all_artifacts = self.artifact_service.get_artifact_info(
713
- summary.namespace, summary.session_id
706
+ summary.namespace, summary.context_id
714
707
  )
715
708
 
716
709
  input_artifacts, output_artifacts = (
@@ -11,7 +11,7 @@ from solace_ai_connector.common.utils import deep_merge
11
11
  from solace_ai_connector.flow.app import App
12
12
  from solace_ai_connector.components.component_base import ComponentBase
13
13
 
14
- from ...common.a2a_protocol import (
14
+ from ...common.a2a import (
15
15
  get_discovery_topic,
16
16
  get_gateway_response_subscription_topic,
17
17
  get_gateway_status_subscription_topic,
@@ -64,6 +64,26 @@ BASE_GATEWAY_APP_SCHEMA: Dict[str, List[Dict[str, Any]]] = {
64
64
  "default": 12,
65
65
  "description": "Maximum depth for recursively resolving 'artifact_content' embeds within files.",
66
66
  },
67
+ {
68
+ "name": "artifact_handling_mode",
69
+ "required": False,
70
+ "type": "string",
71
+ "default": "reference",
72
+ "description": (
73
+ "How the gateway handles file parts from clients. "
74
+ "'reference': Save inline file bytes to the artifact store and replace with a URI. "
75
+ "'embed': Resolve file URIs and embed content as bytes. "
76
+ "'passthrough': Send file parts to the agent as-is."
77
+ ),
78
+ "enum": ["reference", "embed", "passthrough"],
79
+ },
80
+ {
81
+ "name": "gateway_max_message_size_bytes",
82
+ "required": False,
83
+ "type": "integer",
84
+ "default": 10_000_000, # 10MB
85
+ "description": "Maximum allowed message size in bytes for messages published by the gateway.",
86
+ },
67
87
  # --- Default User Identity Configuration ---
68
88
  {
69
89
  "name": "default_user_identity",
@@ -200,6 +220,12 @@ class BaseGatewayApp(App):
200
220
  self.gateway_recursive_embed_depth: int = resolved_app_config_block.get(
201
221
  "gateway_recursive_embed_depth", 12
202
222
  )
223
+ self.artifact_handling_mode: str = resolved_app_config_block.get(
224
+ "artifact_handling_mode", "reference"
225
+ )
226
+ self.gateway_max_message_size_bytes: int = resolved_app_config_block.get(
227
+ "gateway_max_message_size_bytes", 10_000_000
228
+ )
203
229
 
204
230
  modified_app_info = app_info.copy()
205
231
  modified_app_info["app_config"] = resolved_app_config_block