solace-agent-mesh 1.1.0__py3-none-any.whl → 1.3.1__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.
- solace_agent_mesh/agent/adk/runner.py +18 -12
- solace_agent_mesh/agent/adk/services.py +3 -3
- solace_agent_mesh/agent/adk/setup.py +141 -34
- solace_agent_mesh/agent/protocol/event_handlers.py +27 -21
- solace_agent_mesh/agent/sac/app.py +0 -1
- solace_agent_mesh/agent/sac/component.py +0 -1
- solace_agent_mesh/agent/tools/__init__.py +1 -0
- solace_agent_mesh/agent/tools/dynamic_tool.py +362 -0
- solace_agent_mesh/assets/docs/404.html +3 -3
- solace_agent_mesh/assets/docs/assets/js/42b3f8d8.d97b8e94.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/483cef9a.4e972867.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/55f47984.cf3781c4.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/664b740a.1b744a32.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/75384d09.c193a8f0.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9a09e75d.d6607c56.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/aba87c2f.071e2d94.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ae0e903d.4d8dda10.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/c835a94d.146e3186.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f284c35a.7334119c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.1c79039d.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.858117b7.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/Enterprise/installation/index.html +29 -0
- solace_agent_mesh/assets/docs/docs/documentation/Enterprise/single-sign-on/index.html +25 -0
- solace_agent_mesh/assets/docs/docs/documentation/{migration-guides/a2a-upgrade-to-0.3.0/a2a-gateway-upgrade-to-0.3.0/index.html → Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0/index.html } +6 -6
- solace_agent_mesh/assets/docs/docs/documentation/{migration-guides/a2a-upgrade-to-0.3.0/a2a-technical-migration-map/index.html → Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map/index.html } +6 -6
- solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +19 -27
- solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/rag-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +5 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-python-tools/index.html +63 -0
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +4 -4
- solace_agent_mesh/assets/docs/lunr-index-1757531604543.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1757531604543.json +1 -0
- solace_agent_mesh/assets/docs/search-doc.json +1 -1
- solace_agent_mesh/assets/docs/sitemap.xml +1 -1
- solace_agent_mesh/cli/__init__.py +1 -1
- solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +125 -48
- solace_agent_mesh/cli/commands/eval_cmd.py +14 -0
- solace_agent_mesh/cli/commands/init_cmd/__init__.py +53 -31
- solace_agent_mesh/cli/commands/init_cmd/database_step.py +91 -0
- solace_agent_mesh/cli/commands/init_cmd/env_step.py +19 -8
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +80 -25
- solace_agent_mesh/cli/commands/init_cmd/web_init_step.py +32 -10
- solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +74 -15
- solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +0 -2
- solace_agent_mesh/cli/commands/run_cmd.py +5 -3
- solace_agent_mesh/cli/utils.py +68 -12
- solace_agent_mesh/client/webui/frontend/static/assets/authCallback-CAX9u8a7.js +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/client-DXU9SPI5.js +25 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-C03yrETa.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-C1k9E0aC.js +339 -0
- solace_agent_mesh/client/webui/frontend/static/assets/vendor-B0BEKoAR.js +390 -0
- solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -2
- solace_agent_mesh/client/webui/frontend/static/index.html +4 -3
- solace_agent_mesh/common/utils/embeds/resolver.py +1 -0
- solace_agent_mesh/config_portal/backend/common.py +2 -2
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-bFMKlzKf.js +98 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/{manifest-d845808d.js → manifest-89db7c30.js} +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/index.html +1 -1
- solace_agent_mesh/evaluation/message_organizer.py +35 -56
- solace_agent_mesh/evaluation/run.py +26 -5
- solace_agent_mesh/evaluation/subscriber.py +35 -10
- solace_agent_mesh/evaluation/summary_builder.py +27 -34
- solace_agent_mesh/gateway/http_sse/ARCHITECTURE_GUIDE.md +676 -0
- solace_agent_mesh/gateway/http_sse/alembic/env.py +85 -0
- solace_agent_mesh/gateway/http_sse/alembic/script.py.mako +28 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/b1c2d3e4f5g6_add_database_indexes.py +83 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/d5b3f8f2e9a0_create_initial_database.py +58 -0
- solace_agent_mesh/gateway/http_sse/alembic.ini +147 -0
- solace_agent_mesh/gateway/http_sse/api/__init__.py +11 -0
- solace_agent_mesh/gateway/http_sse/api/controllers/__init__.py +9 -0
- solace_agent_mesh/gateway/http_sse/api/controllers/session_controller.py +355 -0
- solace_agent_mesh/gateway/http_sse/api/controllers/task_controller.py +279 -0
- solace_agent_mesh/gateway/http_sse/api/controllers/user_controller.py +35 -0
- solace_agent_mesh/gateway/http_sse/api/dto/__init__.py +10 -0
- solace_agent_mesh/gateway/http_sse/api/dto/requests/__init__.py +37 -0
- solace_agent_mesh/gateway/http_sse/api/dto/requests/session_requests.py +49 -0
- solace_agent_mesh/gateway/http_sse/api/dto/requests/task_requests.py +66 -0
- solace_agent_mesh/gateway/http_sse/api/dto/responses/__init__.py +43 -0
- solace_agent_mesh/gateway/http_sse/api/dto/responses/session_responses.py +68 -0
- solace_agent_mesh/gateway/http_sse/api/dto/responses/task_responses.py +74 -0
- solace_agent_mesh/gateway/http_sse/app.py +31 -1
- solace_agent_mesh/gateway/http_sse/application/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/application/services/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/application/services/session_service.py +135 -0
- solace_agent_mesh/gateway/http_sse/component.py +224 -62
- solace_agent_mesh/gateway/http_sse/dependencies.py +148 -45
- solace_agent_mesh/gateway/http_sse/domain/entities/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/domain/entities/session.py +90 -0
- solace_agent_mesh/gateway/http_sse/domain/repositories/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/domain/repositories/session_repository.py +54 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/__init__.py +4 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/dependency_injection/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/dependency_injection/container.py +123 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence/__init__.py +4 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence/database_persistence_service.py +16 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence/database_service.py +119 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence/models.py +31 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence_service.py +12 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/repositories/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/repositories/session_repository.py +174 -0
- solace_agent_mesh/gateway/http_sse/main.py +291 -87
- solace_agent_mesh/gateway/http_sse/routers/{agents.py → agent_cards.py} +7 -7
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +121 -54
- solace_agent_mesh/gateway/http_sse/routers/config.py +3 -1
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +83 -2
- solace_agent_mesh/gateway/http_sse/routers/visualization.py +7 -7
- solace_agent_mesh/gateway/http_sse/services/{agent_service.py → agent_card_service.py} +19 -19
- solace_agent_mesh/gateway/http_sse/session_manager.py +64 -30
- solace_agent_mesh/gateway/http_sse/shared/__init__.py +9 -0
- solace_agent_mesh/gateway/http_sse/shared/auth_utils.py +29 -0
- solace_agent_mesh/gateway/http_sse/shared/enums.py +45 -0
- solace_agent_mesh/gateway/http_sse/shared/types.py +45 -0
- solace_agent_mesh/templates/shared_config.yaml +4 -5
- solace_agent_mesh/templates/webui.yaml +8 -10
- {solace_agent_mesh-1.1.0.dist-info → solace_agent_mesh-1.3.1.dist-info}/METADATA +5 -3
- {solace_agent_mesh-1.1.0.dist-info → solace_agent_mesh-1.3.1.dist-info}/RECORD +150 -104
- solace_agent_mesh/assets/docs/assets/js/42b3f8d8.8ccb9901.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/55f47984.c484bf96.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/6e0db977.39a79ca9.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/75384d09.bf78fbdb.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/90dd9cf6.88f385ea.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/aba87c2f.76376d7c.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f284c35a.fb68323a.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/main.a75ecc0d.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.458efb1d.js +0 -1
- solace_agent_mesh/assets/docs/lunr-index-1756992446316.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1756992446316.json +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/authCallback-BmF2l6vg.js +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/client-D881Dttc.js +0 -49
- solace_agent_mesh/client/webui/frontend/static/assets/main-C0jZjYa8.js +0 -699
- solace_agent_mesh/client/webui/frontend/static/assets/main-CCeG324-.css +0 -1
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-Bym6YkMd.js +0 -98
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +0 -85
- solace_agent_mesh/gateway/http_sse/routers/users.py +0 -59
- /solace_agent_mesh/assets/docs/assets/js/{main.a75ecc0d.js.LICENSE.txt → main.1c79039d.js.LICENSE.txt} +0 -0
- {solace_agent_mesh-1.1.0.dist-info → solace_agent_mesh-1.3.1.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.1.0.dist-info → solace_agent_mesh-1.3.1.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.1.0.dist-info → solace_agent_mesh-1.3.1.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-
|
|
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&display=swap"/></head><body><p>Loading...</p><link rel="modulepreload" href="/assets/manifest-
|
|
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&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};
|
|
@@ -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.
|
|
111
|
-
self.
|
|
112
|
-
self.
|
|
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
|
-
|
|
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
|
|
128
|
-
self,
|
|
133
|
+
def _extract_from_subtask_delegation(
|
|
134
|
+
self, payload: dict
|
|
129
135
|
) -> Tuple[Optional[str], Optional[str]]:
|
|
130
|
-
"""Strategy 1:
|
|
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
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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
|
|
153
|
-
self,
|
|
149
|
+
def _extract_from_toplevel_id(
|
|
150
|
+
self, payload: dict
|
|
154
151
|
) -> Tuple[Optional[str], Optional[str]]:
|
|
155
|
-
"""Strategy 2:
|
|
156
|
-
|
|
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
|
|
172
|
-
self,
|
|
158
|
+
def _extract_from_result_object(
|
|
159
|
+
self, payload: dict
|
|
173
160
|
) -> Tuple[Optional[str], Optional[str]]:
|
|
174
|
-
"""Strategy 3:
|
|
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
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
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
|
-
|
|
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
|
-
"
|
|
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
|
|
315
|
-
"""Extract
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
367
|
-
if
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
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,
|
|
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,
|
|
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
|
-
|
|
656
|
-
if
|
|
657
|
-
summary.
|
|
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.
|
|
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.
|
|
706
|
+
summary.namespace, summary.context_id
|
|
714
707
|
)
|
|
715
708
|
|
|
716
709
|
input_artifacts, output_artifacts = (
|