solace-agent-mesh 1.6.3__py3-none-any.whl → 1.7.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/adk_llm.txt +12 -18
- solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +1 -1
- solace_agent_mesh/agent/adk/callbacks.py +138 -20
- solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +2 -0
- solace_agent_mesh/agent/adk/models/lite_llm.py +38 -5
- solace_agent_mesh/agent/adk/models/models_llm.txt +82 -35
- solace_agent_mesh/agent/adk/runner.py +9 -0
- solace_agent_mesh/agent/adk/stream_parser.py +6 -1
- solace_agent_mesh/agent/adk/tool_wrapper.py +3 -0
- solace_agent_mesh/agent/agent_llm.txt +61 -70
- solace_agent_mesh/agent/protocol/event_handlers.py +29 -1
- solace_agent_mesh/agent/protocol/protocol_llm.txt +1 -1
- solace_agent_mesh/agent/proxies/a2a/a2a_llm.txt +190 -0
- solace_agent_mesh/agent/proxies/base/base_llm.txt +148 -0
- solace_agent_mesh/agent/proxies/proxies_llm.txt +283 -0
- solace_agent_mesh/agent/sac/app.py +22 -0
- solace_agent_mesh/agent/sac/component.py +76 -40
- solace_agent_mesh/agent/sac/sac_llm.txt +1 -1
- solace_agent_mesh/agent/sac/task_execution_context.py +21 -0
- solace_agent_mesh/agent/testing/testing_llm.txt +2 -1
- solace_agent_mesh/agent/tools/builtin_artifact_tools.py +13 -148
- solace_agent_mesh/agent/tools/dynamic_tool.py +2 -0
- solace_agent_mesh/agent/tools/tools_llm.txt +93 -80
- solace_agent_mesh/agent/tools/tools_llm_detail.txt +3 -2
- solace_agent_mesh/agent/utils/artifact_helpers.py +4 -0
- solace_agent_mesh/agent/utils/utils_llm.txt +16 -2
- solace_agent_mesh/assets/docs/404.html +3 -3
- solace_agent_mesh/assets/docs/assets/js/05749d90.c70b2be9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/15ba94aa.92fea363.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/15e40e79.36003774.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2987107d.a80604f9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ac1795d.e4870a49.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ff0015d.b63ee53a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/547e15cc.2f7790c1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.45b32c2b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/631738c7.fa471607.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/64195356.c498c4d0.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6a520c9d.b6e3f2ce.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.a5b36a60.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/71da7b71.374b9d54.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8024126c.fa0e7186.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8b032486.91a91afc.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/94e8668d.09ed9234.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{ab9708a8.3e6dd091.js → ab9708a8.245ae0ef.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/ad87452a.9d73dad6.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/cbe2e9ea.f902fad8.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/da0b5bad.b62f7b08.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/db5d6442.3daf1696.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/dd817ffc.c37a755e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/dd81e2b8.b682e9c2.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/de915948.44a432bc.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e04b235d.c9c50c7b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e3d9abda.d11c67a7.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{e6f9706b.e74a984d.js → e6f9706b.045d0fa1.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/e92d0134.3bda61dd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f284c35a.5099c51e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ff4d71f2.74710fc1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.f213fe0c.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.d9606d6a.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/artifact-management/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/audio-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/data-analysis-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/embeds/index.html +18 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/cli/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/components/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/projects/index.html +196 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/proxies/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +6 -7
- solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes-deployment/index.html +47 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/logging/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-gateways/index.html +160 -169
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-python-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/bedrock-agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/custom-agent/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/event-mesh-gateway/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mcp-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mongodb-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rag-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rest-gateway/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/sql-database/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/agent-builder/index.html +59 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/connectors/index.html +62 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +10 -6
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/secure-user-delegated-access/index.html +440 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +27 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/wheel-installation/index.html +62 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/architecture/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +5 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/artifact-storage/index.html +290 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +9 -9
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/session-storage/index.html +251 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/user-feedback/index.html +88 -0
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-gateway-upgrade-to-0.3.0/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-technical-migration-map/index.html +3 -3
- solace_agent_mesh/assets/docs/lunr-index-1762283454666.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1762283454666.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/docs_cmd.py +4 -1
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-D4_RMYRh.js → authCallback-tcIFZLis.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/{client-UZ3qU6Bq.js → client-CRYdKo2Q.js} +3 -3
- solace_agent_mesh/client/webui/frontend/static/assets/main-CojeY_1w.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-ILja9MCG.js +353 -0
- solace_agent_mesh/client/webui/frontend/static/assets/vendor-CINwxvwV.js +470 -0
- solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -3
- solace_agent_mesh/client/webui/frontend/static/index.html +4 -4
- solace_agent_mesh/common/a2a/a2a_llm.txt +13 -20
- solace_agent_mesh/common/a2a/protocol.py +5 -0
- solace_agent_mesh/common/a2a/types.py +1 -0
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +49 -11
- solace_agent_mesh/common/a2a_spec/schemas/artifact_creation_progress.json +23 -6
- solace_agent_mesh/common/a2a_spec/schemas/feedback_event.json +51 -0
- solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +26 -9
- solace_agent_mesh/common/common_llm.txt +13 -34
- solace_agent_mesh/common/data_parts.py +20 -4
- solace_agent_mesh/common/middleware/middleware_llm.txt +1 -1
- solace_agent_mesh/common/sac/sac_llm.txt +1 -1
- solace_agent_mesh/common/sam_events/sam_events_llm.txt +1 -1
- solace_agent_mesh/common/services/employee_service.py +1 -1
- solace_agent_mesh/common/services/providers/providers_llm.txt +3 -2
- solace_agent_mesh/common/services/services_llm.txt +9 -4
- solace_agent_mesh/common/utils/embeds/constants.py +1 -0
- solace_agent_mesh/common/utils/embeds/embeds_llm.txt +1 -1
- solace_agent_mesh/common/utils/embeds/modifiers.py +2 -1
- solace_agent_mesh/common/utils/embeds/resolver.py +58 -6
- solace_agent_mesh/common/utils/embeds/types.py +8 -0
- solace_agent_mesh/common/utils/utils_llm.txt +5 -6
- solace_agent_mesh/core_a2a/core_a2a_llm.txt +1 -1
- solace_agent_mesh/gateway/adapter/__init__.py +1 -0
- solace_agent_mesh/gateway/adapter/base.py +143 -0
- solace_agent_mesh/gateway/adapter/types.py +221 -0
- solace_agent_mesh/gateway/base/app.py +29 -2
- solace_agent_mesh/gateway/base/base_llm.txt +10 -8
- solace_agent_mesh/gateway/base/component.py +573 -142
- solace_agent_mesh/gateway/gateway_llm.txt +55 -59
- solace_agent_mesh/gateway/generic/__init__.py +1 -0
- solace_agent_mesh/gateway/generic/app.py +50 -0
- solace_agent_mesh/gateway/generic/component.py +650 -0
- solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +99 -49
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_fulltext_search_indexes.py +92 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_project_users_table.py +72 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_soft_delete_and_search.py +150 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_default_agent_to_projects.py +26 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_projects_table.py +135 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +26 -20
- solace_agent_mesh/gateway/http_sse/app.py +0 -14
- solace_agent_mesh/gateway/http_sse/component.py +17 -56
- solace_agent_mesh/gateway/http_sse/components/components_llm.txt +1 -1
- solace_agent_mesh/gateway/http_sse/dependencies.py +21 -3
- solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +8 -8
- solace_agent_mesh/gateway/http_sse/main.py +23 -5
- solace_agent_mesh/gateway/http_sse/repository/__init__.py +19 -1
- solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +56 -98
- solace_agent_mesh/gateway/http_sse/repository/entities/project.py +81 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/project_user.py +47 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/session.py +23 -1
- solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +47 -0
- solace_agent_mesh/gateway/http_sse/repository/interfaces.py +112 -4
- solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +9 -1
- solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +51 -60
- solace_agent_mesh/gateway/http_sse/repository/models/project_model.py +51 -0
- solace_agent_mesh/gateway/http_sse/repository/models/project_user_model.py +75 -0
- solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +7 -1
- solace_agent_mesh/gateway/http_sse/repository/project_repository.py +172 -0
- solace_agent_mesh/gateway/http_sse/repository/project_user_repository.py +186 -0
- solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +125 -157
- solace_agent_mesh/gateway/http_sse/repository/session_repository.py +269 -8
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +143 -51
- solace_agent_mesh/gateway/http_sse/routers/config.py +69 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +198 -94
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/project_requests.py +48 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +68 -18
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +13 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/project_responses.py +30 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +51 -35
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +2 -0
- solace_agent_mesh/gateway/http_sse/routers/feedback.py +133 -2
- solace_agent_mesh/gateway/http_sse/routers/projects.py +542 -0
- solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +9 -11
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +154 -3
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +296 -4
- solace_agent_mesh/gateway/http_sse/services/project_service.py +403 -0
- solace_agent_mesh/gateway/http_sse/services/services_llm.txt +16 -10
- solace_agent_mesh/gateway/http_sse/services/session_service.py +178 -6
- solace_agent_mesh/gateway/http_sse/shared/exception_handlers.py +2 -3
- solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +48 -14
- solace_agent_mesh/solace_agent_mesh_llm.txt +1 -1
- {solace_agent_mesh-1.6.3.dist-info → solace_agent_mesh-1.7.1.dist-info}/METADATA +3 -5
- {solace_agent_mesh-1.6.3.dist-info → solace_agent_mesh-1.7.1.dist-info}/RECORD +218 -175
- solace_agent_mesh/assets/docs/assets/js/15ba94aa.932dd2db.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/3ac1795d.76654dd9.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/3ff0015d.2be20244.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/547e15cc.2cbb060a.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.eda4bcb2.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/631738c7.7c4594c9.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/6a520c9d.ba015d81.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.f4b15f3b.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/71da7b71.ddbdfbe2.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/8024126c.56e59919.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/94e8668d.3b883666.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/da0b5bad.d08a9466.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/dd817ffc.0aa9630a.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/dd81e2b8.d590bc9e.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/de915948.27d6b065.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e3d9abda.6b9493d0.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e92d0134.4f395c6b.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f284c35a.720d2ef2.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/ff4d71f2.15b02f97.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/main.ed05b14d.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.a8a75e0b.js +0 -1
- solace_agent_mesh/assets/docs/lunr-index-1761744323675.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1761744323675.json +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main--3yJYl7S.css +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-DojKHS49.js +0 -342
- solace_agent_mesh/client/webui/frontend/static/assets/vendor-DSqhjwq_.js +0 -405
- /solace_agent_mesh/assets/docs/assets/js/{main.ed05b14d.js.LICENSE.txt → main.f213fe0c.js.LICENSE.txt} +0 -0
- {solace_agent_mesh-1.6.3.dist-info → solace_agent_mesh-1.7.1.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.6.3.dist-info → solace_agent_mesh-1.7.1.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.6.3.dist-info → solace_agent_mesh-1.7.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -5,6 +5,7 @@ Contains the main embed resolution functions, including the chain executor.
|
|
|
5
5
|
import logging
|
|
6
6
|
import asyncio
|
|
7
7
|
import json
|
|
8
|
+
import uuid
|
|
8
9
|
from typing import Any, Callable, Dict, Optional, Set, Tuple, List, Union
|
|
9
10
|
from .constants import (
|
|
10
11
|
EMBED_REGEX,
|
|
@@ -20,7 +21,7 @@ from .converter import (
|
|
|
20
21
|
serialize_data,
|
|
21
22
|
_parse_string_to_list_of_dicts,
|
|
22
23
|
)
|
|
23
|
-
from .types import DataFormat
|
|
24
|
+
from .types import DataFormat, ResolutionMode
|
|
24
25
|
from ..mime_helpers import is_text_based_mime_type
|
|
25
26
|
|
|
26
27
|
log = logging.getLogger(__name__)
|
|
@@ -85,10 +86,11 @@ async def _evaluate_artifact_content_embed_with_chain(
|
|
|
85
86
|
output_format_from_directive: Optional[str],
|
|
86
87
|
context: Any,
|
|
87
88
|
log_identifier: str,
|
|
89
|
+
resolution_mode: "ResolutionMode",
|
|
88
90
|
config: Optional[Dict] = None,
|
|
89
91
|
current_depth: int = 0,
|
|
90
92
|
visited_artifacts: Optional[Set[Tuple[str, int]]] = None,
|
|
91
|
-
) -> Tuple[str, Optional[str], int]:
|
|
93
|
+
) -> Union[Tuple[str, Optional[str], int], Tuple[None, str, Any]]:
|
|
92
94
|
"""
|
|
93
95
|
Loads artifact content, recursively resolves its internal embeds if text-based,
|
|
94
96
|
applies a chain of modifiers, and serializes the final result.
|
|
@@ -167,6 +169,7 @@ async def _evaluate_artifact_content_embed_with_chain(
|
|
|
167
169
|
context=context,
|
|
168
170
|
resolver_func=evaluate_embed,
|
|
169
171
|
types_to_resolve=EARLY_EMBED_TYPES.union(LATE_EMBED_TYPES),
|
|
172
|
+
resolution_mode=ResolutionMode.RECURSIVE_ARTIFACT_CONTENT,
|
|
170
173
|
log_identifier=log_identifier,
|
|
171
174
|
config=config,
|
|
172
175
|
max_depth=config.get("gateway_recursive_embed_depth", 12),
|
|
@@ -422,6 +425,26 @@ async def _evaluate_artifact_content_embed_with_chain(
|
|
|
422
425
|
err_msg = f"Unexpected error in modifier '{prefix}': {mod_err}"
|
|
423
426
|
return f"[Error: {err_msg}]", err_msg, 0
|
|
424
427
|
|
|
428
|
+
if (
|
|
429
|
+
current_format == DataFormat.BYTES
|
|
430
|
+
and resolution_mode == ResolutionMode.A2A_MESSAGE_TO_USER
|
|
431
|
+
):
|
|
432
|
+
log.info(
|
|
433
|
+
"%s [Depth:%d] Result is binary data in A2A_MESSAGE_TO_USER mode. Signaling for inline binary content.",
|
|
434
|
+
log_identifier,
|
|
435
|
+
current_depth,
|
|
436
|
+
)
|
|
437
|
+
filename_for_signal = artifact_spec_from_directive.split(":", 1)[0]
|
|
438
|
+
return (
|
|
439
|
+
None,
|
|
440
|
+
"SIGNAL_INLINE_BINARY_CONTENT",
|
|
441
|
+
{
|
|
442
|
+
"bytes": current_data,
|
|
443
|
+
"mime_type": original_mime_type,
|
|
444
|
+
"name": filename_for_signal,
|
|
445
|
+
},
|
|
446
|
+
)
|
|
447
|
+
|
|
425
448
|
target_string_format = output_format_from_directive
|
|
426
449
|
if target_string_format is None:
|
|
427
450
|
log.warning(
|
|
@@ -486,9 +509,10 @@ async def resolve_embeds_in_string(
|
|
|
486
509
|
..., Union[Tuple[str, Optional[str], int], Tuple[None, str, Any]]
|
|
487
510
|
],
|
|
488
511
|
types_to_resolve: Set[str],
|
|
512
|
+
resolution_mode: "ResolutionMode",
|
|
489
513
|
log_identifier: str = "[EmbedUtil]",
|
|
490
514
|
config: Optional[Dict[str, Any]] = None,
|
|
491
|
-
) -> Tuple[str, int, List[Tuple[int, Any]]]:
|
|
515
|
+
) -> Tuple[str, int, List[Tuple[int, Any, str]]]:
|
|
492
516
|
"""
|
|
493
517
|
Resolves specified embed types within a string using a provided resolver function.
|
|
494
518
|
This is the TOP-LEVEL resolver called by gateways. It handles signals and buffering.
|
|
@@ -520,7 +544,7 @@ async def resolve_embeds_in_string(
|
|
|
520
544
|
The index corresponds to the start index of the embed directive in the original string.
|
|
521
545
|
"""
|
|
522
546
|
resolved_parts = []
|
|
523
|
-
signals_found: List[Tuple[int, Any]] = []
|
|
547
|
+
signals_found: List[Tuple[int, Any, str]] = []
|
|
524
548
|
last_end = 0
|
|
525
549
|
original_length = len(text)
|
|
526
550
|
|
|
@@ -550,6 +574,7 @@ async def resolve_embeds_in_string(
|
|
|
550
574
|
format_spec,
|
|
551
575
|
context,
|
|
552
576
|
log_identifier,
|
|
577
|
+
resolution_mode,
|
|
553
578
|
config,
|
|
554
579
|
)
|
|
555
580
|
|
|
@@ -566,10 +591,13 @@ async def resolve_embeds_in_string(
|
|
|
566
591
|
signal_type,
|
|
567
592
|
start,
|
|
568
593
|
)
|
|
594
|
+
placeholder = f"__EMBED_SIGNAL_{uuid.uuid4().hex}__"
|
|
595
|
+
resolved_parts.append(placeholder)
|
|
569
596
|
signals_found.append(
|
|
570
597
|
(
|
|
571
598
|
start,
|
|
572
599
|
resolved_value,
|
|
600
|
+
placeholder,
|
|
573
601
|
)
|
|
574
602
|
)
|
|
575
603
|
elif (
|
|
@@ -657,6 +685,7 @@ async def resolve_embeds_recursively_in_string(
|
|
|
657
685
|
context: Any,
|
|
658
686
|
resolver_func: Callable[..., Tuple[str, Optional[str], int]],
|
|
659
687
|
types_to_resolve: Set[str],
|
|
688
|
+
resolution_mode: "ResolutionMode",
|
|
660
689
|
log_identifier: str,
|
|
661
690
|
config: Optional[Dict],
|
|
662
691
|
max_depth: int,
|
|
@@ -709,6 +738,7 @@ async def resolve_embeds_recursively_in_string(
|
|
|
709
738
|
format_spec,
|
|
710
739
|
context,
|
|
711
740
|
log_identifier,
|
|
741
|
+
resolution_mode,
|
|
712
742
|
config,
|
|
713
743
|
current_depth,
|
|
714
744
|
visited_artifacts,
|
|
@@ -776,6 +806,7 @@ async def evaluate_embed(
|
|
|
776
806
|
format_spec: Optional[str],
|
|
777
807
|
context: Dict[str, Any],
|
|
778
808
|
log_identifier: str,
|
|
809
|
+
resolution_mode: "ResolutionMode",
|
|
779
810
|
config: Optional[Dict] = None,
|
|
780
811
|
current_depth: int = 0,
|
|
781
812
|
visited_artifacts: Optional[Set[Tuple[str, int]]] = None,
|
|
@@ -812,6 +843,26 @@ async def evaluate_embed(
|
|
|
812
843
|
log.info("%s Detected 'status_update' embed. Signaling.", log_identifier)
|
|
813
844
|
return (None, "SIGNAL_STATUS_UPDATE", status_text)
|
|
814
845
|
|
|
846
|
+
elif embed_type == "artifact_return":
|
|
847
|
+
if resolution_mode == ResolutionMode.A2A_MESSAGE_TO_USER:
|
|
848
|
+
parts = expression.strip().split(":", 1)
|
|
849
|
+
filename = parts[0]
|
|
850
|
+
version = parts[1] if len(parts) > 1 else "latest"
|
|
851
|
+
log.info("%s Detected 'artifact_return' embed. Signaling.", log_identifier)
|
|
852
|
+
return (
|
|
853
|
+
None,
|
|
854
|
+
"SIGNAL_ARTIFACT_RETURN",
|
|
855
|
+
{"filename": filename, "version": version},
|
|
856
|
+
)
|
|
857
|
+
else:
|
|
858
|
+
log.warning(
|
|
859
|
+
"%s Ignoring 'artifact_return' embed in unsupported context: %s",
|
|
860
|
+
log_identifier,
|
|
861
|
+
resolution_mode.name,
|
|
862
|
+
)
|
|
863
|
+
original_embed_text = f"«{embed_type}:{expression}»"
|
|
864
|
+
return original_embed_text, None, len(original_embed_text.encode("utf-8"))
|
|
865
|
+
|
|
815
866
|
elif embed_type == "artifact_content":
|
|
816
867
|
artifact_spec, modifiers, output_format = _parse_modifier_chain(expression)
|
|
817
868
|
if output_format is None and format_spec is not None:
|
|
@@ -822,17 +873,18 @@ async def evaluate_embed(
|
|
|
822
873
|
)
|
|
823
874
|
output_format = format_spec
|
|
824
875
|
|
|
825
|
-
|
|
876
|
+
result = await _evaluate_artifact_content_embed_with_chain(
|
|
826
877
|
artifact_spec_from_directive=artifact_spec,
|
|
827
878
|
modifiers_from_directive=modifiers,
|
|
828
879
|
output_format_from_directive=output_format,
|
|
829
880
|
context=context,
|
|
830
881
|
log_identifier=log_identifier,
|
|
882
|
+
resolution_mode=resolution_mode,
|
|
831
883
|
config=config,
|
|
832
884
|
current_depth=current_depth,
|
|
833
885
|
visited_artifacts=visited_artifacts or set(),
|
|
834
886
|
)
|
|
835
|
-
return
|
|
887
|
+
return result
|
|
836
888
|
|
|
837
889
|
else:
|
|
838
890
|
evaluator = EMBED_EVALUATORS.get(embed_type)
|
|
@@ -5,6 +5,14 @@ Defines types used within the embed processing system, like DataFormat.
|
|
|
5
5
|
from enum import Enum, auto
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
class ResolutionMode(Enum):
|
|
9
|
+
"""Defines the context in which embed resolution is occurring."""
|
|
10
|
+
|
|
11
|
+
A2A_MESSAGE_TO_USER = auto()
|
|
12
|
+
TOOL_PARAMETER = auto()
|
|
13
|
+
RECURSIVE_ARTIFACT_CONTENT = auto()
|
|
14
|
+
|
|
15
|
+
|
|
8
16
|
class DataFormat(Enum):
|
|
9
17
|
"""Represents internal data formats during modifier chain execution."""
|
|
10
18
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# DEVELOPER GUIDE: utils
|
|
2
|
+
|
|
1
3
|
## Quick Summary
|
|
2
4
|
The `utils` directory provides essential utility functions and tools for the Solace Agent Mesh system. It contains both direct utility files for common operations (MIME type handling, caching, message validation, authentication) and a sophisticated `embeds` subdirectory that implements a dynamic expression evaluation system. The utilities work together to provide platform compatibility, security features, data processing capabilities, and dynamic content generation for agent workflows.
|
|
3
5
|
|
|
@@ -119,6 +121,7 @@ The `utils` directory provides essential utility functions and tools for the Sol
|
|
|
119
121
|
- `__setitem__(key: str, value: Any)` - Dict-like ['key'] = value assignment
|
|
120
122
|
- `__contains__(key: str) -> bool` - Dict-like 'in' support
|
|
121
123
|
- `keys()`, `values()`, `items()`, `__iter__()` - Dict-like iteration methods
|
|
124
|
+
- `pop(key: str, default: Any = None) -> Any` - Dict-like .pop() method
|
|
122
125
|
|
|
123
126
|
#### type_utils.py
|
|
124
127
|
**Purpose:** Utilities for robust type checking, especially in development environments
|
|
@@ -327,10 +330,6 @@ async def webhook_handler(request: Request):
|
|
|
327
330
|
data = await request.json()
|
|
328
331
|
# Process authenticated notification
|
|
329
332
|
print(f"Received verified notification: {data}")
|
|
330
|
-
return Response
|
|
331
|
-
else:
|
|
332
|
-
return Response("Unauthorized", status_code=401)
|
|
333
|
-
except Exception as e:
|
|
334
|
-
print(f"
|
|
333
|
+
return Response
|
|
335
334
|
|
|
336
|
-
# content_hash:
|
|
335
|
+
# content_hash: c5bd94fc53429706fd6649d3dcf489665da150cfed54fd6961472c7b57dfc910
|
|
@@ -87,4 +87,4 @@ agent_card = AgentCard(name="new_agent", description="A new agent")
|
|
|
87
87
|
service.process_discovery_message(agent_card)
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
-
# content_hash:
|
|
90
|
+
# content_hash: 64e02756b1b097e39257e8e52df701d758df0f8d022ea6d6b088057f7025a6d9
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Abstract base classes and types for the Generic Gateway Adapter Framework."""
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Defines the abstract base class for Generic Gateway Adapters.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
from typing import Any, Dict, Generic, Optional, Type, TypeVar
|
|
7
|
+
|
|
8
|
+
from pydantic import BaseModel
|
|
9
|
+
|
|
10
|
+
from .types import (
|
|
11
|
+
AuthClaims,
|
|
12
|
+
GatewayContext,
|
|
13
|
+
ResponseContext,
|
|
14
|
+
SamDataPart,
|
|
15
|
+
SamError,
|
|
16
|
+
SamFilePart,
|
|
17
|
+
SamTask,
|
|
18
|
+
SamTextPart,
|
|
19
|
+
SamUpdate,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
T_ExternalInput = TypeVar("T_ExternalInput", bound=Any)
|
|
23
|
+
T_PlatformContext = TypeVar("T_PlatformContext", bound=Dict[str, Any])
|
|
24
|
+
T_AdapterConfig = TypeVar("T_AdapterConfig", bound=BaseModel)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class GatewayAdapter(
|
|
28
|
+
ABC, Generic[T_ExternalInput, T_PlatformContext, T_AdapterConfig]
|
|
29
|
+
):
|
|
30
|
+
"""
|
|
31
|
+
Abstract base class for gateway adapter plugins.
|
|
32
|
+
|
|
33
|
+
Gateway adapters handle platform-specific communication while the
|
|
34
|
+
GenericGatewayComponent manages A2A protocol complexity.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
ConfigModel: Optional[Type[BaseModel]] = None
|
|
38
|
+
|
|
39
|
+
# --- Lifecycle ---
|
|
40
|
+
async def init(self, context: GatewayContext) -> None:
|
|
41
|
+
"""
|
|
42
|
+
Initialize the gateway adapter.
|
|
43
|
+
|
|
44
|
+
This is where you should:
|
|
45
|
+
- Start platform listeners (WebSocket, HTTP server, stdin reader, etc.)
|
|
46
|
+
- Connect to external services and store the context for later use.
|
|
47
|
+
"""
|
|
48
|
+
pass
|
|
49
|
+
|
|
50
|
+
async def cleanup(self) -> None:
|
|
51
|
+
"""
|
|
52
|
+
Clean up resources on shutdown.
|
|
53
|
+
|
|
54
|
+
This is where you should:
|
|
55
|
+
- Stop platform listeners, close connections, and release resources.
|
|
56
|
+
"""
|
|
57
|
+
pass
|
|
58
|
+
|
|
59
|
+
# --- Authentication ---
|
|
60
|
+
async def extract_auth_claims(
|
|
61
|
+
self,
|
|
62
|
+
external_input: T_ExternalInput,
|
|
63
|
+
endpoint_context: Optional[Dict[str, Any]] = None,
|
|
64
|
+
) -> Optional[AuthClaims]:
|
|
65
|
+
"""
|
|
66
|
+
Extract authentication claims from platform input.
|
|
67
|
+
|
|
68
|
+
Return AuthClaims with user info/tokens, or None to use config-based auth.
|
|
69
|
+
"""
|
|
70
|
+
return None
|
|
71
|
+
|
|
72
|
+
# --- Inbound: Platform -> A2A ---
|
|
73
|
+
@abstractmethod
|
|
74
|
+
async def prepare_task(
|
|
75
|
+
self,
|
|
76
|
+
external_input: T_ExternalInput,
|
|
77
|
+
endpoint_context: Optional[Dict[str, Any]] = None,
|
|
78
|
+
) -> SamTask:
|
|
79
|
+
"""
|
|
80
|
+
Prepare a task from platform input.
|
|
81
|
+
|
|
82
|
+
This method is called after authentication succeeds. Convert your
|
|
83
|
+
platform's event format into a SamTask with parts.
|
|
84
|
+
"""
|
|
85
|
+
pass
|
|
86
|
+
|
|
87
|
+
# --- Outbound: A2A -> Platform ---
|
|
88
|
+
async def handle_update(self, update: SamUpdate, context: ResponseContext) -> None:
|
|
89
|
+
"""
|
|
90
|
+
Handle an update from the agent (batch handler).
|
|
91
|
+
|
|
92
|
+
By default, this method dispatches to individual part handlers.
|
|
93
|
+
Override for custom batch processing.
|
|
94
|
+
"""
|
|
95
|
+
for part in update.parts:
|
|
96
|
+
if isinstance(part, SamTextPart):
|
|
97
|
+
await self.handle_text_chunk(part.text, context)
|
|
98
|
+
elif isinstance(part, SamFilePart):
|
|
99
|
+
await self.handle_file(part, context)
|
|
100
|
+
elif isinstance(part, SamDataPart):
|
|
101
|
+
# Check for special data part types that have their own handlers
|
|
102
|
+
if part.data.get("type") == "agent_progress_update":
|
|
103
|
+
status_text = part.data.get("status_text")
|
|
104
|
+
if status_text:
|
|
105
|
+
await self.handle_status_update(status_text, context)
|
|
106
|
+
else:
|
|
107
|
+
# Fallback to the generic data part handler
|
|
108
|
+
await self.handle_data_part(part, context)
|
|
109
|
+
|
|
110
|
+
async def handle_text_chunk(self, text: str, context: ResponseContext) -> None:
|
|
111
|
+
"""
|
|
112
|
+
Handle streaming text chunk from the agent.
|
|
113
|
+
|
|
114
|
+
This is called by the default `handle_update` implementation.
|
|
115
|
+
An adapter can override this method to process text parts individually.
|
|
116
|
+
"""
|
|
117
|
+
pass
|
|
118
|
+
|
|
119
|
+
async def handle_file(
|
|
120
|
+
self, file_part: SamFilePart, context: ResponseContext
|
|
121
|
+
) -> None:
|
|
122
|
+
"""Handle file/artifact from the agent."""
|
|
123
|
+
pass
|
|
124
|
+
|
|
125
|
+
async def handle_data_part(
|
|
126
|
+
self, data_part: SamDataPart, context: ResponseContext
|
|
127
|
+
) -> None:
|
|
128
|
+
"""Handle structured data part from the agent."""
|
|
129
|
+
pass
|
|
130
|
+
|
|
131
|
+
async def handle_status_update(
|
|
132
|
+
self, status_text: str, context: ResponseContext
|
|
133
|
+
) -> None:
|
|
134
|
+
"""Handle agent status update (progress indicator)."""
|
|
135
|
+
pass
|
|
136
|
+
|
|
137
|
+
async def handle_task_complete(self, context: ResponseContext) -> None:
|
|
138
|
+
"""Handle task completion notification."""
|
|
139
|
+
pass
|
|
140
|
+
|
|
141
|
+
async def handle_error(self, error: SamError, context: ResponseContext) -> None:
|
|
142
|
+
"""Handle error from the agent or gateway."""
|
|
143
|
+
pass
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Defines the Pydantic models for the Generic Gateway Adapter framework.
|
|
3
|
+
|
|
4
|
+
These types create a stable abstraction layer, decoupling gateway adapters from the
|
|
5
|
+
underlying A2A protocol specifics.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Literal, Optional, Union
|
|
11
|
+
|
|
12
|
+
from pydantic import BaseModel, Field, model_validator
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from google.adk.artifacts import BaseArtifactService
|
|
16
|
+
from ...common.a2a.types import ArtifactInfo
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# --- Content Part Models ---
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class SamTextPart(BaseModel):
|
|
23
|
+
"""Text content in a SAM task."""
|
|
24
|
+
|
|
25
|
+
type: Literal["text"] = "text"
|
|
26
|
+
text: str
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class SamFilePart(BaseModel):
|
|
30
|
+
"""File content in a SAM task, with either inline bytes or a URI."""
|
|
31
|
+
|
|
32
|
+
type: Literal["file"] = "file"
|
|
33
|
+
name: str
|
|
34
|
+
content_bytes: Optional[bytes] = None
|
|
35
|
+
uri: Optional[str] = None
|
|
36
|
+
mime_type: Optional[str] = None
|
|
37
|
+
|
|
38
|
+
@model_validator(mode="after")
|
|
39
|
+
def validate_content_or_uri(self) -> "SamFilePart":
|
|
40
|
+
"""Ensures that either content_bytes or uri is set, but not both."""
|
|
41
|
+
if not self.content_bytes and not self.uri:
|
|
42
|
+
raise ValueError("SamFilePart must have either 'content_bytes' or 'uri'.")
|
|
43
|
+
if self.content_bytes and self.uri:
|
|
44
|
+
raise ValueError("SamFilePart cannot have both 'content_bytes' and 'uri'.")
|
|
45
|
+
return self
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class SamDataPart(BaseModel):
|
|
49
|
+
"""Structured data in a SAM task."""
|
|
50
|
+
|
|
51
|
+
type: Literal["data"] = "data"
|
|
52
|
+
data: Dict[str, Any]
|
|
53
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
SamContentPart = Union[SamTextPart, SamFilePart, SamDataPart]
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# --- Task and Update Models ---
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class SamTask(BaseModel):
|
|
63
|
+
"""A task prepared for submission to the SAM agent mesh."""
|
|
64
|
+
|
|
65
|
+
parts: List[SamContentPart]
|
|
66
|
+
session_id: Optional[str] = None
|
|
67
|
+
target_agent: str = Field(..., description="Target agent name (required).")
|
|
68
|
+
is_streaming: bool = Field(default=True, description="Enable streaming responses.")
|
|
69
|
+
platform_context: Dict[str, Any] = Field(
|
|
70
|
+
default_factory=dict,
|
|
71
|
+
description="Platform-specific data for response routing.",
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class SamUpdate(BaseModel):
|
|
76
|
+
"""An update event from the agent containing one or more parts."""
|
|
77
|
+
|
|
78
|
+
parts: List[SamContentPart] = Field(default_factory=list)
|
|
79
|
+
is_final: bool = Field(
|
|
80
|
+
default=False,
|
|
81
|
+
description="True if this is the final update before task completion.",
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
# --- Auth and Error Models ---
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class AuthClaims(BaseModel):
|
|
89
|
+
"""Authentication claims extracted from a platform event."""
|
|
90
|
+
|
|
91
|
+
id: Optional[str] = Field(
|
|
92
|
+
default=None,
|
|
93
|
+
description="Primary user identifier. If None, generic gateway uses auth_config default.",
|
|
94
|
+
)
|
|
95
|
+
email: Optional[str] = None
|
|
96
|
+
token: Optional[str] = Field(
|
|
97
|
+
default=None, description="Bearer token or API key for token-based auth flows."
|
|
98
|
+
)
|
|
99
|
+
token_type: Optional[Literal["bearer", "api_key"]] = None
|
|
100
|
+
source: str = Field(default="platform", description="Authentication source.")
|
|
101
|
+
raw_context: Dict[str, Any] = Field(
|
|
102
|
+
default_factory=dict, description="Platform-specific auth context."
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class SamError(BaseModel):
|
|
107
|
+
"""A structured error object for outbound error handling."""
|
|
108
|
+
|
|
109
|
+
message: str
|
|
110
|
+
code: int
|
|
111
|
+
category: Literal[
|
|
112
|
+
"FAILED", "CANCELED", "TIMED_OUT", "PROTOCOL_ERROR", "GATEWAY_ERROR"
|
|
113
|
+
]
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class SamFeedback(BaseModel):
|
|
117
|
+
"""A structured model for submitting user feedback."""
|
|
118
|
+
|
|
119
|
+
task_id: str
|
|
120
|
+
session_id: str
|
|
121
|
+
rating: Literal["up", "down"]
|
|
122
|
+
comment: Optional[str] = None
|
|
123
|
+
user_id: str
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# --- Context Models ---
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class ResponseContext(BaseModel):
|
|
130
|
+
"""Context provided with each outbound response callback."""
|
|
131
|
+
|
|
132
|
+
task_id: str
|
|
133
|
+
session_id: Optional[str]
|
|
134
|
+
user_id: str
|
|
135
|
+
platform_context: Dict[str, Any]
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class GatewayContext:
|
|
139
|
+
"""
|
|
140
|
+
Context provided to gateway adapter during initialization.
|
|
141
|
+
|
|
142
|
+
Provides access to gateway services and helper methods.
|
|
143
|
+
This is an abstract class definition; the concrete implementation is the
|
|
144
|
+
GenericGatewayComponent.
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
gateway_id: str
|
|
148
|
+
namespace: str
|
|
149
|
+
config: Dict[str, Any]
|
|
150
|
+
adapter_config: Any # Can be a Pydantic model or a dict
|
|
151
|
+
artifact_service: "BaseArtifactService"
|
|
152
|
+
|
|
153
|
+
async def handle_external_input(
|
|
154
|
+
self, external_input: Any, endpoint_context: Optional[Dict[str, Any]] = None
|
|
155
|
+
) -> str:
|
|
156
|
+
raise NotImplementedError
|
|
157
|
+
|
|
158
|
+
async def cancel_task(self, task_id: str) -> None:
|
|
159
|
+
raise NotImplementedError
|
|
160
|
+
|
|
161
|
+
async def submit_feedback(self, feedback: "SamFeedback") -> None:
|
|
162
|
+
"""Submits user feedback related to a task."""
|
|
163
|
+
raise NotImplementedError
|
|
164
|
+
|
|
165
|
+
async def load_artifact_content(
|
|
166
|
+
self, context: "ResponseContext", filename: str, version: Union[int, str] = "latest"
|
|
167
|
+
) -> Optional[bytes]:
|
|
168
|
+
"""Loads the raw byte content of an artifact."""
|
|
169
|
+
raise NotImplementedError
|
|
170
|
+
|
|
171
|
+
async def list_artifacts(
|
|
172
|
+
self, context: "ResponseContext"
|
|
173
|
+
) -> List["ArtifactInfo"]:
|
|
174
|
+
"""Lists all artifacts available in the user's context."""
|
|
175
|
+
raise NotImplementedError
|
|
176
|
+
|
|
177
|
+
def add_timer(
|
|
178
|
+
self, delay_ms: int, callback: "Callable", interval_ms: Optional[int] = None
|
|
179
|
+
) -> str:
|
|
180
|
+
raise NotImplementedError
|
|
181
|
+
|
|
182
|
+
def cancel_timer(self, timer_id: str) -> None:
|
|
183
|
+
raise NotImplementedError
|
|
184
|
+
|
|
185
|
+
def get_task_state(self, task_id: str, key: str, default: Any = None) -> Any:
|
|
186
|
+
raise NotImplementedError
|
|
187
|
+
|
|
188
|
+
def set_task_state(self, task_id: str, key: str, value: Any) -> None:
|
|
189
|
+
raise NotImplementedError
|
|
190
|
+
|
|
191
|
+
def get_session_state(self, session_id: str, key: str, default: Any = None) -> Any:
|
|
192
|
+
raise NotImplementedError
|
|
193
|
+
|
|
194
|
+
def set_session_state(self, session_id: str, key: str, value: Any) -> None:
|
|
195
|
+
raise NotImplementedError
|
|
196
|
+
|
|
197
|
+
def create_text_part(self, text: str) -> SamTextPart:
|
|
198
|
+
return SamTextPart(text=text)
|
|
199
|
+
|
|
200
|
+
def create_file_part_from_bytes(
|
|
201
|
+
self, name: str, content_bytes: bytes, mime_type: str
|
|
202
|
+
) -> SamFilePart:
|
|
203
|
+
return SamFilePart(name=name, content_bytes=content_bytes, mime_type=mime_type)
|
|
204
|
+
|
|
205
|
+
def create_file_part_from_uri(
|
|
206
|
+
self, uri: str, name: str, mime_type: Optional[str] = None
|
|
207
|
+
) -> SamFilePart:
|
|
208
|
+
return SamFilePart(name=name, uri=uri, mime_type=mime_type)
|
|
209
|
+
|
|
210
|
+
def create_data_part(self, data: Dict[str, Any]) -> SamDataPart:
|
|
211
|
+
return SamDataPart(data=data)
|
|
212
|
+
|
|
213
|
+
def process_sac_template(
|
|
214
|
+
self,
|
|
215
|
+
template: str,
|
|
216
|
+
payload: Any = None,
|
|
217
|
+
headers: Optional[Dict[str, str]] = None,
|
|
218
|
+
query_params: Optional[Dict[str, str]] = None,
|
|
219
|
+
user_data: Optional[Dict[str, Any]] = None,
|
|
220
|
+
) -> str:
|
|
221
|
+
raise NotImplementedError
|
|
@@ -39,6 +39,27 @@ BASE_GATEWAY_APP_SCHEMA: Dict[str, List[Dict[str, Any]]] = {
|
|
|
39
39
|
"default": None,
|
|
40
40
|
"description": "Unique ID for this gateway instance. Auto-generated if omitted.",
|
|
41
41
|
},
|
|
42
|
+
{
|
|
43
|
+
"name": "default_agent_name",
|
|
44
|
+
"required": False,
|
|
45
|
+
"type": "string",
|
|
46
|
+
"default": None,
|
|
47
|
+
"description": "Default agent to route messages to if not specified by the platform or user.",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"name": "system_purpose",
|
|
51
|
+
"required": False,
|
|
52
|
+
"type": "string",
|
|
53
|
+
"default": "",
|
|
54
|
+
"description": "Detailed description of the system's overall purpose, to be optionally used by agents.",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"name": "response_format",
|
|
58
|
+
"required": False,
|
|
59
|
+
"type": "string",
|
|
60
|
+
"default": "",
|
|
61
|
+
"description": "General guidelines on how agent responses should be structured, to be optionally used by agents.",
|
|
62
|
+
},
|
|
42
63
|
{
|
|
43
64
|
"name": "artifact_service",
|
|
44
65
|
"required": True,
|
|
@@ -144,8 +165,14 @@ class BaseGatewayApp(App):
|
|
|
144
165
|
|
|
145
166
|
base_params = BaseGatewayApp.app_schema.get("config_parameters", [])
|
|
146
167
|
|
|
147
|
-
|
|
148
|
-
merged_config_parameters
|
|
168
|
+
# Start with the child's parameters to give them precedence.
|
|
169
|
+
merged_config_parameters = list(specific_params)
|
|
170
|
+
specific_param_names = {p["name"] for p in specific_params}
|
|
171
|
+
|
|
172
|
+
# Add base parameters only if they are not already defined in the child.
|
|
173
|
+
for base_param in base_params:
|
|
174
|
+
if base_param["name"] not in specific_param_names:
|
|
175
|
+
merged_config_parameters.append(base_param)
|
|
149
176
|
|
|
150
177
|
cls.app_schema = {"config_parameters": merged_config_parameters}
|
|
151
178
|
log.debug(
|