solace-agent-mesh 1.6.1__py3-none-any.whl → 1.13.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of solace-agent-mesh might be problematic. Click here for more details.
- solace_agent_mesh/agent/adk/alembic/README +74 -0
- solace_agent_mesh/agent/adk/alembic/env.py +77 -0
- solace_agent_mesh/agent/adk/alembic/script.py.mako +28 -0
- solace_agent_mesh/agent/adk/alembic/versions/e2902798564d_adk_session_db_upgrade.py +52 -0
- solace_agent_mesh/agent/adk/alembic.ini +112 -0
- solace_agent_mesh/agent/adk/app_llm_agent.py +26 -0
- solace_agent_mesh/agent/adk/artifacts/filesystem_artifact_service.py +165 -1
- solace_agent_mesh/agent/adk/artifacts/s3_artifact_service.py +163 -0
- solace_agent_mesh/agent/adk/callbacks.py +852 -109
- solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +234 -36
- solace_agent_mesh/agent/adk/intelligent_mcp_callbacks.py +52 -5
- solace_agent_mesh/agent/adk/mcp_content_processor.py +1 -1
- solace_agent_mesh/agent/adk/models/lite_llm.py +77 -21
- solace_agent_mesh/agent/adk/models/oauth2_token_manager.py +24 -137
- solace_agent_mesh/agent/adk/runner.py +85 -20
- solace_agent_mesh/agent/adk/schema_migration.py +88 -0
- solace_agent_mesh/agent/adk/services.py +94 -18
- solace_agent_mesh/agent/adk/setup.py +281 -65
- solace_agent_mesh/agent/adk/stream_parser.py +231 -37
- solace_agent_mesh/agent/adk/tool_wrapper.py +3 -0
- solace_agent_mesh/agent/protocol/event_handlers.py +472 -137
- solace_agent_mesh/agent/proxies/a2a/app.py +3 -2
- solace_agent_mesh/agent/proxies/a2a/component.py +572 -75
- solace_agent_mesh/agent/proxies/a2a/config.py +80 -4
- solace_agent_mesh/agent/proxies/base/app.py +3 -2
- solace_agent_mesh/agent/proxies/base/component.py +188 -22
- solace_agent_mesh/agent/proxies/base/proxy_task_context.py +3 -1
- solace_agent_mesh/agent/sac/app.py +91 -3
- solace_agent_mesh/agent/sac/component.py +591 -157
- solace_agent_mesh/agent/sac/patch_adk.py +8 -16
- solace_agent_mesh/agent/sac/task_execution_context.py +146 -4
- solace_agent_mesh/agent/tools/__init__.py +3 -0
- solace_agent_mesh/agent/tools/audio_tools.py +3 -3
- solace_agent_mesh/agent/tools/builtin_artifact_tools.py +710 -171
- solace_agent_mesh/agent/tools/deep_research_tools.py +2161 -0
- solace_agent_mesh/agent/tools/dynamic_tool.py +2 -0
- solace_agent_mesh/agent/tools/peer_agent_tool.py +82 -15
- solace_agent_mesh/agent/tools/time_tools.py +126 -0
- solace_agent_mesh/agent/tools/tool_config_types.py +57 -2
- solace_agent_mesh/agent/tools/web_search_tools.py +279 -0
- solace_agent_mesh/agent/tools/web_tools.py +125 -17
- solace_agent_mesh/agent/utils/artifact_helpers.py +248 -6
- solace_agent_mesh/agent/utils/context_helpers.py +17 -0
- solace_agent_mesh/assets/docs/404.html +6 -6
- solace_agent_mesh/assets/docs/assets/css/{styles.906a1503.css → styles.8162edfb.css} +1 -1
- solace_agent_mesh/assets/docs/assets/js/05749d90.19ac4f35.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/15ba94aa.e186750d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/15e40e79.434bb30f.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/17896441.e612dfb4.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2279.550aa580.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/{17896441.a5e82f9b.js.LICENSE.txt → 2279.550aa580.js.LICENSE.txt} +6 -0
- solace_agent_mesh/assets/docs/assets/js/240a0364.83e37aa8.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2987107d.a80604f9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2e32b5e0.2f0db237.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3a6c6137.7e61915d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ac1795d.7f7ab1c1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ff0015d.e53c9b78.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/41adc471.0e95b87c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4667dc50.bf2ad456.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/49eed117.493d6f99.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{509e993c.4c7a1a6d.js → 509e993c.a1fbf45a.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/547e15cc.8e6da617.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/55b7b518.29d6e75d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5b8d9c11.d4eb37b8.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.1ee87753.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/60702c0e.a8bdd79b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/631738c7.fa471607.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/64195356.09dbd087.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/66d4869e.30340bd3.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6a520c9d.b6e3f2ce.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6aaedf65.7253541d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.a5b36a60.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6d84eae0.fd23ba4a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/71da7b71.374b9d54.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/729898df.7249e9fd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/7e294c01.7c5f6906.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8024126c.e3467286.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/81a99df0.7ed65d45.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/82fbfb93.161823a5.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8b032486.91a91afc.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/924ffdeb.975e428a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/94e8668d.16083b3f.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9bb13469.4523ae20.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/a7d42657.a956689d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/a94703ab.3e5fbcb3.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ab9708a8.3e563275.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ad87452a.9d73dad6.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/c93cbaa0.0e0d8baf.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/cab03b5b.6a073091.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/cbe2e9ea.07e170dd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/da0b5bad.b62f7b08.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.06d23db6.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e1b6eeb4.deb2b62e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e3d9abda.1476f570.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e6f9706b.acc800d3.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e92d0134.c147a429.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ee0c2fe7.94d0a351.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f284c35a.cc97854c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ff4d71f2.74710fc1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.d634009f.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.27bb82a7.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +68 -68
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/artifact-management/index.html +50 -50
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/audio-tools/index.html +42 -42
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/data-analysis-tools/index.html +55 -55
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/embeds/index.html +82 -68
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/image-tools/index.html +81 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/index.html +67 -50
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/research-tools/index.html +136 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/cli/index.html +178 -144
- solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +43 -42
- solace_agent_mesh/assets/docs/docs/documentation/components/index.html +20 -18
- solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +23 -23
- solace_agent_mesh/assets/docs/docs/documentation/components/platform-service/index.html +33 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +45 -45
- solace_agent_mesh/assets/docs/docs/documentation/components/projects/index.html +182 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/prompts/index.html +147 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/proxies/index.html +208 -125
- solace_agent_mesh/assets/docs/docs/documentation/components/speech/index.html +52 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +28 -49
- solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +29 -30
- solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +14 -14
- solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes/index.html +47 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes/kubernetes-deployment-guide/index.html +197 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/logging/index.html +90 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +17 -16
- solace_agent_mesh/assets/docs/docs/documentation/deploying/proxy_configuration/index.html +49 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-agents/index.html +38 -38
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-gateways/index.html +162 -171
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-python-tools/index.html +67 -49
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +17 -17
- solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +51 -51
- solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +22 -22
- solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +27 -27
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/bedrock-agents/index.html +135 -135
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/custom-agent/index.html +66 -66
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/event-mesh-gateway/index.html +51 -51
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mcp-integration/index.html +50 -38
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mongodb-integration/index.html +86 -86
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rag-integration/index.html +51 -51
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rest-gateway/index.html +24 -24
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +30 -30
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/sql-database/index.html +44 -44
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/teams-integration/index.html +115 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/agent-builder/index.html +86 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/connectors/index.html +67 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +23 -19
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +40 -37
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/openapi-tools/index.html +324 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +112 -87
- 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 +87 -64
- 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 +44 -44
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +39 -37
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +30 -30
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +18 -18
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/vibe_coding/index.html +62 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/artifact-storage/index.html +311 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +39 -42
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +14 -14
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +27 -25
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +69 -69
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +72 -72
- 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 +42 -42
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-technical-migration-map/index.html +20 -20
- solace_agent_mesh/assets/docs/docs/documentation/migrations/platform-service-split/index.html +85 -0
- solace_agent_mesh/assets/docs/lunr-index-1768329217460.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1768329217460.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/__init__.py +3 -1
- solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +6 -1
- solace_agent_mesh/cli/commands/add_cmd/proxy_cmd.py +100 -0
- solace_agent_mesh/cli/commands/docs_cmd.py +4 -1
- solace_agent_mesh/cli/commands/eval_cmd.py +1 -1
- solace_agent_mesh/cli/commands/init_cmd/__init__.py +15 -0
- solace_agent_mesh/cli/commands/init_cmd/directory_step.py +1 -1
- solace_agent_mesh/cli/commands/init_cmd/env_step.py +30 -3
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +3 -4
- solace_agent_mesh/cli/commands/init_cmd/platform_service_step.py +85 -0
- solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +16 -3
- solace_agent_mesh/cli/commands/plugin_cmd/add_cmd.py +2 -1
- solace_agent_mesh/cli/commands/plugin_cmd/catalog_cmd.py +1 -0
- solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +3 -3
- solace_agent_mesh/cli/commands/run_cmd.py +64 -49
- solace_agent_mesh/cli/commands/tools_cmd.py +315 -0
- solace_agent_mesh/cli/main.py +15 -0
- solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-BTf6dqwp.js → authCallback-KnKMP_vb.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/client-DpBL2stg.js +25 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-Cd498TV2.js +435 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-rSf8Vu29.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/vendor-CGk8Suyh.js +565 -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/client/webui/frontend/static/mockServiceWorker.js +336 -0
- solace_agent_mesh/client/webui/frontend/static/ui-version.json +6 -0
- solace_agent_mesh/common/a2a/events.py +2 -1
- solace_agent_mesh/common/a2a/protocol.py +5 -0
- solace_agent_mesh/common/a2a/types.py +2 -1
- 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/agent_registry.py +38 -11
- solace_agent_mesh/common/data_parts.py +144 -4
- solace_agent_mesh/common/error_handlers.py +83 -0
- solace_agent_mesh/common/exceptions.py +24 -0
- solace_agent_mesh/common/oauth/__init__.py +17 -0
- solace_agent_mesh/common/oauth/oauth_client.py +408 -0
- solace_agent_mesh/common/oauth/utils.py +50 -0
- solace_agent_mesh/common/rag_dto.py +156 -0
- solace_agent_mesh/common/sac/sam_component_base.py +97 -19
- solace_agent_mesh/common/sam_events/event_service.py +2 -2
- solace_agent_mesh/common/services/employee_service.py +1 -1
- solace_agent_mesh/common/utils/embeds/constants.py +1 -0
- solace_agent_mesh/common/utils/embeds/converter.py +1 -8
- solace_agent_mesh/common/utils/embeds/modifiers.py +4 -28
- solace_agent_mesh/common/utils/embeds/resolver.py +152 -31
- solace_agent_mesh/common/utils/embeds/types.py +9 -0
- solace_agent_mesh/common/utils/log_formatters.py +20 -0
- solace_agent_mesh/common/utils/mime_helpers.py +12 -5
- solace_agent_mesh/common/utils/pydantic_utils.py +90 -3
- solace_agent_mesh/common/utils/rbac_utils.py +69 -0
- solace_agent_mesh/common/utils/templates/__init__.py +8 -0
- solace_agent_mesh/common/utils/templates/liquid_renderer.py +210 -0
- solace_agent_mesh/common/utils/templates/template_resolver.py +161 -0
- solace_agent_mesh/config_portal/backend/common.py +12 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-CljP4_mv.js +103 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/{components-Rk0n-9cK.js → components-CaC6hG8d.js} +22 -22
- solace_agent_mesh/config_portal/frontend/static/client/assets/{entry.client-mvZjNKiz.js → entry.client-H_TM0YBt.js} +3 -3
- solace_agent_mesh/config_portal/frontend/static/client/assets/{index-DzNKzXrc.js → index-CnFykb2v.js} +16 -16
- solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-f8439d40.js +1 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-BIMqslJB.css +1 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-mJmTIdIk.js +10 -0
- solace_agent_mesh/config_portal/frontend/static/client/index.html +3 -3
- solace_agent_mesh/core_a2a/service.py +3 -2
- solace_agent_mesh/gateway/adapter/__init__.py +1 -0
- solace_agent_mesh/gateway/adapter/base.py +170 -0
- solace_agent_mesh/gateway/adapter/types.py +230 -0
- solace_agent_mesh/gateway/base/app.py +39 -2
- solace_agent_mesh/gateway/base/auth_interface.py +103 -0
- solace_agent_mesh/gateway/base/component.py +1027 -151
- 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 +894 -0
- solace_agent_mesh/gateway/http_sse/alembic/env.py +0 -7
- 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 +109 -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/20251108_create_prompt_tables_with_sharing.py +154 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251115_add_parent_task_id.py +32 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251126_add_background_task_fields.py +47 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251202_add_versioned_fields_to_prompts.py +52 -0
- solace_agent_mesh/gateway/http_sse/alembic.ini +0 -36
- solace_agent_mesh/gateway/http_sse/app.py +40 -11
- solace_agent_mesh/gateway/http_sse/component.py +285 -160
- solace_agent_mesh/gateway/http_sse/dependencies.py +149 -114
- solace_agent_mesh/gateway/http_sse/main.py +68 -450
- solace_agent_mesh/gateway/http_sse/repository/__init__.py +19 -1
- solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +2 -2
- 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 +26 -3
- solace_agent_mesh/gateway/http_sse/repository/entities/task.py +7 -0
- solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +47 -0
- solace_agent_mesh/gateway/http_sse/repository/interfaces.py +114 -6
- solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +13 -0
- 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/prompt_model.py +159 -0
- solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +8 -2
- solace_agent_mesh/gateway/http_sse/repository/models/task_model.py +8 -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/session_repository.py +177 -11
- solace_agent_mesh/gateway/http_sse/repository/task_repository.py +86 -2
- solace_agent_mesh/gateway/http_sse/routers/agent_cards.py +38 -7
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +256 -58
- solace_agent_mesh/gateway/http_sse/routers/auth.py +168 -134
- solace_agent_mesh/gateway/http_sse/routers/config.py +302 -8
- solace_agent_mesh/gateway/http_sse/routers/dto/project_dto.py +69 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/prompt_dto.py +255 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/project_requests.py +48 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +14 -1
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/base_responses.py +1 -1
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/project_responses.py +31 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +5 -2
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/version_responses.py +31 -0
- solace_agent_mesh/gateway/http_sse/routers/feedback.py +133 -2
- solace_agent_mesh/gateway/http_sse/routers/people.py +2 -2
- solace_agent_mesh/gateway/http_sse/routers/projects.py +768 -0
- solace_agent_mesh/gateway/http_sse/routers/prompts.py +1416 -0
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +167 -7
- solace_agent_mesh/gateway/http_sse/routers/speech.py +355 -0
- solace_agent_mesh/gateway/http_sse/routers/sse.py +131 -8
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +670 -18
- solace_agent_mesh/gateway/http_sse/routers/users.py +1 -1
- solace_agent_mesh/gateway/http_sse/routers/version.py +343 -0
- solace_agent_mesh/gateway/http_sse/routers/visualization.py +92 -9
- solace_agent_mesh/gateway/http_sse/services/audio_service.py +1227 -0
- solace_agent_mesh/gateway/http_sse/services/background_task_monitor.py +186 -0
- solace_agent_mesh/gateway/http_sse/services/data_retention_service.py +1 -1
- solace_agent_mesh/gateway/http_sse/services/feedback_service.py +1 -1
- solace_agent_mesh/gateway/http_sse/services/project_service.py +930 -0
- solace_agent_mesh/gateway/http_sse/services/prompt_builder_assistant.py +303 -0
- solace_agent_mesh/gateway/http_sse/services/session_service.py +361 -12
- solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +354 -4
- solace_agent_mesh/gateway/http_sse/session_manager.py +15 -15
- solace_agent_mesh/gateway/http_sse/sse_manager.py +286 -166
- solace_agent_mesh/gateway/http_sse/utils/artifact_copy_utils.py +370 -0
- solace_agent_mesh/gateway/http_sse/utils/stim_utils.py +41 -1
- solace_agent_mesh/services/__init__.py +0 -0
- solace_agent_mesh/services/platform/__init__.py +29 -0
- solace_agent_mesh/services/platform/alembic/env.py +85 -0
- solace_agent_mesh/services/platform/alembic/script.py.mako +28 -0
- solace_agent_mesh/services/platform/alembic.ini +109 -0
- solace_agent_mesh/services/platform/api/__init__.py +3 -0
- solace_agent_mesh/services/platform/api/dependencies.py +154 -0
- solace_agent_mesh/services/platform/api/main.py +314 -0
- solace_agent_mesh/services/platform/api/middleware.py +51 -0
- solace_agent_mesh/services/platform/api/routers/__init__.py +33 -0
- solace_agent_mesh/services/platform/api/routers/health_router.py +31 -0
- solace_agent_mesh/services/platform/app.py +215 -0
- solace_agent_mesh/services/platform/component.py +777 -0
- solace_agent_mesh/shared/__init__.py +14 -0
- solace_agent_mesh/shared/api/__init__.py +42 -0
- solace_agent_mesh/shared/auth/__init__.py +26 -0
- solace_agent_mesh/shared/auth/dependencies.py +204 -0
- solace_agent_mesh/shared/auth/middleware.py +347 -0
- solace_agent_mesh/shared/database/__init__.py +20 -0
- solace_agent_mesh/{gateway/http_sse/shared → shared/database}/base_repository.py +1 -1
- solace_agent_mesh/{gateway/http_sse/shared → shared/database}/database_exceptions.py +1 -1
- solace_agent_mesh/{gateway/http_sse/shared → shared/database}/database_helpers.py +1 -1
- solace_agent_mesh/shared/exceptions/__init__.py +36 -0
- solace_agent_mesh/{gateway/http_sse/shared → shared/exceptions}/exception_handlers.py +19 -5
- solace_agent_mesh/shared/utils/__init__.py +21 -0
- solace_agent_mesh/templates/logging_config_template.yaml +48 -0
- solace_agent_mesh/templates/main_orchestrator.yaml +12 -1
- solace_agent_mesh/templates/platform.yaml +49 -0
- solace_agent_mesh/templates/plugin_readme_template.md +3 -25
- solace_agent_mesh/templates/plugin_tool_config_template.yaml +109 -0
- solace_agent_mesh/templates/proxy_template.yaml +62 -0
- solace_agent_mesh/templates/webui.yaml +148 -6
- solace_agent_mesh/tools/web_search/__init__.py +18 -0
- solace_agent_mesh/tools/web_search/base.py +84 -0
- solace_agent_mesh/tools/web_search/google_search.py +247 -0
- solace_agent_mesh/tools/web_search/models.py +99 -0
- {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/METADATA +31 -12
- solace_agent_mesh-1.13.2.dist-info/RECORD +591 -0
- {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/WHEEL +1 -1
- solace_agent_mesh/agent/adk/adk_llm.txt +0 -232
- solace_agent_mesh/agent/adk/adk_llm_detail.txt +0 -566
- solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +0 -171
- solace_agent_mesh/agent/adk/models/models_llm.txt +0 -142
- solace_agent_mesh/agent/agent_llm.txt +0 -378
- solace_agent_mesh/agent/agent_llm_detail.txt +0 -1702
- solace_agent_mesh/agent/protocol/protocol_llm.txt +0 -81
- solace_agent_mesh/agent/protocol/protocol_llm_detail.txt +0 -92
- solace_agent_mesh/agent/sac/sac_llm.txt +0 -189
- solace_agent_mesh/agent/sac/sac_llm_detail.txt +0 -200
- solace_agent_mesh/agent/testing/testing_llm.txt +0 -57
- solace_agent_mesh/agent/testing/testing_llm_detail.txt +0 -68
- solace_agent_mesh/agent/tools/tools_llm.txt +0 -263
- solace_agent_mesh/agent/tools/tools_llm_detail.txt +0 -274
- solace_agent_mesh/agent/utils/utils_llm.txt +0 -138
- solace_agent_mesh/agent/utils/utils_llm_detail.txt +0 -149
- solace_agent_mesh/assets/docs/assets/js/15ba94aa.932dd2db.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/17896441.a5e82f9b.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/240a0364.7eac6021.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/2e32b5e0.33f5d75b.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/3a6c6137.f5940cfa.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/55b7b518.f2b1d1ba.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.eda4bcb2.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/631738c7.a8b1ef8b.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/6d84eae0.4a5fbf39.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/71da7b71.38583438.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/8024126c.56e59919.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/81a99df0.07034dd9.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/82fbfb93.139a1a1f.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/924ffdeb.8095e148.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/94e8668d.b5ddb7a1.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/9bb13469.dd1c9b54.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/a94703ab.0438dbc2.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/ab9708a8.3e6dd091.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/c93cbaa0.eaff365e.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/e6f9706b.e74a984d.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e92d0134.cf6d6522.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f284c35a.42f59cdd.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/ff4d71f2.15b02f97.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/main.b12eac43.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.e268214e.js +0 -1
- solace_agent_mesh/assets/docs/lunr-index-1761248203150.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1761248203150.json +0 -1
- solace_agent_mesh/cli/commands/add_cmd/add_cmd_llm.txt +0 -250
- solace_agent_mesh/cli/commands/init_cmd/init_cmd_llm.txt +0 -365
- solace_agent_mesh/cli/commands/plugin_cmd/plugin_cmd_llm.txt +0 -305
- solace_agent_mesh/client/webui/frontend/static/assets/client-CaY59VuC.js +0 -25
- solace_agent_mesh/client/webui/frontend/static/assets/main-B32noGmR.js +0 -342
- solace_agent_mesh/client/webui/frontend/static/assets/main-DHJKSW1S.css +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/vendor-BEmvJSYz.js +0 -405
- solace_agent_mesh/common/a2a/a2a_llm.txt +0 -182
- solace_agent_mesh/common/a2a/a2a_llm_detail.txt +0 -193
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +0 -407
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm_detail.txt +0 -736
- solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +0 -313
- solace_agent_mesh/common/common_llm.txt +0 -251
- solace_agent_mesh/common/common_llm_detail.txt +0 -2562
- solace_agent_mesh/common/middleware/middleware_llm.txt +0 -174
- solace_agent_mesh/common/middleware/middleware_llm_detail.txt +0 -185
- solace_agent_mesh/common/sac/sac_llm.txt +0 -71
- solace_agent_mesh/common/sac/sac_llm_detail.txt +0 -82
- solace_agent_mesh/common/sam_events/sam_events_llm.txt +0 -104
- solace_agent_mesh/common/sam_events/sam_events_llm_detail.txt +0 -115
- solace_agent_mesh/common/services/providers/providers_llm.txt +0 -80
- solace_agent_mesh/common/services/services_llm.txt +0 -363
- solace_agent_mesh/common/services/services_llm_detail.txt +0 -459
- solace_agent_mesh/common/utils/embeds/embeds_llm.txt +0 -220
- solace_agent_mesh/common/utils/utils_llm.txt +0 -336
- solace_agent_mesh/common/utils/utils_llm_detail.txt +0 -572
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-ByU1X1HD.js +0 -98
- solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-61038fc6.js +0 -1
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-BWvk5-gF.js +0 -10
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-DxRwaWiE.css +0 -1
- solace_agent_mesh/core_a2a/core_a2a_llm.txt +0 -90
- solace_agent_mesh/core_a2a/core_a2a_llm_detail.txt +0 -101
- solace_agent_mesh/gateway/base/base_llm.txt +0 -224
- solace_agent_mesh/gateway/base/base_llm_detail.txt +0 -235
- solace_agent_mesh/gateway/gateway_llm.txt +0 -373
- solace_agent_mesh/gateway/gateway_llm_detail.txt +0 -3885
- solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +0 -295
- solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +0 -155
- solace_agent_mesh/gateway/http_sse/components/components_llm.txt +0 -105
- solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +0 -299
- solace_agent_mesh/gateway/http_sse/http_sse_llm_detail.txt +0 -3278
- solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +0 -263
- solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +0 -266
- solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +0 -340
- solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +0 -346
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +0 -83
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +0 -107
- solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +0 -314
- solace_agent_mesh/gateway/http_sse/services/services_llm.txt +0 -297
- solace_agent_mesh/gateway/http_sse/shared/__init__.py +0 -146
- solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +0 -285
- solace_agent_mesh/gateway/http_sse/utils/utils_llm.txt +0 -47
- solace_agent_mesh/llm.txt +0 -228
- solace_agent_mesh/llm_detail.txt +0 -2835
- solace_agent_mesh/solace_agent_mesh_llm.txt +0 -362
- solace_agent_mesh/solace_agent_mesh_llm_detail.txt +0 -8599
- solace_agent_mesh/templates/logging_config_template.ini +0 -45
- solace_agent_mesh/templates/templates_llm.txt +0 -147
- solace_agent_mesh-1.6.1.dist-info/RECORD +0 -525
- /solace_agent_mesh/assets/docs/assets/js/{main.b12eac43.js.LICENSE.txt → main.d634009f.js.LICENSE.txt} +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/api}/auth_utils.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/api}/pagination.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/api}/response_utils.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/exceptions}/error_dto.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/exceptions}/exceptions.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/enums.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/timestamp_utils.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/types.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/utils.py +0 -0
- {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -11,11 +11,24 @@ from ..base.config import BaseProxyAppConfig, ProxiedAgentConfig
|
|
|
11
11
|
from ....common.utils.pydantic_utils import SamConfigBase
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
class HttpHeaderConfig(SamConfigBase):
|
|
15
|
+
"""Configuration for a single HTTP header."""
|
|
16
|
+
|
|
17
|
+
name: str = Field(
|
|
18
|
+
...,
|
|
19
|
+
description="The HTTP header name (e.g., 'X-API-Key', 'Authorization').",
|
|
20
|
+
)
|
|
21
|
+
value: str = Field(
|
|
22
|
+
...,
|
|
23
|
+
description="The HTTP header value.",
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
14
27
|
class AuthenticationConfig(SamConfigBase):
|
|
15
28
|
"""Authentication configuration for downstream A2A agents."""
|
|
16
29
|
|
|
17
30
|
type: Optional[
|
|
18
|
-
Literal["static_bearer", "static_apikey", "oauth2_client_credentials"]
|
|
31
|
+
Literal["static_bearer", "static_apikey", "oauth2_client_credentials", "oauth2_authorization_code"]
|
|
19
32
|
] = Field(
|
|
20
33
|
default=None,
|
|
21
34
|
description="Authentication type. If not specified, inferred from 'scheme' for backward compatibility.",
|
|
@@ -34,11 +47,11 @@ class AuthenticationConfig(SamConfigBase):
|
|
|
34
47
|
)
|
|
35
48
|
client_id: Optional[str] = Field(
|
|
36
49
|
default=None,
|
|
37
|
-
description="OAuth 2.0 client identifier (required for oauth2_client_credentials
|
|
50
|
+
description="OAuth 2.0 client identifier (required for oauth2_client_credentials and oauth2_authorization_code types).",
|
|
38
51
|
)
|
|
39
52
|
client_secret: Optional[str] = Field(
|
|
40
53
|
default=None,
|
|
41
|
-
description="OAuth 2.0 client secret (required for oauth2_client_credentials type).",
|
|
54
|
+
description="OAuth 2.0 client secret (required for oauth2_client_credentials type, optional for oauth2_authorization_code).",
|
|
42
55
|
)
|
|
43
56
|
scope: Optional[str] = Field(
|
|
44
57
|
default=None,
|
|
@@ -50,6 +63,20 @@ class AuthenticationConfig(SamConfigBase):
|
|
|
50
63
|
description="How long to cache OAuth 2.0 tokens before refresh, in seconds (default: 3300 = 55 minutes).",
|
|
51
64
|
)
|
|
52
65
|
|
|
66
|
+
# NEW fields for oauth2_authorization_code
|
|
67
|
+
authorization_url: Optional[str] = Field(
|
|
68
|
+
default=None,
|
|
69
|
+
description="OAuth 2.0 authorization endpoint URL (for oauth2_authorization_code type). Can override agent card URL.",
|
|
70
|
+
)
|
|
71
|
+
redirect_uri: Optional[str] = Field(
|
|
72
|
+
default=None,
|
|
73
|
+
description="OAuth 2.0 redirect URI (required for oauth2_authorization_code type).",
|
|
74
|
+
)
|
|
75
|
+
scopes: Optional[List[str]] = Field(
|
|
76
|
+
default=None,
|
|
77
|
+
description="OAuth 2.0 scopes as a list of strings (optional for oauth2_authorization_code type).",
|
|
78
|
+
)
|
|
79
|
+
|
|
53
80
|
@model_validator(mode="after")
|
|
54
81
|
def validate_auth_config(self) -> "AuthenticationConfig":
|
|
55
82
|
"""Validates authentication configuration based on type."""
|
|
@@ -108,10 +135,35 @@ class AuthenticationConfig(SamConfigBase):
|
|
|
108
135
|
"OAuth 2.0 client credentials flow requires 'client_secret'."
|
|
109
136
|
)
|
|
110
137
|
|
|
138
|
+
elif auth_type == "oauth2_authorization_code":
|
|
139
|
+
# Validate client_id
|
|
140
|
+
if not self.client_id:
|
|
141
|
+
raise ValueError(
|
|
142
|
+
"OAuth 2.0 authorization code flow requires 'client_id'."
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
# Validate redirect_uri
|
|
146
|
+
if not self.redirect_uri:
|
|
147
|
+
raise ValueError(
|
|
148
|
+
"OAuth 2.0 authorization code flow requires 'redirect_uri'."
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
# Optional: Validate authorization_url if provided (can also come from agent card)
|
|
152
|
+
if self.authorization_url:
|
|
153
|
+
try:
|
|
154
|
+
parsed_url = urlparse(self.authorization_url)
|
|
155
|
+
if parsed_url.scheme not in ["https", "http"]:
|
|
156
|
+
raise ValueError(
|
|
157
|
+
f"OAuth 2.0 'authorization_url' must use HTTP(S). "
|
|
158
|
+
f"Got scheme: '{parsed_url.scheme}'"
|
|
159
|
+
)
|
|
160
|
+
except Exception as e:
|
|
161
|
+
raise ValueError(f"Failed to parse 'authorization_url': {e}")
|
|
162
|
+
|
|
111
163
|
else:
|
|
112
164
|
raise ValueError(
|
|
113
165
|
f"Unsupported authentication type '{auth_type}'. "
|
|
114
|
-
f"Supported types: static_bearer, static_apikey, oauth2_client_credentials."
|
|
166
|
+
f"Supported types: static_bearer, static_apikey, oauth2_client_credentials, oauth2_authorization_code."
|
|
115
167
|
)
|
|
116
168
|
|
|
117
169
|
return self
|
|
@@ -128,6 +180,30 @@ class A2AProxiedAgentConfig(ProxiedAgentConfig):
|
|
|
128
180
|
default=None,
|
|
129
181
|
description="Authentication details for the downstream agent.",
|
|
130
182
|
)
|
|
183
|
+
use_auth_for_agent_card: bool = Field(
|
|
184
|
+
default=False,
|
|
185
|
+
description="If true, applies the configured authentication to agent card fetching. "
|
|
186
|
+
"If false, agent card requests are made without authentication.",
|
|
187
|
+
)
|
|
188
|
+
use_agent_card_url: bool = Field(
|
|
189
|
+
default=True,
|
|
190
|
+
description="If true, uses the URL from the agent card for task invocations. "
|
|
191
|
+
"If false, uses the configured URL directly for task invocations. "
|
|
192
|
+
"Note: The configured URL is always used to fetch the agent card itself.",
|
|
193
|
+
)
|
|
194
|
+
agent_card_headers: Optional[List[HttpHeaderConfig]] = Field(
|
|
195
|
+
default=None,
|
|
196
|
+
description="Custom HTTP headers to include when fetching the agent card. "
|
|
197
|
+
"These headers are added alongside authentication headers.",
|
|
198
|
+
)
|
|
199
|
+
task_headers: Optional[List[HttpHeaderConfig]] = Field(
|
|
200
|
+
default=None,
|
|
201
|
+
description="Custom HTTP headers to include when invoking A2A tasks. "
|
|
202
|
+
"These headers are added alongside authentication headers. Note: The A2A SDK's "
|
|
203
|
+
"AuthInterceptor applies authentication headers after these are set, so custom "
|
|
204
|
+
"headers cannot override authentication. For custom auth, omit the 'authentication' "
|
|
205
|
+
"config and use task_headers to set auth headers directly.",
|
|
206
|
+
)
|
|
131
207
|
|
|
132
208
|
|
|
133
209
|
class A2AProxyAppConfig(BaseProxyAppConfig):
|
|
@@ -43,8 +43,9 @@ class BaseProxyApp(App, ABC):
|
|
|
43
43
|
# Overwrite the raw dict with the validated object for downstream use
|
|
44
44
|
app_info["app_config"] = app_config
|
|
45
45
|
except ValidationError as e:
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
message = BaseProxyAppConfig.format_validation_error_message(e, app_info['name'])
|
|
47
|
+
log.error("Invalid Proxy configuration:\n%s", message)
|
|
48
|
+
raise
|
|
48
49
|
|
|
49
50
|
namespace = app_config.get("namespace")
|
|
50
51
|
proxied_agents = app_config.get("proxied_agents", [])
|
|
@@ -7,8 +7,9 @@ from __future__ import annotations
|
|
|
7
7
|
import asyncio
|
|
8
8
|
import concurrent.futures
|
|
9
9
|
import threading
|
|
10
|
+
import time
|
|
10
11
|
from abc import ABC, abstractmethod
|
|
11
|
-
from typing import Any, Dict, Optional, TYPE_CHECKING
|
|
12
|
+
from typing import Any, Dict, Optional, Tuple, TYPE_CHECKING
|
|
12
13
|
|
|
13
14
|
import httpx
|
|
14
15
|
|
|
@@ -32,6 +33,8 @@ from ....common.a2a.protocol import (
|
|
|
32
33
|
from a2a.types import (
|
|
33
34
|
A2ARequest,
|
|
34
35
|
AgentCard,
|
|
36
|
+
AgentCapabilities,
|
|
37
|
+
AgentExtension,
|
|
35
38
|
CancelTaskRequest,
|
|
36
39
|
FilePart,
|
|
37
40
|
InternalError,
|
|
@@ -77,16 +80,22 @@ class BaseProxyComponent(ComponentBase, ABC):
|
|
|
77
80
|
"artifact_service", {"type": "memory"}
|
|
78
81
|
)
|
|
79
82
|
self.discovery_interval_sec = self.get_config("discovery_interval_seconds", 60)
|
|
83
|
+
self.task_state_ttl_minutes = self.get_config("task_state_ttl_minutes", 60)
|
|
84
|
+
self.task_cleanup_interval_minutes = self.get_config(
|
|
85
|
+
"task_cleanup_interval_minutes", 10
|
|
86
|
+
)
|
|
80
87
|
|
|
81
88
|
self.agent_registry = AgentRegistry()
|
|
82
89
|
self.artifact_service: Optional[BaseArtifactService] = None
|
|
83
|
-
|
|
90
|
+
# Store (timestamp, ProxyTaskContext) tuples for TTL-based cleanup
|
|
91
|
+
self.active_tasks: Dict[str, Tuple[float, ProxyTaskContext]] = {}
|
|
84
92
|
self.active_tasks_lock = threading.Lock()
|
|
85
93
|
|
|
86
94
|
self._async_loop: Optional[asyncio.AbstractEventLoop] = None
|
|
87
95
|
self._async_thread: Optional[threading.Thread] = None
|
|
88
96
|
self._async_init_future: Optional[concurrent.futures.Future] = None
|
|
89
97
|
self._discovery_timer_id = f"proxy_discovery_{self.name}"
|
|
98
|
+
self._task_cleanup_timer_id = f"proxy_task_cleanup_{self.name}"
|
|
90
99
|
|
|
91
100
|
try:
|
|
92
101
|
# Initialize synchronous services first
|
|
@@ -158,8 +167,11 @@ class BaseProxyComponent(ComponentBase, ABC):
|
|
|
158
167
|
if not hasattr(event, "_proxy_message_handled"):
|
|
159
168
|
event._proxy_message_handled = message_handled
|
|
160
169
|
elif event.event_type == EventType.TIMER:
|
|
161
|
-
|
|
170
|
+
timer_id = event.data.get("timer_id")
|
|
171
|
+
if timer_id == self._discovery_timer_id:
|
|
162
172
|
await self._discover_and_publish_agents()
|
|
173
|
+
elif timer_id == self._task_cleanup_timer_id:
|
|
174
|
+
await self._cleanup_stale_tasks()
|
|
163
175
|
else:
|
|
164
176
|
log.debug(
|
|
165
177
|
"%s Ignoring unhandled event type: %s",
|
|
@@ -209,12 +221,13 @@ class BaseProxyComponent(ComponentBase, ABC):
|
|
|
209
221
|
"status_topic": message.get_user_properties().get("a2aStatusTopic"),
|
|
210
222
|
"reply_to_topic": message.get_user_properties().get("replyTo"),
|
|
211
223
|
"is_streaming": isinstance(a2a_request.root, SendStreamingMessageRequest),
|
|
224
|
+
"user_properties": message.get_user_properties(),
|
|
212
225
|
}
|
|
213
226
|
task_context = ProxyTaskContext(
|
|
214
227
|
task_id=logical_task_id, a2a_context=a2a_context
|
|
215
228
|
)
|
|
216
229
|
with self.active_tasks_lock:
|
|
217
|
-
self.active_tasks[logical_task_id] = task_context
|
|
230
|
+
self.active_tasks[logical_task_id] = (time.time(), task_context)
|
|
218
231
|
|
|
219
232
|
log.info(
|
|
220
233
|
"%s Forwarding request for task %s to agent %s.",
|
|
@@ -228,12 +241,13 @@ class BaseProxyComponent(ComponentBase, ABC):
|
|
|
228
241
|
|
|
229
242
|
elif isinstance(a2a_request.root, CancelTaskRequest):
|
|
230
243
|
logical_task_id = get_task_id_from_cancel_request(a2a_request)
|
|
231
|
-
|
|
244
|
+
|
|
232
245
|
# Get the agent name from the topic (same as for send_message)
|
|
233
246
|
target_agent_name = topic.split("/")[-1]
|
|
234
|
-
|
|
247
|
+
|
|
235
248
|
with self.active_tasks_lock:
|
|
236
|
-
|
|
249
|
+
task_entry = self.active_tasks.get(logical_task_id)
|
|
250
|
+
task_context = task_entry[1] if task_entry else None
|
|
237
251
|
|
|
238
252
|
if task_context:
|
|
239
253
|
log.info(
|
|
@@ -319,6 +333,73 @@ class BaseProxyComponent(ComponentBase, ABC):
|
|
|
319
333
|
|
|
320
334
|
return update_message_parts(original_message, resolved_parts)
|
|
321
335
|
|
|
336
|
+
def _update_agent_card_for_proxy(self, agent_card: AgentCard, agent_alias: str) -> AgentCard:
|
|
337
|
+
"""
|
|
338
|
+
Updates an agent card for proxying by:
|
|
339
|
+
1. Setting the name to the proxy alias
|
|
340
|
+
2. Adding/updating the display-name extension to preserve the original name
|
|
341
|
+
|
|
342
|
+
Args:
|
|
343
|
+
agent_card: The original agent card fetched from the remote agent
|
|
344
|
+
agent_alias: The alias/name to use for this agent in SAM
|
|
345
|
+
|
|
346
|
+
Returns:
|
|
347
|
+
A modified copy of the agent card with updated name and display-name extension
|
|
348
|
+
"""
|
|
349
|
+
# Create a deep copy to avoid modifying the original
|
|
350
|
+
card_copy = agent_card.model_copy(deep=True)
|
|
351
|
+
|
|
352
|
+
# Store the original name as the display name (if not already set)
|
|
353
|
+
# This preserves the agent's identity while allowing it to be proxied under an alias
|
|
354
|
+
original_display_name = agent_card.name
|
|
355
|
+
|
|
356
|
+
# Check if there's already a display-name extension to preserve
|
|
357
|
+
display_name_uri = "https://solace.com/a2a/extensions/display-name"
|
|
358
|
+
if card_copy.capabilities and card_copy.capabilities.extensions:
|
|
359
|
+
for ext in card_copy.capabilities.extensions:
|
|
360
|
+
if ext.uri == display_name_uri and ext.params and ext.params.get("display_name"):
|
|
361
|
+
# Use the existing display name from the extension
|
|
362
|
+
original_display_name = ext.params["display_name"]
|
|
363
|
+
break
|
|
364
|
+
|
|
365
|
+
# Update the card's name to the proxy alias
|
|
366
|
+
card_copy.name = agent_alias
|
|
367
|
+
|
|
368
|
+
# Ensure capabilities and extensions exist
|
|
369
|
+
if not card_copy.capabilities:
|
|
370
|
+
card_copy.capabilities = AgentCapabilities(extensions=[])
|
|
371
|
+
if not card_copy.capabilities.extensions:
|
|
372
|
+
card_copy.capabilities.extensions = []
|
|
373
|
+
|
|
374
|
+
# Find or create the display-name extension
|
|
375
|
+
display_name_ext = None
|
|
376
|
+
for ext in card_copy.capabilities.extensions:
|
|
377
|
+
if ext.uri == display_name_uri:
|
|
378
|
+
display_name_ext = ext
|
|
379
|
+
break
|
|
380
|
+
|
|
381
|
+
if display_name_ext:
|
|
382
|
+
# Update existing extension
|
|
383
|
+
if not display_name_ext.params:
|
|
384
|
+
display_name_ext.params = {}
|
|
385
|
+
display_name_ext.params["display_name"] = original_display_name
|
|
386
|
+
else:
|
|
387
|
+
# Create new extension
|
|
388
|
+
new_ext = AgentExtension(
|
|
389
|
+
uri=display_name_uri,
|
|
390
|
+
params={"display_name": original_display_name}
|
|
391
|
+
)
|
|
392
|
+
card_copy.capabilities.extensions.append(new_ext)
|
|
393
|
+
|
|
394
|
+
log.debug(
|
|
395
|
+
"%s Updated agent card: name='%s', display_name='%s'",
|
|
396
|
+
self.log_identifier,
|
|
397
|
+
agent_alias,
|
|
398
|
+
original_display_name
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
return card_copy
|
|
402
|
+
|
|
322
403
|
def _initial_discovery_sync(self):
|
|
323
404
|
"""
|
|
324
405
|
Synchronously fetches agent cards to populate the registry at startup.
|
|
@@ -340,12 +421,12 @@ class BaseProxyComponent(ComponentBase, ABC):
|
|
|
340
421
|
continue
|
|
341
422
|
try:
|
|
342
423
|
# Use a synchronous client for this initial blocking call
|
|
343
|
-
response = client.get(f"{agent_url}/.well-known/agent.json")
|
|
424
|
+
response = client.get(f"{agent_url}/.well-known/agent-card.json")
|
|
344
425
|
response.raise_for_status()
|
|
345
426
|
agent_card = AgentCard.model_validate(response.json())
|
|
346
427
|
|
|
347
|
-
|
|
348
|
-
card_for_proxy
|
|
428
|
+
# Update the card for proxying (preserves display name)
|
|
429
|
+
card_for_proxy = self._update_agent_card_for_proxy(agent_card, agent_alias)
|
|
349
430
|
self.agent_registry.add_or_update_agent(card_for_proxy)
|
|
350
431
|
log.info(
|
|
351
432
|
"%s Initial discovery successful for alias '%s' (actual name: '%s').",
|
|
@@ -376,12 +457,12 @@ class BaseProxyComponent(ComponentBase, ABC):
|
|
|
376
457
|
continue
|
|
377
458
|
|
|
378
459
|
agent_alias = agent_config["name"]
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
self.agent_registry.add_or_update_agent(
|
|
460
|
+
# Update the card for proxying (preserves display name)
|
|
461
|
+
card_for_registry = self._update_agent_card_for_proxy(modern_card, agent_alias)
|
|
462
|
+
self.agent_registry.add_or_update_agent(card_for_registry)
|
|
382
463
|
|
|
383
|
-
#
|
|
384
|
-
card_to_publish =
|
|
464
|
+
# Create a separate copy for publishing
|
|
465
|
+
card_to_publish = card_for_registry.model_copy(deep=True)
|
|
385
466
|
card_to_publish.url = (
|
|
386
467
|
f"solace:{a2a.get_agent_request_topic(self.namespace, agent_alias)}"
|
|
387
468
|
)
|
|
@@ -418,10 +499,14 @@ class BaseProxyComponent(ComponentBase, ABC):
|
|
|
418
499
|
response = create_success_response(
|
|
419
500
|
result=event, request_id=a2a_context.get("jsonrpc_request_id")
|
|
420
501
|
)
|
|
421
|
-
self._publish_a2a_message(
|
|
502
|
+
self._publish_a2a_message(
|
|
503
|
+
response.model_dump(exclude_none=True),
|
|
504
|
+
target_topic,
|
|
505
|
+
user_properties=a2a_context.get("user_properties")
|
|
506
|
+
)
|
|
422
507
|
|
|
423
|
-
async def
|
|
424
|
-
"""Publishes
|
|
508
|
+
async def _publish_task_response(self, task: Task, a2a_context: Dict):
|
|
509
|
+
"""Publishes a Task object to the reply topic."""
|
|
425
510
|
target_topic = a2a_context.get("reply_to_topic")
|
|
426
511
|
if not target_topic:
|
|
427
512
|
log.warning(
|
|
@@ -434,7 +519,11 @@ class BaseProxyComponent(ComponentBase, ABC):
|
|
|
434
519
|
response = create_success_response(
|
|
435
520
|
result=task, request_id=a2a_context.get("jsonrpc_request_id")
|
|
436
521
|
)
|
|
437
|
-
self._publish_a2a_message(
|
|
522
|
+
self._publish_a2a_message(
|
|
523
|
+
response.model_dump(exclude_none=True),
|
|
524
|
+
target_topic,
|
|
525
|
+
user_properties=a2a_context.get("user_properties")
|
|
526
|
+
)
|
|
438
527
|
|
|
439
528
|
async def _publish_artifact_update(
|
|
440
529
|
self, event: TaskArtifactUpdateEvent, a2a_context: Dict
|
|
@@ -452,7 +541,11 @@ class BaseProxyComponent(ComponentBase, ABC):
|
|
|
452
541
|
response = create_success_response(
|
|
453
542
|
result=event, request_id=a2a_context.get("jsonrpc_request_id")
|
|
454
543
|
)
|
|
455
|
-
self._publish_a2a_message(
|
|
544
|
+
self._publish_a2a_message(
|
|
545
|
+
response.model_dump(exclude_none=True),
|
|
546
|
+
target_topic,
|
|
547
|
+
user_properties=a2a_context.get("user_properties")
|
|
548
|
+
)
|
|
456
549
|
|
|
457
550
|
async def _publish_error_response(
|
|
458
551
|
self,
|
|
@@ -551,16 +644,73 @@ class BaseProxyComponent(ComponentBase, ABC):
|
|
|
551
644
|
nack_e,
|
|
552
645
|
)
|
|
553
646
|
|
|
647
|
+
async def _cleanup_stale_tasks(self):
|
|
648
|
+
"""
|
|
649
|
+
Removes task state older than configured TTL.
|
|
650
|
+
This prevents memory leaks from tasks that complete without sending terminal events
|
|
651
|
+
(e.g., due to agent crashes or network failures).
|
|
652
|
+
"""
|
|
653
|
+
ttl_seconds = self.task_state_ttl_minutes * 60
|
|
654
|
+
cutoff_time = time.time() - ttl_seconds
|
|
655
|
+
|
|
656
|
+
with self.active_tasks_lock:
|
|
657
|
+
stale_task_ids = [
|
|
658
|
+
task_id
|
|
659
|
+
for task_id, (timestamp, _) in self.active_tasks.items()
|
|
660
|
+
if timestamp < cutoff_time
|
|
661
|
+
]
|
|
662
|
+
for task_id in stale_task_ids:
|
|
663
|
+
del self.active_tasks[task_id]
|
|
664
|
+
log.warning(
|
|
665
|
+
"%s Cleaned up stale task %s (exceeded TTL of %d minutes)",
|
|
666
|
+
self.log_identifier,
|
|
667
|
+
task_id,
|
|
668
|
+
self.task_state_ttl_minutes,
|
|
669
|
+
)
|
|
670
|
+
|
|
671
|
+
if stale_task_ids:
|
|
672
|
+
log.info(
|
|
673
|
+
"%s Stale task cleanup removed %d tasks",
|
|
674
|
+
self.log_identifier,
|
|
675
|
+
len(stale_task_ids),
|
|
676
|
+
)
|
|
677
|
+
|
|
678
|
+
def _cleanup_task_state(self, task_id: str) -> None:
|
|
679
|
+
"""
|
|
680
|
+
Cleans up state for a completed task.
|
|
681
|
+
Called when a terminal event is detected (Task with terminal state,
|
|
682
|
+
or TaskStatusUpdateEvent with final=true).
|
|
683
|
+
|
|
684
|
+
Args:
|
|
685
|
+
task_id: The ID of the task to clean up
|
|
686
|
+
"""
|
|
687
|
+
with self.active_tasks_lock:
|
|
688
|
+
entry = self.active_tasks.pop(task_id, None)
|
|
689
|
+
if entry:
|
|
690
|
+
log.info(
|
|
691
|
+
"%s Removed task %s from active_tasks (terminal event detected)",
|
|
692
|
+
self.log_identifier,
|
|
693
|
+
task_id,
|
|
694
|
+
)
|
|
695
|
+
else:
|
|
696
|
+
log.debug(
|
|
697
|
+
"%s Task %s not found in active_tasks during cleanup (already removed)",
|
|
698
|
+
self.log_identifier,
|
|
699
|
+
task_id,
|
|
700
|
+
)
|
|
701
|
+
|
|
554
702
|
def _publish_discovered_cards(self):
|
|
555
703
|
"""Publishes all agent cards currently in the registry."""
|
|
556
704
|
log.info(
|
|
557
705
|
"%s Publishing initially discovered agent cards...", self.log_identifier
|
|
558
706
|
)
|
|
559
707
|
for agent_alias in self.agent_registry.get_agent_names():
|
|
560
|
-
|
|
561
|
-
if not
|
|
708
|
+
original_card = self.agent_registry.get_agent(agent_alias)
|
|
709
|
+
if not original_card:
|
|
562
710
|
continue
|
|
563
711
|
|
|
712
|
+
# Create a copy for publishing to avoid modifying the card in the registry
|
|
713
|
+
card_to_publish = original_card.model_copy(deep=True)
|
|
564
714
|
card_to_publish.url = (
|
|
565
715
|
f"solace:{a2a.get_agent_request_topic(self.namespace, agent_alias)}"
|
|
566
716
|
)
|
|
@@ -599,6 +749,21 @@ class BaseProxyComponent(ComponentBase, ABC):
|
|
|
599
749
|
self.discovery_interval_sec,
|
|
600
750
|
)
|
|
601
751
|
|
|
752
|
+
# Schedule the recurring task cleanup timer
|
|
753
|
+
if self.task_cleanup_interval_minutes > 0:
|
|
754
|
+
cleanup_interval_ms = self.task_cleanup_interval_minutes * 60 * 1000
|
|
755
|
+
self.add_timer(
|
|
756
|
+
delay_ms=cleanup_interval_ms,
|
|
757
|
+
timer_id=self._task_cleanup_timer_id,
|
|
758
|
+
interval_ms=cleanup_interval_ms,
|
|
759
|
+
)
|
|
760
|
+
log.info(
|
|
761
|
+
"%s Scheduled recurring stale task cleanup every %d minutes (TTL: %d minutes).",
|
|
762
|
+
self.log_identifier,
|
|
763
|
+
self.task_cleanup_interval_minutes,
|
|
764
|
+
self.task_state_ttl_minutes,
|
|
765
|
+
)
|
|
766
|
+
|
|
602
767
|
super().run()
|
|
603
768
|
|
|
604
769
|
def clear_client_cache(self):
|
|
@@ -614,6 +779,7 @@ class BaseProxyComponent(ComponentBase, ABC):
|
|
|
614
779
|
"""Cleans up resources on component shutdown."""
|
|
615
780
|
log.info("%s Cleaning up proxy component.", self.log_identifier)
|
|
616
781
|
self.cancel_timer(self._discovery_timer_id)
|
|
782
|
+
self.cancel_timer(self._task_cleanup_timer_id)
|
|
617
783
|
|
|
618
784
|
# Clear active tasks (no need to signal cancellation - downstream agents own their tasks)
|
|
619
785
|
with self.active_tasks_lock:
|
|
@@ -13,5 +13,7 @@ class ProxyTaskContext:
|
|
|
13
13
|
This object is created when a task is initiated and destroyed when it completes.
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
|
-
task_id: str
|
|
16
|
+
task_id: str # SAM's task ID (used for upstream communication)
|
|
17
17
|
a2a_context: Dict[str, Any]
|
|
18
|
+
downstream_task_id: str | None = None # Downstream agent's task ID (used for cancellation)
|
|
19
|
+
original_request: Any = None # Original A2A request (for task pause/resume in OAuth2 flows)
|
|
@@ -231,6 +231,32 @@ class ArtifactServiceConfig(SamConfigBase):
|
|
|
231
231
|
return self
|
|
232
232
|
|
|
233
233
|
|
|
234
|
+
class AgentIdentityConfig(SamConfigBase):
|
|
235
|
+
"""Configuration for agent identity and key management."""
|
|
236
|
+
|
|
237
|
+
key_mode: Literal["auto", "manual"] = Field(
|
|
238
|
+
default="auto",
|
|
239
|
+
description="Key mode for agent identity: 'auto' for automatic generation, 'manual' for user-provided.",
|
|
240
|
+
)
|
|
241
|
+
key_identity: Optional[str] = Field(
|
|
242
|
+
default=None, description="Actual key value when key_mode is 'manual'."
|
|
243
|
+
)
|
|
244
|
+
key_persistence: Optional[str] = Field(
|
|
245
|
+
default=None,
|
|
246
|
+
description="Path to the key file, e.g. '/path/to/keys/agent_{name}.key'.",
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
@model_validator(mode="after")
|
|
250
|
+
def check_key_mode_and_identity(self) -> "AgentIdentityConfig":
|
|
251
|
+
if self.key_mode == "manual" and not self.key_identity:
|
|
252
|
+
raise ValueError("'key_identity' is required when 'key_mode' is 'manual'.")
|
|
253
|
+
if self.key_mode == "auto" and self.key_identity:
|
|
254
|
+
log.warning(
|
|
255
|
+
"Configuration Warning: 'key_identity' is ignored when 'key_mode' is 'auto'."
|
|
256
|
+
)
|
|
257
|
+
return self
|
|
258
|
+
|
|
259
|
+
|
|
234
260
|
class SessionServiceConfig(SamConfigBase):
|
|
235
261
|
"""Configuration for the ADK Session Service."""
|
|
236
262
|
|
|
@@ -245,6 +271,12 @@ class SessionServiceConfig(SamConfigBase):
|
|
|
245
271
|
)
|
|
246
272
|
|
|
247
273
|
|
|
274
|
+
class CredentialServiceConfig(SamConfigBase):
|
|
275
|
+
"""Configuration for the ADK Credential Service."""
|
|
276
|
+
|
|
277
|
+
type: str = Field(..., description="Service type (e.g., 'memory').")
|
|
278
|
+
|
|
279
|
+
|
|
248
280
|
class SamAgentAppConfig(SamConfigBase):
|
|
249
281
|
"""Pydantic model for the complete agent application configuration."""
|
|
250
282
|
|
|
@@ -264,6 +296,10 @@ class SamAgentAppConfig(SamConfigBase):
|
|
|
264
296
|
model: Union[str, Dict[str, Any]] = Field(
|
|
265
297
|
..., description="ADK model name (string) or BaseLlm config dict."
|
|
266
298
|
)
|
|
299
|
+
agent_identity: Optional[AgentIdentityConfig] = Field(
|
|
300
|
+
default_factory=lambda: AgentIdentityConfig(key_mode="auto"),
|
|
301
|
+
description="Configuration for agent identity and key management.",
|
|
302
|
+
)
|
|
267
303
|
trust_manager: Optional[Union[TrustManagerConfig, Dict[str, Any]]] = Field(
|
|
268
304
|
default=None,
|
|
269
305
|
description="Configuration for the Trust Manager (enterprise feature)",
|
|
@@ -306,6 +342,10 @@ class SamAgentAppConfig(SamConfigBase):
|
|
|
306
342
|
default={"type": "memory"},
|
|
307
343
|
description="Configuration for ADK Memory Service (defaults to memory).",
|
|
308
344
|
)
|
|
345
|
+
credential_service: Optional[CredentialServiceConfig] = Field(
|
|
346
|
+
default=None,
|
|
347
|
+
description="Configuration for ADK Credential Service (optional).",
|
|
348
|
+
)
|
|
309
349
|
multi_session_request_response: Dict[str, Any] = Field(
|
|
310
350
|
default_factory=lambda: {"enabled": True},
|
|
311
351
|
description="Enables multi-session request/response capabilities for the agent, required for peer delegation.",
|
|
@@ -335,6 +375,12 @@ class SamAgentAppConfig(SamConfigBase):
|
|
|
335
375
|
ge=0,
|
|
336
376
|
description="Maximum number of dictionary keys to inspect during schema inference.",
|
|
337
377
|
)
|
|
378
|
+
schema_inference_depth: int = Field(
|
|
379
|
+
default=4,
|
|
380
|
+
ge=1,
|
|
381
|
+
le=10,
|
|
382
|
+
description="Maximum depth for schema inference on nested structures. Higher values reveal more nested field names but increase metadata size.",
|
|
383
|
+
)
|
|
338
384
|
enable_embed_resolution: bool = Field(
|
|
339
385
|
default=True,
|
|
340
386
|
description="Enable early-stage processing of dynamic embeds and inject related instructions.",
|
|
@@ -344,7 +390,7 @@ class SamAgentAppConfig(SamConfigBase):
|
|
|
344
390
|
description="If true, automatically attempts to continue LLM generation if it is interrupted by a token limit.",
|
|
345
391
|
)
|
|
346
392
|
stream_batching_threshold_bytes: int = Field(
|
|
347
|
-
default=
|
|
393
|
+
default=100,
|
|
348
394
|
description="Minimum size in bytes for accumulated text from LLM stream before sending a status update.",
|
|
349
395
|
)
|
|
350
396
|
max_message_size_bytes: int = Field(
|
|
@@ -436,8 +482,11 @@ class SamAgentApp(App):
|
|
|
436
482
|
# Overwrite the raw dict with the validated object for downstream use
|
|
437
483
|
app_info["app_config"] = app_config
|
|
438
484
|
except ValidationError as e:
|
|
439
|
-
|
|
440
|
-
|
|
485
|
+
message = SamAgentAppConfig.format_validation_error_message(
|
|
486
|
+
e, app_info["name"], app_config_dict.get("agent_name")
|
|
487
|
+
)
|
|
488
|
+
log.error("Invalid Agent configuration:\n%s", message)
|
|
489
|
+
raise
|
|
441
490
|
|
|
442
491
|
# The rest of the method can now safely use .get() on the app_config object,
|
|
443
492
|
# ensuring full backward compatibility.
|
|
@@ -510,3 +559,42 @@ class SamAgentApp(App):
|
|
|
510
559
|
|
|
511
560
|
super().__init__(app_info, **kwargs)
|
|
512
561
|
log.debug("%s Agent initialization complete.", agent_name)
|
|
562
|
+
|
|
563
|
+
def run(self):
|
|
564
|
+
"""
|
|
565
|
+
Override run to ensure component initialization failures cause application failure.
|
|
566
|
+
|
|
567
|
+
This is critical for containerized deployments where the process must exit with
|
|
568
|
+
a non-zero code if initialization fails. By re-raising the exception, we allow
|
|
569
|
+
the SAC framework's main() to handle cleanup (component.cleanup(), broker
|
|
570
|
+
disconnection, etc.) before exiting with code 1.
|
|
571
|
+
"""
|
|
572
|
+
try:
|
|
573
|
+
super().run()
|
|
574
|
+
except Exception as e:
|
|
575
|
+
log.critical(
|
|
576
|
+
"Failed to start agent application '%s': %s", self.name, e, exc_info=e
|
|
577
|
+
)
|
|
578
|
+
raise
|
|
579
|
+
|
|
580
|
+
def get_component(self, component_name: str = None) -> "SamAgentComponent":
|
|
581
|
+
"""
|
|
582
|
+
Retrieves the running SamAgentComponent instance from the app's flow.
|
|
583
|
+
|
|
584
|
+
Args:
|
|
585
|
+
component_name: Optional component name (for compatibility, but ignored since there's only one component)
|
|
586
|
+
|
|
587
|
+
Returns:
|
|
588
|
+
The SamAgentComponent instance or None if not found
|
|
589
|
+
"""
|
|
590
|
+
if self.flows and self.flows[0].component_groups:
|
|
591
|
+
for group in self.flows[0].component_groups:
|
|
592
|
+
for component_wrapper in group:
|
|
593
|
+
component = (
|
|
594
|
+
component_wrapper.component
|
|
595
|
+
if hasattr(component_wrapper, "component")
|
|
596
|
+
else component_wrapper
|
|
597
|
+
)
|
|
598
|
+
if isinstance(component, SamAgentComponent):
|
|
599
|
+
return component
|
|
600
|
+
return None
|