solace-agent-mesh 1.5.0__py3-none-any.whl → 1.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of solace-agent-mesh might be problematic. Click here for more details.
- solace_agent_mesh/agent/adk/callbacks.py +14 -17
- solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +3 -1
- solace_agent_mesh/agent/adk/intelligent_mcp_callbacks.py +2 -1
- solace_agent_mesh/agent/adk/mcp_content_processor.py +2 -1
- solace_agent_mesh/agent/adk/models/lite_llm.py +123 -8
- solace_agent_mesh/agent/adk/models/oauth2_token_manager.py +245 -0
- solace_agent_mesh/agent/adk/runner.py +3 -1
- solace_agent_mesh/agent/adk/services.py +4 -1
- solace_agent_mesh/agent/adk/setup.py +3 -1
- solace_agent_mesh/agent/adk/tool_wrapper.py +2 -2
- solace_agent_mesh/agent/protocol/event_handlers.py +42 -2
- solace_agent_mesh/agent/proxies/__init__.py +0 -0
- solace_agent_mesh/agent/proxies/a2a/__init__.py +3 -0
- solace_agent_mesh/agent/proxies/a2a/app.py +55 -0
- solace_agent_mesh/agent/proxies/a2a/component.py +1115 -0
- solace_agent_mesh/agent/proxies/a2a/config.py +140 -0
- solace_agent_mesh/agent/proxies/a2a/oauth_token_cache.py +104 -0
- solace_agent_mesh/agent/proxies/base/__init__.py +3 -0
- solace_agent_mesh/agent/proxies/base/app.py +99 -0
- solace_agent_mesh/agent/proxies/base/component.py +619 -0
- solace_agent_mesh/agent/proxies/base/config.py +85 -0
- solace_agent_mesh/agent/proxies/base/proxy_task_context.py +17 -0
- solace_agent_mesh/agent/sac/app.py +12 -4
- solace_agent_mesh/agent/sac/component.py +164 -9
- solace_agent_mesh/agent/tools/audio_tools.py +127 -9
- solace_agent_mesh/agent/tools/builtin_artifact_tools.py +3 -1
- solace_agent_mesh/agent/tools/builtin_data_analysis_tools.py +3 -1
- solace_agent_mesh/agent/tools/dynamic_tool.py +2 -1
- solace_agent_mesh/agent/tools/general_agent_tools.py +2 -1
- solace_agent_mesh/agent/tools/image_tools.py +2 -1
- solace_agent_mesh/agent/tools/peer_agent_tool.py +2 -1
- solace_agent_mesh/agent/tools/registry.py +3 -1
- solace_agent_mesh/agent/tools/test_tools.py +2 -1
- solace_agent_mesh/agent/tools/web_tools.py +12 -6
- solace_agent_mesh/agent/utils/artifact_helpers.py +144 -4
- solace_agent_mesh/agent/utils/config_parser.py +3 -1
- solace_agent_mesh/assets/docs/404.html +3 -3
- solace_agent_mesh/assets/docs/assets/js/{b7006a3a.73a79653.js → 032c2d61.f3d37824.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/0bcf40b7.c019ad46.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/15ba94aa.932dd2db.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2131ec11.5c7a1f6e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{2334.622a6395.js → 2334.1cf50a20.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/240a0364.7eac6021.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2e32b5e0.33f5d75b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/341393d4.0fac2613.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{3624.b524e433.js → 3624.0eaa1fd0.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/3a6c6137.f5940cfa.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ac1795d.76654dd9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ff0015d.2be20244.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/509e993c.4c7a1a6d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/547e15cc.2cbb060a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/55b7b518.f2b1d1ba.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.eda4bcb2.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6063ff4c.ef84f702.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/631738c7.a8b1ef8b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6a520c9d.ba015d81.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.f4b15f3b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6d84eae0.4a5fbf39.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6fdfefc7.99de744e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/71da7b71.38583438.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/722f809d.965da774.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/742f027b.46c07808.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/77cf947d.48cb18a2.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8024126c.56e59919.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/81a99df0.07034dd9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/82fbfb93.139a1a1f.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{8591.d7c16be6.js → 8591.5d015485.js} +2 -2
- solace_agent_mesh/assets/docs/assets/js/{8731.49e930c2.js → 8731.6c1dbf0c.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/924ffdeb.8095e148.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/945fb41e.6f4cdffd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/94e8668d.b5ddb7a1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9bb13469.dd1c9b54.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9e9d0a82.570c057b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ab9708a8.3e6dd091.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ad71b5ed.af3ecfd1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/c198a0dc.8f31f867.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/c93cbaa0.eaff365e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ceb2a7a6.5d92d7d0.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/da0b5bad.d08a9466.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/db924877.e98d12a1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/dd817ffc.0aa9630a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/dd81e2b8.d590bc9e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/de5f4c65.e8241890.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/de915948.27d6b065.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e3d9abda.2b916f9e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e6f9706b.e74a984d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e92d0134.cf6d6522.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f284c35a.42f59cdd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ff4d71f2.15b02f97.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.20feee82.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.0d198646.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +154 -0
- solace_agent_mesh/assets/docs/docs/documentation/{user-guide → components}/builtin-tools/artifact-management/index.html +7 -7
- solace_agent_mesh/assets/docs/docs/documentation/{user-guide → components}/builtin-tools/audio-tools/index.html +7 -7
- solace_agent_mesh/assets/docs/docs/documentation/{user-guide → components}/builtin-tools/data-analysis-tools/index.html +8 -8
- solace_agent_mesh/assets/docs/docs/documentation/{user-guide → components}/builtin-tools/embeds/index.html +6 -6
- solace_agent_mesh/assets/docs/docs/documentation/{user-guide → components}/builtin-tools/index.html +11 -11
- solace_agent_mesh/assets/docs/docs/documentation/{concepts → components}/cli/index.html +25 -25
- solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +91 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/index.html +29 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +55 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +110 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/proxies/index.html +262 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +104 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +85 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +25 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +59 -0
- solace_agent_mesh/assets/docs/docs/documentation/{user-guide → developing}/create-agents/index.html +113 -152
- solace_agent_mesh/assets/docs/docs/documentation/{user-guide → developing}/create-gateways/index.html +10 -10
- solace_agent_mesh/assets/docs/docs/documentation/{user-guide → developing}/creating-python-tools/index.html +12 -12
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +54 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +135 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +34 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +55 -0
- solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/bedrock-agents/index.html +25 -25
- solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/custom-agent/index.html +13 -13
- solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/event-mesh-gateway/index.html +12 -12
- solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/mcp-integration/index.html +10 -10
- solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/mongodb-integration/index.html +13 -13
- solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/rag-integration/index.html +13 -13
- solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/rest-gateway/index.html +10 -10
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +72 -0
- solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/sql-database/index.html +14 -14
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +33 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +83 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +222 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +161 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/architecture/index.html +75 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +53 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +35 -100
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +41 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +81 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +25 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +76 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +160 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +142 -0
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-gateway-upgrade-to-0.3.0/index.html +100 -0
- solace_agent_mesh/assets/docs/docs/documentation/{Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map/index.html → migrations/a2a-upgrade/a2a-technical-migration-map/index.html} +10 -11
- solace_agent_mesh/assets/docs/img/solace-logo.png +0 -0
- solace_agent_mesh/assets/docs/lunr-index-1761165361160.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1761165361160.json +1 -0
- solace_agent_mesh/assets/docs/search-doc.json +1 -1
- solace_agent_mesh/assets/docs/sitemap.xml +1 -1
- solace_agent_mesh/cli/__init__.py +1 -1
- solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +2 -69
- solace_agent_mesh/cli/commands/eval_cmd.py +11 -49
- solace_agent_mesh/cli/commands/init_cmd/__init__.py +0 -5
- solace_agent_mesh/cli/commands/init_cmd/env_step.py +10 -12
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +9 -61
- solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +9 -49
- solace_agent_mesh/cli/commands/plugin_cmd/add_cmd.py +1 -2
- solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-DwrxZE0E.js → authCallback-BTf6dqwp.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/{client-DarGQzyw.js → client-CaY59VuC.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-BGTaW0uv.js +342 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-DHJKSW1S.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/{vendor-BKIeiHj_.js → vendor-BEmvJSYz.js} +1 -1
- 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/__init__.py +24 -0
- solace_agent_mesh/common/a2a/artifact.py +41 -1
- solace_agent_mesh/common/a2a/events.py +29 -0
- solace_agent_mesh/common/a2a/message.py +68 -0
- solace_agent_mesh/common/a2a/protocol.py +76 -3
- solace_agent_mesh/common/a2a/translation.py +3 -1
- solace_agent_mesh/common/agent_registry.py +83 -3
- solace_agent_mesh/common/constants.py +3 -1
- solace_agent_mesh/common/middleware/config_resolver.py +3 -1
- solace_agent_mesh/common/middleware/registry.py +3 -1
- solace_agent_mesh/common/sac/sam_component_base.py +2 -1
- solace_agent_mesh/common/sam_events/event_service.py +3 -2
- solace_agent_mesh/common/services/employee_service.py +3 -1
- solace_agent_mesh/common/services/identity_service.py +2 -1
- solace_agent_mesh/common/services/providers/local_file_identity_service.py +2 -1
- solace_agent_mesh/common/utils/artifact_utils.py +3 -1
- solace_agent_mesh/common/utils/asyncio_macos_fix.py +3 -1
- solace_agent_mesh/common/utils/embeds/converter.py +3 -1
- solace_agent_mesh/common/utils/embeds/evaluators.py +2 -1
- solace_agent_mesh/common/utils/embeds/modifiers.py +3 -2
- solace_agent_mesh/common/utils/embeds/resolver.py +2 -1
- solace_agent_mesh/common/utils/initializer.py +3 -1
- solace_agent_mesh/common/utils/message_utils.py +2 -1
- solace_agent_mesh/common/utils/push_notification_auth.py +3 -2
- solace_agent_mesh/common/utils/pydantic_utils.py +12 -0
- solace_agent_mesh/config_portal/backend/common.py +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-ByU1X1HD.js +98 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/{manifest-44d62be6.js → manifest-61038fc6.js} +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/index.html +1 -1
- solace_agent_mesh/core_a2a/service.py +2 -2
- solace_agent_mesh/evaluation/evaluator.py +128 -104
- solace_agent_mesh/evaluation/message_organizer.py +116 -110
- solace_agent_mesh/evaluation/report_data_processor.py +84 -86
- solace_agent_mesh/evaluation/report_generator.py +73 -79
- solace_agent_mesh/evaluation/run.py +421 -235
- solace_agent_mesh/evaluation/shared/__init__.py +92 -0
- solace_agent_mesh/evaluation/shared/constants.py +47 -0
- solace_agent_mesh/evaluation/shared/exceptions.py +50 -0
- solace_agent_mesh/evaluation/shared/helpers.py +35 -0
- solace_agent_mesh/evaluation/shared/test_case_loader.py +167 -0
- solace_agent_mesh/evaluation/shared/test_suite_loader.py +280 -0
- solace_agent_mesh/evaluation/subscriber.py +111 -232
- solace_agent_mesh/evaluation/summary_builder.py +227 -117
- solace_agent_mesh/gateway/base/app.py +3 -2
- solace_agent_mesh/gateway/base/component.py +11 -2
- solace_agent_mesh/gateway/base/task_context.py +2 -1
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251015_add_session_performance_indexes.py +70 -0
- solace_agent_mesh/gateway/http_sse/app.py +2 -1
- solace_agent_mesh/gateway/http_sse/component.py +102 -3
- solace_agent_mesh/gateway/http_sse/components/task_logger_forwarder.py +3 -2
- solace_agent_mesh/gateway/http_sse/components/visualization_forwarder_component.py +3 -1
- solace_agent_mesh/gateway/http_sse/dependencies.py +7 -5
- solace_agent_mesh/gateway/http_sse/main.py +5 -2
- solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +12 -13
- solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +15 -18
- solace_agent_mesh/gateway/http_sse/repository/interfaces.py +25 -18
- solace_agent_mesh/gateway/http_sse/repository/session_repository.py +30 -26
- solace_agent_mesh/gateway/http_sse/repository/task_repository.py +35 -44
- solace_agent_mesh/gateway/http_sse/routers/agent_cards.py +7 -5
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +97 -205
- solace_agent_mesh/gateway/http_sse/routers/auth.py +3 -1
- solace_agent_mesh/gateway/http_sse/routers/config.py +3 -2
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +4 -3
- solace_agent_mesh/gateway/http_sse/routers/people.py +3 -1
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +5 -3
- solace_agent_mesh/gateway/http_sse/routers/sse.py +3 -2
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +35 -42
- solace_agent_mesh/gateway/http_sse/routers/users.py +3 -1
- solace_agent_mesh/gateway/http_sse/routers/visualization.py +19 -12
- solace_agent_mesh/gateway/http_sse/services/agent_card_service.py +3 -1
- solace_agent_mesh/gateway/http_sse/services/data_retention_service.py +6 -5
- solace_agent_mesh/gateway/http_sse/services/feedback_service.py +53 -44
- solace_agent_mesh/gateway/http_sse/services/people_service.py +2 -2
- solace_agent_mesh/gateway/http_sse/services/session_service.py +23 -21
- solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +10 -9
- solace_agent_mesh/gateway/http_sse/services/task_service.py +3 -2
- solace_agent_mesh/gateway/http_sse/session_manager.py +2 -1
- solace_agent_mesh/gateway/http_sse/shared/base_repository.py +45 -71
- solace_agent_mesh/gateway/http_sse/shared/types.py +0 -18
- solace_agent_mesh/gateway/http_sse/sse_event_buffer.py +2 -1
- solace_agent_mesh/gateway/http_sse/sse_manager.py +2 -2
- solace_agent_mesh/templates/gateway_app_template.py +4 -2
- solace_agent_mesh/templates/gateway_component_template.py +3 -1
- solace_agent_mesh/templates/gateway_config_template.yaml +0 -5
- solace_agent_mesh/templates/logging_config_template.ini +27 -46
- solace_agent_mesh/templates/plugin_gateway_config_template.yaml +0 -3
- solace_agent_mesh/templates/plugin_tools_template.py +2 -2
- solace_agent_mesh/templates/shared_config.yaml +40 -0
- {solace_agent_mesh-1.5.0.dist-info → solace_agent_mesh-1.6.0.dist-info}/METADATA +47 -21
- {solace_agent_mesh-1.5.0.dist-info → solace_agent_mesh-1.6.0.dist-info}/RECORD +254 -225
- solace_agent_mesh/assets/docs/assets/images/sac-flows-80d5b603c6aafd33e87945680ce0abf3.png +0 -0
- solace_agent_mesh/assets/docs/assets/images/sac_parts_of_a_component-cb3d0424b1d0c17734c5435cca6b4082.png +0 -0
- solace_agent_mesh/assets/docs/assets/js/04989206.a248f00c.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/0e682baa.d54b8668.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/1023fc19.8a8a9309.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/1523c6b4.2645ef68.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/166ab619.e27886d9.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/1c6e87d2.e056b7e0.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/21ceee5f.3bf39250.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/2a9cab12.2afaee76.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/332e10b5.f7629851.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/3d406171.5560fdf9.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/42b3f8d8.508ae8db.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/442a8107.b5c2532a.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/453a82a6.3c6bb61d.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/483cef9a.bf9398af.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/4c2787c2.c1290a40.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/55f47984.bcd00a86.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/5b4258a4.fdfd2325.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/664b740a.ba305a89.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/75384d09.c19e8b51.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/768e31b0.9abcdc48.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/85387663.be2bc838.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/945fb41e.16e00776.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/9a09e75d.92de8cf5.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/9eff14a2.d62aad71.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/a12a4955.25fbed32.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/a3a92b25.af35e313.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/aba87c2f.4ddf32f2.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/ae0e903d.5fe5203f.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/ae4415af.16cc58d3.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/bac0be12.17de4316.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/c2c06897.87cb1f47.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/c835a94d.ce21f0bf.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/cc969b05.feef7dcc.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/cd3d4052.a19e7d78.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/ced92a13.fb92e7ca.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/cee5d587.47904f5e.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/d6a81ee7.829198f1.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f284c35a.ed8dd236.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f897a61a.126663fe.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/fbfa3e75.e144b16c.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/main.0c149855.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.c66557e4.js +0 -1
- solace_agent_mesh/assets/docs/docs/documentation/Enterprise/installation/index.html +0 -46
- solace_agent_mesh/assets/docs/docs/documentation/Enterprise/rbac-setup-guilde/index.html +0 -201
- solace_agent_mesh/assets/docs/docs/documentation/Enterprise/single-sign-on/index.html +0 -29
- solace_agent_mesh/assets/docs/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0/index.html +0 -105
- solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +0 -144
- solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +0 -91
- solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +0 -91
- solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +0 -55
- solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +0 -111
- solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +0 -77
- solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +0 -48
- solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +0 -54
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +0 -45
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/index.html +0 -74
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/litellm_models/index.html +0 -49
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +0 -76
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +0 -73
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +0 -72
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +0 -54
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +0 -69
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +0 -59
- solace_agent_mesh/assets/docs/lunr-index-1760032255022.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1760032255022.json +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-CZbpmwfA.css +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-C__uuUkB.js +0 -339
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-BNuqpWDc.js +0 -98
- solace_agent_mesh/evaluation/config_loader.py +0 -657
- solace_agent_mesh/evaluation/test_case_loader.py +0 -714
- /solace_agent_mesh/assets/docs/assets/js/{8591.d7c16be6.js.LICENSE.txt → 8591.5d015485.js.LICENSE.txt} +0 -0
- /solace_agent_mesh/assets/docs/assets/js/{main.0c149855.js.LICENSE.txt → main.20feee82.js.LICENSE.txt} +0 -0
- {solace_agent_mesh-1.5.0.dist-info → solace_agent_mesh-1.6.0.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.5.0.dist-info → solace_agent_mesh-1.6.0.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.5.0.dist-info → solace_agent_mesh-1.6.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pydantic configuration models for proxy applications.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import List, Literal, Optional
|
|
6
|
+
|
|
7
|
+
from pydantic import Field, model_validator
|
|
8
|
+
|
|
9
|
+
from ....common.utils.pydantic_utils import SamConfigBase
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ArtifactServiceConfig(SamConfigBase):
|
|
13
|
+
"""Configuration for the shared Artifact Service."""
|
|
14
|
+
|
|
15
|
+
type: str = Field(
|
|
16
|
+
..., description="Service type (e.g., 'memory', 'gcs', 'filesystem')."
|
|
17
|
+
)
|
|
18
|
+
base_path: Optional[str] = Field(
|
|
19
|
+
default=None,
|
|
20
|
+
description="Base directory path (required for type 'filesystem').",
|
|
21
|
+
)
|
|
22
|
+
bucket_name: Optional[str] = Field(
|
|
23
|
+
default=None, description="GCS bucket name (required for type 'gcs')."
|
|
24
|
+
)
|
|
25
|
+
artifact_scope: Literal["namespace", "app", "custom"] = Field(
|
|
26
|
+
default="namespace", description="Process-wide scope for all artifact services."
|
|
27
|
+
)
|
|
28
|
+
artifact_scope_value: Optional[str] = Field(
|
|
29
|
+
default=None,
|
|
30
|
+
description="Custom identifier for artifact scope (required if artifact_scope is 'custom').",
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
@model_validator(mode="after")
|
|
34
|
+
def check_artifact_scope(self) -> "ArtifactServiceConfig":
|
|
35
|
+
if self.artifact_scope == "custom" and not self.artifact_scope_value:
|
|
36
|
+
raise ValueError(
|
|
37
|
+
"'artifact_scope_value' is required when 'artifact_scope' is 'custom'."
|
|
38
|
+
)
|
|
39
|
+
if self.artifact_scope != "custom" and self.artifact_scope_value:
|
|
40
|
+
from solace_ai_connector.common.log import log
|
|
41
|
+
log.warning(
|
|
42
|
+
"Configuration Warning: 'artifact_scope_value' is ignored when 'artifact_scope' is not 'custom'."
|
|
43
|
+
)
|
|
44
|
+
return self
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class ProxiedAgentConfig(SamConfigBase):
|
|
48
|
+
"""Base configuration for a proxied agent."""
|
|
49
|
+
|
|
50
|
+
name: str = Field(
|
|
51
|
+
...,
|
|
52
|
+
description="The name the agent will have on the Solace mesh.",
|
|
53
|
+
)
|
|
54
|
+
request_timeout_seconds: Optional[int] = Field(
|
|
55
|
+
default=None,
|
|
56
|
+
description="Optional timeout override for this specific agent.",
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class BaseProxyAppConfig(SamConfigBase):
|
|
61
|
+
"""Base configuration for all proxy applications."""
|
|
62
|
+
|
|
63
|
+
namespace: str = Field(
|
|
64
|
+
...,
|
|
65
|
+
description="Absolute topic prefix for A2A communication (e.g., 'myorg/dev').",
|
|
66
|
+
)
|
|
67
|
+
proxied_agents: List[ProxiedAgentConfig] = Field(
|
|
68
|
+
...,
|
|
69
|
+
min_length=1,
|
|
70
|
+
description="A list of downstream agents to be proxied.",
|
|
71
|
+
)
|
|
72
|
+
artifact_service: ArtifactServiceConfig = Field(
|
|
73
|
+
default_factory=lambda: ArtifactServiceConfig(type="memory"),
|
|
74
|
+
description="Configuration for the shared Artifact Service.",
|
|
75
|
+
)
|
|
76
|
+
discovery_interval_seconds: int = Field(
|
|
77
|
+
default=60,
|
|
78
|
+
ge=0,
|
|
79
|
+
description="Interval (seconds) to re-fetch agent cards. <= 0 disables periodic discovery.",
|
|
80
|
+
)
|
|
81
|
+
default_request_timeout_seconds: int = Field(
|
|
82
|
+
default=300,
|
|
83
|
+
gt=0,
|
|
84
|
+
description="Default timeout in seconds for requests to downstream agents.",
|
|
85
|
+
)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Encapsulates the runtime state for a single, in-flight proxied agent task.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Any, Dict
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass
|
|
10
|
+
class ProxyTaskContext:
|
|
11
|
+
"""
|
|
12
|
+
A class to hold all runtime state and control mechanisms for a single proxied agent task.
|
|
13
|
+
This object is created when a task is initiated and destroyed when it completes.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
task_id: str
|
|
17
|
+
a2a_context: Dict[str, Any]
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
import sys
|
|
2
3
|
import os
|
|
3
4
|
|
|
@@ -7,7 +8,6 @@ sys.path.insert(
|
|
|
7
8
|
|
|
8
9
|
from common.utils.asyncio_macos_fix import ensure_asyncio_compatibility
|
|
9
10
|
from .patch_adk import patch_adk
|
|
10
|
-
from solace_ai_connector.common.log import log
|
|
11
11
|
|
|
12
12
|
ensure_asyncio_compatibility()
|
|
13
13
|
patch_adk()
|
|
@@ -23,12 +23,14 @@ from ...common.a2a import (
|
|
|
23
23
|
get_agent_status_subscription_topic,
|
|
24
24
|
get_sam_events_subscription_topic,
|
|
25
25
|
)
|
|
26
|
-
from ...common.constants import DEFAULT_COMMUNICATION_TIMEOUT, TEXT_ARTIFACT_CONTEXT_MAX_LENGTH_CAPACITY, TEXT_ARTIFACT_CONTEXT_DEFAULT_LENGTH
|
|
26
|
+
from ...common.constants import DEFAULT_COMMUNICATION_TIMEOUT, TEXT_ARTIFACT_CONTEXT_MAX_LENGTH_CAPACITY, TEXT_ARTIFACT_CONTEXT_DEFAULT_LENGTH, HEALTH_CHECK_TTL_SECONDS, HEALTH_CHECK_INTERVAL_SECONDS
|
|
27
27
|
from ...agent.sac.component import SamAgentComponent
|
|
28
28
|
from ...agent.utils.artifact_helpers import DEFAULT_SCHEMA_MAX_KEYS
|
|
29
29
|
from ...common.utils.pydantic_utils import SamConfigBase
|
|
30
30
|
from ..tools.tool_config_types import AnyToolConfig
|
|
31
31
|
|
|
32
|
+
log = logging.getLogger(__name__)
|
|
33
|
+
|
|
32
34
|
info = {
|
|
33
35
|
"class_name": "SamAgentApp",
|
|
34
36
|
"description": "Custom App class for SAM Agent Host with namespace prefixing and automatic subscription generation.",
|
|
@@ -77,6 +79,12 @@ class AgentDiscoveryConfig(SamConfigBase):
|
|
|
77
79
|
enabled: bool = Field(
|
|
78
80
|
default=True, description="Enable discovery and instruction injection."
|
|
79
81
|
)
|
|
82
|
+
health_check_ttl_seconds: int = Field(
|
|
83
|
+
default=HEALTH_CHECK_TTL_SECONDS, description="Time-to-live in seconds after which an unresponsive agent is de-registered."
|
|
84
|
+
)
|
|
85
|
+
health_check_interval_seconds: int = Field(
|
|
86
|
+
default=HEALTH_CHECK_INTERVAL_SECONDS, description="Interval in seconds between health checks."
|
|
87
|
+
)
|
|
80
88
|
|
|
81
89
|
|
|
82
90
|
class InterAgentCommunicationConfig(SamConfigBase):
|
|
@@ -450,8 +458,8 @@ class SamAgentApp(App):
|
|
|
450
458
|
broker_config["queue_name"] = generated_queue_name
|
|
451
459
|
log.debug("Injected generated broker.queue_name: %s", generated_queue_name)
|
|
452
460
|
|
|
453
|
-
broker_config["temporary_queue"] = True
|
|
454
|
-
log.debug("Set broker_config.temporary_queue =
|
|
461
|
+
broker_config["temporary_queue"] = app_info.get("broker", {}).get("temporary_queue", True)
|
|
462
|
+
log.debug("Set broker_config.temporary_queue = %s", broker_config["temporary_queue"])
|
|
455
463
|
|
|
456
464
|
super().__init__(app_info, **kwargs)
|
|
457
465
|
log.debug("%s Agent initialization complete.", agent_name)
|
|
@@ -2,21 +2,20 @@
|
|
|
2
2
|
Custom Solace AI Connector Component to Host Google ADK Agents via A2A Protocol.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
import logging
|
|
5
6
|
from typing import Any, Dict, Optional, Union, Callable, List, Tuple, TYPE_CHECKING
|
|
6
7
|
import asyncio
|
|
7
8
|
import functools
|
|
8
9
|
import threading
|
|
9
10
|
import concurrent.futures
|
|
10
|
-
import uuid
|
|
11
11
|
import fnmatch
|
|
12
|
-
import
|
|
13
|
-
from datetime import datetime, timezone
|
|
12
|
+
import time
|
|
14
13
|
import json
|
|
15
14
|
from solace_ai_connector.common.message import (
|
|
16
15
|
Message as SolaceMessage,
|
|
17
16
|
)
|
|
18
|
-
from solace_ai_connector.common.log import log
|
|
19
17
|
from solace_ai_connector.common.event import Event, EventType
|
|
18
|
+
|
|
20
19
|
from solace_ai_connector.common.utils import import_module
|
|
21
20
|
import inspect
|
|
22
21
|
from pydantic import BaseModel, ValidationError
|
|
@@ -72,9 +71,12 @@ from ...agent.tools.peer_agent_tool import (
|
|
|
72
71
|
PEER_TOOL_PREFIX,
|
|
73
72
|
)
|
|
74
73
|
from ...common.middleware.registry import MiddlewareRegistry
|
|
75
|
-
from ...common.constants import DEFAULT_COMMUNICATION_TIMEOUT
|
|
74
|
+
from ...common.constants import DEFAULT_COMMUNICATION_TIMEOUT, HEALTH_CHECK_TTL_SECONDS, HEALTH_CHECK_INTERVAL_SECONDS
|
|
76
75
|
from ...agent.tools.registry import tool_registry
|
|
77
76
|
from ...common.sac.sam_component_base import SamComponentBase
|
|
77
|
+
from ...common.agent_registry import AgentRegistry
|
|
78
|
+
|
|
79
|
+
log = logging.getLogger(__name__)
|
|
78
80
|
|
|
79
81
|
if TYPE_CHECKING:
|
|
80
82
|
from .app import AgentInitCleanupConfig
|
|
@@ -110,6 +112,7 @@ class SamAgentComponent(SamComponentBase):
|
|
|
110
112
|
|
|
111
113
|
CORRELATION_DATA_PREFIX = CORRELATION_DATA_PREFIX
|
|
112
114
|
HOST_COMPONENT_VERSION = "1.0.0-alpha"
|
|
115
|
+
HEALTH_CHECK_TIMER_ID = "agent_health_check"
|
|
113
116
|
|
|
114
117
|
def __init__(self, **kwargs):
|
|
115
118
|
"""
|
|
@@ -126,6 +129,9 @@ class SamAgentComponent(SamComponentBase):
|
|
|
126
129
|
super().__init__(info, **kwargs)
|
|
127
130
|
self.agent_name = self.get_config("agent_name")
|
|
128
131
|
log.info("%s Initializing A2A ADK Host Component...", self.log_identifier)
|
|
132
|
+
|
|
133
|
+
# Initialize the agent registry for health tracking
|
|
134
|
+
self.agent_registry = AgentRegistry()
|
|
129
135
|
try:
|
|
130
136
|
self.namespace = self.get_config("namespace")
|
|
131
137
|
if not self.namespace:
|
|
@@ -234,7 +240,7 @@ class SamAgentComponent(SamComponentBase):
|
|
|
234
240
|
self.adk_agent: LlmAgent = None
|
|
235
241
|
self.runner: Runner = None
|
|
236
242
|
self.agent_card_tool_manifest: List[Dict[str, Any]] = []
|
|
237
|
-
self.peer_agents: Dict[str, Any] = {}
|
|
243
|
+
self.peer_agents: Dict[str, Any] = {} # Keep for backward compatibility
|
|
238
244
|
self._card_publish_timer_id: str = f"publish_card_{self.agent_name}"
|
|
239
245
|
self._async_init_future = None
|
|
240
246
|
self.peer_response_queues: Dict[str, asyncio.Queue] = {}
|
|
@@ -411,6 +417,26 @@ class SamAgentComponent(SamComponentBase):
|
|
|
411
417
|
"%s Agent card publishing interval not configured or invalid, card will not be published periodically.",
|
|
412
418
|
self.log_identifier,
|
|
413
419
|
)
|
|
420
|
+
|
|
421
|
+
# Set up health check timer if enabled
|
|
422
|
+
health_check_interval_seconds = self.agent_discovery_config.get("health_check_interval_seconds", HEALTH_CHECK_INTERVAL_SECONDS)
|
|
423
|
+
if health_check_interval_seconds > 0:
|
|
424
|
+
log.info(
|
|
425
|
+
"%s Scheduling agent health check every %d seconds.",
|
|
426
|
+
self.log_identifier,
|
|
427
|
+
health_check_interval_seconds,
|
|
428
|
+
)
|
|
429
|
+
self.add_timer(
|
|
430
|
+
delay_ms=health_check_interval_seconds * 1000,
|
|
431
|
+
timer_id=self.HEALTH_CHECK_TIMER_ID,
|
|
432
|
+
interval_ms=health_check_interval_seconds * 1000,
|
|
433
|
+
)
|
|
434
|
+
else:
|
|
435
|
+
log.warning(
|
|
436
|
+
"%s Agent health check interval not configured or invalid, health checks will not run periodically.",
|
|
437
|
+
self.log_identifier,
|
|
438
|
+
)
|
|
439
|
+
|
|
414
440
|
log.info(
|
|
415
441
|
"%s Initialization complete for agent: %s",
|
|
416
442
|
self.log_identifier,
|
|
@@ -485,10 +511,14 @@ class SamAgentComponent(SamComponentBase):
|
|
|
485
511
|
)
|
|
486
512
|
|
|
487
513
|
def handle_timer_event(self, timer_data: Dict[str, Any]):
|
|
488
|
-
"""Handles timer events
|
|
514
|
+
"""Handles timer events for agent card publishing and health checks."""
|
|
489
515
|
log.debug("%s Received timer event: %s", self.log_identifier, timer_data)
|
|
490
|
-
|
|
516
|
+
timer_id = timer_data.get("timer_id")
|
|
517
|
+
|
|
518
|
+
if timer_id == self._card_publish_timer_id:
|
|
491
519
|
publish_agent_card(self)
|
|
520
|
+
elif timer_id == self.HEALTH_CHECK_TIMER_ID:
|
|
521
|
+
self._check_agent_health()
|
|
492
522
|
|
|
493
523
|
async def handle_cache_expiry_event(self, cache_data: Dict[str, Any]):
|
|
494
524
|
"""
|
|
@@ -863,7 +893,8 @@ class SamAgentComponent(SamComponentBase):
|
|
|
863
893
|
peer_tools_to_add = []
|
|
864
894
|
allowed_peer_descriptions = []
|
|
865
895
|
|
|
866
|
-
|
|
896
|
+
# Sort peer agents alphabetically to ensure consistent tool ordering for prompt caching
|
|
897
|
+
for peer_name, agent_card in sorted(self.peer_agents.items()):
|
|
867
898
|
if not isinstance(agent_card, AgentCard) or peer_name == self_name:
|
|
868
899
|
continue
|
|
869
900
|
|
|
@@ -2988,6 +3019,7 @@ class SamAgentComponent(SamComponentBase):
|
|
|
2988
3019
|
"""Clean up resources on component shutdown."""
|
|
2989
3020
|
log.info("%s Cleaning up A2A ADK Host Component.", self.log_identifier)
|
|
2990
3021
|
self.cancel_timer(self._card_publish_timer_id)
|
|
3022
|
+
self.cancel_timer(self.HEALTH_CHECK_TIMER_ID)
|
|
2991
3023
|
|
|
2992
3024
|
cleanup_func_details = self.get_config("agent_cleanup_function")
|
|
2993
3025
|
|
|
@@ -3148,6 +3180,129 @@ class SamAgentComponent(SamComponentBase):
|
|
|
3148
3180
|
For now, using the agent name, but could be made more robust (e.g., hostname + agent name).
|
|
3149
3181
|
"""
|
|
3150
3182
|
return self.agent_name
|
|
3183
|
+
|
|
3184
|
+
def _check_agent_health(self):
|
|
3185
|
+
"""
|
|
3186
|
+
Checks the health of peer agents and de-registers unresponsive ones.
|
|
3187
|
+
This is called periodically by the health check timer.
|
|
3188
|
+
Uses TTL-based expiration to determine if an agent is unresponsive.
|
|
3189
|
+
"""
|
|
3190
|
+
|
|
3191
|
+
log.debug("%s Performing agent health check...", self.log_identifier)
|
|
3192
|
+
|
|
3193
|
+
ttl_seconds = self.agent_discovery_config.get("health_check_ttl_seconds", HEALTH_CHECK_TTL_SECONDS)
|
|
3194
|
+
health_check_interval = self.agent_discovery_config.get("health_check_interval_seconds", HEALTH_CHECK_INTERVAL_SECONDS)
|
|
3195
|
+
|
|
3196
|
+
log.debug(
|
|
3197
|
+
"%s Health check configuration: interval=%d seconds, TTL=%d seconds",
|
|
3198
|
+
self.log_identifier,
|
|
3199
|
+
health_check_interval,
|
|
3200
|
+
ttl_seconds
|
|
3201
|
+
)
|
|
3202
|
+
|
|
3203
|
+
# Validate configuration values
|
|
3204
|
+
if ttl_seconds <= 0 or health_check_interval <= 0 or ttl_seconds < health_check_interval:
|
|
3205
|
+
log.error(
|
|
3206
|
+
"%s agent_health_check_ttl_seconds (%d) and agent_health_check_interval_seconds (%d) must be positive and TTL must be greater than interval.",
|
|
3207
|
+
self.log_identifier,
|
|
3208
|
+
ttl_seconds,
|
|
3209
|
+
health_check_interval
|
|
3210
|
+
)
|
|
3211
|
+
raise ValueError(f"Invalid health check configuration. agent_health_check_ttl_seconds ({ttl_seconds}) and agent_health_check_interval_seconds ({health_check_interval}) must be positive and TTL must be greater than interval.")
|
|
3212
|
+
|
|
3213
|
+
# Get all agent names from the registry
|
|
3214
|
+
agent_names = self.agent_registry.get_agent_names()
|
|
3215
|
+
total_agents = len(agent_names)
|
|
3216
|
+
agents_to_deregister = []
|
|
3217
|
+
|
|
3218
|
+
log.debug("%s Checking health of %d peer agents", self.log_identifier, total_agents)
|
|
3219
|
+
|
|
3220
|
+
for agent_name in agent_names:
|
|
3221
|
+
# Skip our own agent
|
|
3222
|
+
if agent_name == self.agent_name:
|
|
3223
|
+
continue
|
|
3224
|
+
|
|
3225
|
+
# Check if the agent's TTL has expired
|
|
3226
|
+
is_expired, time_since_last_seen = self.agent_registry.check_ttl_expired(agent_name, ttl_seconds)
|
|
3227
|
+
|
|
3228
|
+
if is_expired:
|
|
3229
|
+
log.warning(
|
|
3230
|
+
"%s Agent '%s' TTL has expired. De-registering. Time since last seen: %d seconds (TTL: %d seconds)",
|
|
3231
|
+
self.log_identifier,
|
|
3232
|
+
agent_name,
|
|
3233
|
+
time_since_last_seen,
|
|
3234
|
+
ttl_seconds
|
|
3235
|
+
)
|
|
3236
|
+
agents_to_deregister.append(agent_name)
|
|
3237
|
+
|
|
3238
|
+
# De-register unresponsive agents
|
|
3239
|
+
for agent_name in agents_to_deregister:
|
|
3240
|
+
self._deregister_agent(agent_name)
|
|
3241
|
+
|
|
3242
|
+
log.debug(
|
|
3243
|
+
"%s Agent health check completed. Total agents: %d, De-registered: %d",
|
|
3244
|
+
self.log_identifier,
|
|
3245
|
+
total_agents,
|
|
3246
|
+
len(agents_to_deregister)
|
|
3247
|
+
)
|
|
3248
|
+
|
|
3249
|
+
def _deregister_agent(self, agent_name: str):
|
|
3250
|
+
"""
|
|
3251
|
+
De-registers an agent from the registry and publishes a de-registration event.
|
|
3252
|
+
"""
|
|
3253
|
+
# Remove from registry
|
|
3254
|
+
registry_removed = self.agent_registry.remove_agent(agent_name)
|
|
3255
|
+
|
|
3256
|
+
# Always remove from peer_agents regardless of registry result
|
|
3257
|
+
peer_removed = False
|
|
3258
|
+
if agent_name in self.peer_agents:
|
|
3259
|
+
del self.peer_agents[agent_name]
|
|
3260
|
+
peer_removed = True
|
|
3261
|
+
log.info(
|
|
3262
|
+
"%s Removed agent '%s' from peer_agents dictionary",
|
|
3263
|
+
self.log_identifier,
|
|
3264
|
+
agent_name
|
|
3265
|
+
)
|
|
3266
|
+
|
|
3267
|
+
# Publish de-registration event if agent was in either data structure
|
|
3268
|
+
if registry_removed or peer_removed:
|
|
3269
|
+
try:
|
|
3270
|
+
# Create a de-registration event topic
|
|
3271
|
+
namespace = self.get_config("namespace")
|
|
3272
|
+
deregistration_topic = f"{namespace}/a2a/events/agent/deregistered"
|
|
3273
|
+
|
|
3274
|
+
current_time = time.time()
|
|
3275
|
+
|
|
3276
|
+
# Create the payload
|
|
3277
|
+
deregistration_payload = {
|
|
3278
|
+
"event_type": "agent.deregistered",
|
|
3279
|
+
"agent_name": agent_name,
|
|
3280
|
+
"reason": "health_check_failure",
|
|
3281
|
+
"metadata": {
|
|
3282
|
+
"timestamp": current_time,
|
|
3283
|
+
"deregistered_by": self.agent_name
|
|
3284
|
+
}
|
|
3285
|
+
}
|
|
3286
|
+
|
|
3287
|
+
# Publish the event
|
|
3288
|
+
self.publish_a2a_message(
|
|
3289
|
+
payload=deregistration_payload,
|
|
3290
|
+
topic=deregistration_topic
|
|
3291
|
+
)
|
|
3292
|
+
|
|
3293
|
+
log.info(
|
|
3294
|
+
"%s Published de-registration event for agent '%s' to topic '%s'",
|
|
3295
|
+
self.log_identifier,
|
|
3296
|
+
agent_name,
|
|
3297
|
+
deregistration_topic
|
|
3298
|
+
)
|
|
3299
|
+
except Exception as e:
|
|
3300
|
+
log.error(
|
|
3301
|
+
"%s Failed to publish de-registration event for agent '%s': %s",
|
|
3302
|
+
self.log_identifier,
|
|
3303
|
+
agent_name,
|
|
3304
|
+
e
|
|
3305
|
+
)
|
|
3151
3306
|
|
|
3152
3307
|
async def _resolve_early_embeds_and_handle_signals(
|
|
3153
3308
|
self, raw_text: str, a2a_context: Dict
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Collection of Python tools for audio processing and text-to-speech generation.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
import logging
|
|
5
6
|
import asyncio
|
|
6
7
|
import inspect
|
|
7
8
|
import io
|
|
@@ -20,11 +21,11 @@ from google import genai
|
|
|
20
21
|
from google.genai import types as adk_types
|
|
21
22
|
from google.adk.tools import ToolContext
|
|
22
23
|
from pydub import AudioSegment
|
|
23
|
-
from solace_ai_connector.common.log import log
|
|
24
24
|
|
|
25
25
|
from ...agent.utils.artifact_helpers import (
|
|
26
26
|
load_artifact_content_or_metadata,
|
|
27
27
|
save_artifact_with_metadata,
|
|
28
|
+
ensure_correct_extension,
|
|
28
29
|
DEFAULT_SCHEMA_MAX_KEYS,
|
|
29
30
|
)
|
|
30
31
|
from ...agent.utils.context_helpers import get_original_session_id
|
|
@@ -32,6 +33,7 @@ from ...agent.utils.context_helpers import get_original_session_id
|
|
|
32
33
|
from .tool_definition import BuiltinTool
|
|
33
34
|
from .registry import tool_registry
|
|
34
35
|
|
|
36
|
+
log = logging.getLogger(__name__)
|
|
35
37
|
|
|
36
38
|
VOICE_TONE_MAPPING = {
|
|
37
39
|
"bright": ["Zephyr", "Autonoe"],
|
|
@@ -1209,14 +1211,18 @@ async def concatenate_audio(
|
|
|
1209
1211
|
|
|
1210
1212
|
async def transcribe_audio(
|
|
1211
1213
|
audio_filename: str,
|
|
1214
|
+
output_filename: Optional[str] = None,
|
|
1215
|
+
description: Optional[str] = None,
|
|
1212
1216
|
tool_context: ToolContext = None,
|
|
1213
1217
|
tool_config: Optional[Dict[str, Any]] = None,
|
|
1214
1218
|
) -> Dict[str, Any]:
|
|
1215
1219
|
"""
|
|
1216
|
-
Transcribes an audio recording
|
|
1220
|
+
Transcribes an audio recording and saves the transcription as a text artifact.
|
|
1217
1221
|
|
|
1218
1222
|
Args:
|
|
1219
1223
|
audio_filename: The filename (and optional :version) of the input audio artifact.
|
|
1224
|
+
output_filename: Optional filename for the transcription text file (without extension).
|
|
1225
|
+
description: Optional description of the transcription for metadata.
|
|
1220
1226
|
tool_context: The context provided by the ADK framework.
|
|
1221
1227
|
tool_config: Configuration dictionary containing model, api_base, api_key.
|
|
1222
1228
|
|
|
@@ -1224,9 +1230,10 @@ async def transcribe_audio(
|
|
|
1224
1230
|
A dictionary containing:
|
|
1225
1231
|
- "status": "success" or "error".
|
|
1226
1232
|
- "message": A descriptive message about the outcome.
|
|
1227
|
-
- "
|
|
1228
|
-
- "
|
|
1229
|
-
- "
|
|
1233
|
+
- "output_filename": The name of the saved transcription artifact.
|
|
1234
|
+
- "output_version": The version of the saved transcription artifact.
|
|
1235
|
+
- "audio_filename": The name of the input audio artifact.
|
|
1236
|
+
- "audio_version": The version of the input audio artifact.
|
|
1230
1237
|
"""
|
|
1231
1238
|
log_identifier = f"[AudioTools:transcribe_audio:{audio_filename}]"
|
|
1232
1239
|
if not tool_context:
|
|
@@ -1339,8 +1346,28 @@ async def transcribe_audio(
|
|
|
1339
1346
|
)
|
|
1340
1347
|
|
|
1341
1348
|
audio_bytes = audio_artifact_part.inline_data.data
|
|
1349
|
+
audio_mime_type = audio_artifact_part.inline_data.mime_type or "application/octet-stream"
|
|
1342
1350
|
log.debug(f"{log_identifier} Loaded audio artifact: {len(audio_bytes)} bytes")
|
|
1343
1351
|
|
|
1352
|
+
# Load source audio metadata to copy description
|
|
1353
|
+
source_audio_metadata = {}
|
|
1354
|
+
try:
|
|
1355
|
+
metadata_result = await load_artifact_content_or_metadata(
|
|
1356
|
+
artifact_service=artifact_service,
|
|
1357
|
+
app_name=app_name,
|
|
1358
|
+
user_id=user_id,
|
|
1359
|
+
session_id=session_id,
|
|
1360
|
+
filename=filename_base_for_load,
|
|
1361
|
+
version=version_to_load,
|
|
1362
|
+
load_metadata_only=True,
|
|
1363
|
+
log_identifier_prefix=f"{log_identifier}[source_metadata]",
|
|
1364
|
+
)
|
|
1365
|
+
if metadata_result.get("status") == "success":
|
|
1366
|
+
source_audio_metadata = metadata_result.get("metadata", {})
|
|
1367
|
+
log.debug(f"{log_identifier} Loaded source audio metadata")
|
|
1368
|
+
except Exception as meta_err:
|
|
1369
|
+
log.warning(f"{log_identifier} Could not load source audio metadata: {meta_err}")
|
|
1370
|
+
|
|
1344
1371
|
temp_file_path = None
|
|
1345
1372
|
try:
|
|
1346
1373
|
file_ext = os.path.splitext(filename_base_for_load)[1]
|
|
@@ -1382,12 +1409,93 @@ async def transcribe_audio(
|
|
|
1382
1409
|
f"{log_identifier} Audio transcribed successfully. Transcription length: {len(transcription)} characters"
|
|
1383
1410
|
)
|
|
1384
1411
|
|
|
1412
|
+
# Determine output filename
|
|
1413
|
+
if output_filename:
|
|
1414
|
+
final_filename = ensure_correct_extension(output_filename, "txt")
|
|
1415
|
+
else:
|
|
1416
|
+
# Auto-generate from source audio filename
|
|
1417
|
+
base_name = os.path.splitext(filename_base_for_load)[0]
|
|
1418
|
+
final_filename = f"{base_name}_transcription.txt"
|
|
1419
|
+
|
|
1420
|
+
# Build comprehensive metadata
|
|
1421
|
+
transcription_word_count = len(transcription.split())
|
|
1422
|
+
transcription_char_count = len(transcription)
|
|
1423
|
+
|
|
1424
|
+
# Build description from multiple sources
|
|
1425
|
+
description_parts = []
|
|
1426
|
+
|
|
1427
|
+
# Add user-provided description
|
|
1428
|
+
if description:
|
|
1429
|
+
description_parts.append(description)
|
|
1430
|
+
|
|
1431
|
+
# Add source audio description if available
|
|
1432
|
+
source_description = source_audio_metadata.get("description")
|
|
1433
|
+
if source_description:
|
|
1434
|
+
description_parts.append(f"Source: {source_description}")
|
|
1435
|
+
|
|
1436
|
+
# Add source audio info
|
|
1437
|
+
description_parts.append(f"Transcribed from audio file '{filename_base_for_load}' (version {version_to_load}, {audio_mime_type})")
|
|
1438
|
+
|
|
1439
|
+
# Combine all description parts
|
|
1440
|
+
final_description = ". ".join(description_parts)
|
|
1441
|
+
|
|
1442
|
+
metadata = {
|
|
1443
|
+
"description": final_description,
|
|
1444
|
+
"source_audio_filename": filename_base_for_load,
|
|
1445
|
+
"source_audio_version": version_to_load,
|
|
1446
|
+
"source_audio_mime_type": audio_mime_type,
|
|
1447
|
+
"transcription_model": model_name,
|
|
1448
|
+
"transcription_timestamp": datetime.now(timezone.utc).isoformat(),
|
|
1449
|
+
"transcription_word_count": transcription_word_count,
|
|
1450
|
+
"transcription_char_count": transcription_char_count,
|
|
1451
|
+
"generation_tool": "transcribe_audio",
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
# Copy source audio description separately for reference
|
|
1455
|
+
if source_description:
|
|
1456
|
+
metadata["source_audio_description"] = source_description
|
|
1457
|
+
|
|
1458
|
+
# Add user-provided description separately if provided
|
|
1459
|
+
if description:
|
|
1460
|
+
metadata["user_provided_description"] = description
|
|
1461
|
+
|
|
1462
|
+
# Save transcription as text artifact
|
|
1463
|
+
transcription_bytes = transcription.encode("utf-8")
|
|
1464
|
+
|
|
1465
|
+
save_result = await save_artifact_with_metadata(
|
|
1466
|
+
artifact_service=artifact_service,
|
|
1467
|
+
app_name=app_name,
|
|
1468
|
+
user_id=user_id,
|
|
1469
|
+
session_id=session_id,
|
|
1470
|
+
filename=final_filename,
|
|
1471
|
+
content_bytes=transcription_bytes,
|
|
1472
|
+
mime_type="text/plain",
|
|
1473
|
+
metadata_dict=metadata,
|
|
1474
|
+
timestamp=datetime.now(timezone.utc),
|
|
1475
|
+
schema_max_keys=DEFAULT_SCHEMA_MAX_KEYS,
|
|
1476
|
+
tool_context=tool_context,
|
|
1477
|
+
)
|
|
1478
|
+
|
|
1479
|
+
if save_result.get("status") != "success":
|
|
1480
|
+
error_msg = save_result.get("message", "Failed to save transcription artifact")
|
|
1481
|
+
log.error(f"{log_identifier} {error_msg}")
|
|
1482
|
+
return {
|
|
1483
|
+
"status": "error",
|
|
1484
|
+
"message": f"Transcription succeeded but failed to save as artifact: {error_msg}",
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
log.info(
|
|
1488
|
+
f"{log_identifier} Transcription saved to '{final_filename}' v{save_result['data_version']}"
|
|
1489
|
+
)
|
|
1490
|
+
|
|
1385
1491
|
return {
|
|
1386
1492
|
"status": "success",
|
|
1387
|
-
"message": "Audio transcribed successfully",
|
|
1388
|
-
"
|
|
1493
|
+
"message": "Audio transcribed and saved successfully",
|
|
1494
|
+
"output_filename": final_filename,
|
|
1495
|
+
"output_version": save_result["data_version"],
|
|
1389
1496
|
"audio_filename": filename_base_for_load,
|
|
1390
1497
|
"audio_version": version_to_load,
|
|
1498
|
+
"result_preview": f"Transcription saved to '{final_filename}' (v{save_result['data_version']}). Length: {transcription_char_count} characters, {transcription_word_count} words."
|
|
1391
1499
|
}
|
|
1392
1500
|
|
|
1393
1501
|
finally:
|
|
@@ -1599,9 +1707,9 @@ concatenate_audio_tool_def = BuiltinTool(
|
|
|
1599
1707
|
transcribe_audio_tool_def = BuiltinTool(
|
|
1600
1708
|
name="transcribe_audio",
|
|
1601
1709
|
implementation=transcribe_audio,
|
|
1602
|
-
description="Transcribes an audio recording
|
|
1710
|
+
description="Transcribes an audio recording and saves the transcription as a text artifact.",
|
|
1603
1711
|
category="audio",
|
|
1604
|
-
required_scopes=["tool:audio:transcribe"],
|
|
1712
|
+
required_scopes=["tool:audio:transcribe", "tool:artifact:create"],
|
|
1605
1713
|
parameters=adk_types.Schema(
|
|
1606
1714
|
type=adk_types.Type.OBJECT,
|
|
1607
1715
|
properties={
|
|
@@ -1609,6 +1717,16 @@ transcribe_audio_tool_def = BuiltinTool(
|
|
|
1609
1717
|
type=adk_types.Type.STRING,
|
|
1610
1718
|
description="The filename (and optional :version) of the input audio artifact.",
|
|
1611
1719
|
),
|
|
1720
|
+
"output_filename": adk_types.Schema(
|
|
1721
|
+
type=adk_types.Type.STRING,
|
|
1722
|
+
description="Optional filename for the transcription text file (without .txt extension). If not provided, will auto-generate from source audio filename.",
|
|
1723
|
+
nullable=True,
|
|
1724
|
+
),
|
|
1725
|
+
"description": adk_types.Schema(
|
|
1726
|
+
type=adk_types.Type.STRING,
|
|
1727
|
+
description="Optional description of the transcription for metadata (e.g., 'Transcription of customer support call about billing inquiry'). Will be combined with source audio description if available.",
|
|
1728
|
+
nullable=True,
|
|
1729
|
+
),
|
|
1612
1730
|
},
|
|
1613
1731
|
required=["audio_filename"],
|
|
1614
1732
|
),
|
|
@@ -5,6 +5,7 @@ use state_delta for signaling artifact return requests to the host component.
|
|
|
5
5
|
Metadata handling is integrated via artifact_helpers.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
import logging
|
|
8
9
|
import uuid
|
|
9
10
|
import json
|
|
10
11
|
import re
|
|
@@ -16,7 +17,6 @@ from google.adk.tools import ToolContext
|
|
|
16
17
|
if TYPE_CHECKING:
|
|
17
18
|
from google.adk.agents.invocation_context import InvocationContext
|
|
18
19
|
from google.genai import types as adk_types
|
|
19
|
-
from solace_ai_connector.common.log import log
|
|
20
20
|
from .tool_definition import BuiltinTool
|
|
21
21
|
from .registry import tool_registry
|
|
22
22
|
from ...agent.utils.artifact_helpers import (
|
|
@@ -38,6 +38,8 @@ from google.adk.models import LlmRequest
|
|
|
38
38
|
from google.adk.models.registry import LLMRegistry
|
|
39
39
|
from ...common.utils.mime_helpers import is_text_based_file
|
|
40
40
|
|
|
41
|
+
log = logging.getLogger(__name__)
|
|
42
|
+
|
|
41
43
|
CATEGORY_NAME = "Artifact Management"
|
|
42
44
|
CATEGORY_DESCRIPTION = "List, read, create, update, and delete artifacts."
|
|
43
45
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Built-in ADK Tools for Data Analysis (SQL, JQ, Plotly).
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
import logging
|
|
5
6
|
import json
|
|
6
7
|
from typing import Any, Dict, Tuple, Optional, Literal
|
|
7
8
|
from datetime import datetime, timezone
|
|
@@ -31,7 +32,6 @@ except ImportError:
|
|
|
31
32
|
|
|
32
33
|
from google.adk.tools import ToolContext
|
|
33
34
|
from google.genai import types as adk_types
|
|
34
|
-
from solace_ai_connector.common.log import log
|
|
35
35
|
|
|
36
36
|
from ...agent.utils.artifact_helpers import (
|
|
37
37
|
ensure_correct_extension,
|
|
@@ -44,6 +44,8 @@ from ...agent.utils.context_helpers import get_original_session_id
|
|
|
44
44
|
from .tool_definition import BuiltinTool
|
|
45
45
|
from .registry import tool_registry
|
|
46
46
|
|
|
47
|
+
log = logging.getLogger(__name__)
|
|
48
|
+
|
|
47
49
|
CATEGORY_NAME = "Data Analysis"
|
|
48
50
|
CATEGORY_DESCRIPTION = "Create static chart images from data in JSON or YAML format."
|
|
49
51
|
|