solace-agent-mesh 1.7.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/artifacts/filesystem_artifact_service.py +164 -0
- solace_agent_mesh/agent/adk/artifacts/s3_artifact_service.py +163 -0
- solace_agent_mesh/agent/adk/callbacks.py +752 -127
- solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +99 -7
- 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 +34 -16
- solace_agent_mesh/agent/adk/models/oauth2_token_manager.py +24 -137
- solace_agent_mesh/agent/adk/runner.py +66 -8
- solace_agent_mesh/agent/adk/schema_migration.py +88 -0
- solace_agent_mesh/agent/adk/services.py +41 -1
- solace_agent_mesh/agent/adk/setup.py +220 -32
- solace_agent_mesh/agent/adk/stream_parser.py +229 -40
- solace_agent_mesh/agent/protocol/event_handlers.py +219 -33
- 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/component.py +188 -22
- solace_agent_mesh/agent/proxies/base/proxy_task_context.py +3 -1
- solace_agent_mesh/agent/sac/app.py +37 -12
- solace_agent_mesh/agent/sac/component.py +322 -52
- solace_agent_mesh/agent/sac/patch_adk.py +8 -16
- solace_agent_mesh/agent/sac/task_execution_context.py +90 -0
- 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 +698 -24
- solace_agent_mesh/agent/tools/deep_research_tools.py +2161 -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 +54 -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 +243 -5
- 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/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/64195356.09dbd087.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/66d4869e.30340bd3.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6aaedf65.7253541d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6d84eae0.fd23ba4a.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/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/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/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/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 +75 -75
- 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 +98 -112
- 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 -28
- solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +29 -29
- 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 +67 -53
- solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +17 -17
- 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 +87 -87
- 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 +50 -23
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/connectors/index.html +29 -24
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +21 -21
- 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 +96 -66
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/secure-user-delegated-access/index.html +181 -181
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +75 -75
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/wheel-installation/index.html +27 -27
- 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 -38
- 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 +135 -114
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +37 -37
- 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 +112 -112
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/user-feedback/index.html +28 -28
- 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/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-tcIFZLis.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-CINwxvwV.js → vendor-CGk8Suyh.js} +189 -94
- 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/types.py +1 -1
- solace_agent_mesh/common/agent_registry.py +38 -11
- solace_agent_mesh/common/data_parts.py +124 -0
- 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 +73 -1
- solace_agent_mesh/common/sam_events/event_service.py +2 -2
- solace_agent_mesh/common/utils/embeds/converter.py +1 -8
- solace_agent_mesh/common/utils/embeds/modifiers.py +2 -27
- solace_agent_mesh/common/utils/embeds/resolver.py +94 -25
- solace_agent_mesh/common/utils/embeds/types.py +1 -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/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/base.py +28 -1
- solace_agent_mesh/gateway/adapter/types.py +9 -0
- solace_agent_mesh/gateway/base/app.py +10 -0
- solace_agent_mesh/gateway/base/auth_interface.py +103 -0
- solace_agent_mesh/gateway/base/component.py +451 -10
- solace_agent_mesh/gateway/generic/component.py +274 -30
- solace_agent_mesh/gateway/http_sse/alembic/env.py +0 -7
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_soft_delete_and_search.py +2 -43
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_default_agent_to_projects.py +2 -2
- 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 +23 -6
- solace_agent_mesh/gateway/http_sse/component.py +158 -73
- solace_agent_mesh/gateway/http_sse/dependencies.py +50 -57
- solace_agent_mesh/gateway/http_sse/main.py +58 -482
- solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +2 -2
- solace_agent_mesh/gateway/http_sse/repository/entities/project.py +1 -1
- solace_agent_mesh/gateway/http_sse/repository/entities/project_user.py +1 -1
- solace_agent_mesh/gateway/http_sse/repository/entities/session.py +3 -2
- solace_agent_mesh/gateway/http_sse/repository/entities/task.py +7 -0
- solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +2 -2
- solace_agent_mesh/gateway/http_sse/repository/interfaces.py +2 -2
- solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +5 -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 +1 -1
- solace_agent_mesh/gateway/http_sse/repository/models/task_model.py +8 -1
- solace_agent_mesh/gateway/http_sse/repository/project_repository.py +1 -1
- solace_agent_mesh/gateway/http_sse/repository/project_user_repository.py +1 -1
- solace_agent_mesh/gateway/http_sse/repository/session_repository.py +12 -107
- 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 +113 -7
- solace_agent_mesh/gateway/http_sse/routers/auth.py +69 -132
- solace_agent_mesh/gateway/http_sse/routers/config.py +235 -10
- 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/session_requests.py +1 -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 +1 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +3 -2
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/version_responses.py +31 -0
- solace_agent_mesh/gateway/http_sse/routers/feedback.py +2 -2
- solace_agent_mesh/gateway/http_sse/routers/people.py +2 -2
- solace_agent_mesh/gateway/http_sse/routers/projects.py +250 -24
- solace_agent_mesh/gateway/http_sse/routers/prompts.py +1416 -0
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +14 -5
- solace_agent_mesh/gateway/http_sse/routers/speech.py +355 -0
- solace_agent_mesh/gateway/http_sse/routers/sse.py +117 -4
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +509 -149
- 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 +2 -1
- 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 +539 -12
- solace_agent_mesh/gateway/http_sse/services/prompt_builder_assistant.py +303 -0
- solace_agent_mesh/gateway/http_sse/services/session_service.py +198 -21
- solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +354 -4
- solace_agent_mesh/gateway/http_sse/sse_manager.py +280 -169
- 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 +1 -1
- 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.7.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/METADATA +29 -8
- {solace_agent_mesh-1.7.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/RECORD +334 -313
- {solace_agent_mesh-1.7.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/WHEEL +1 -1
- solace_agent_mesh/agent/adk/adk_llm.txt +0 -226
- 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 -189
- solace_agent_mesh/agent/agent_llm.txt +0 -369
- 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/proxies/a2a/a2a_llm.txt +0 -190
- solace_agent_mesh/agent/proxies/base/base_llm.txt +0 -148
- solace_agent_mesh/agent/proxies/proxies_llm.txt +0 -283
- 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 -58
- solace_agent_mesh/agent/testing/testing_llm_detail.txt +0 -68
- solace_agent_mesh/agent/tools/tools_llm.txt +0 -276
- solace_agent_mesh/agent/tools/tools_llm_detail.txt +0 -275
- solace_agent_mesh/agent/utils/utils_llm.txt +0 -152
- solace_agent_mesh/agent/utils/utils_llm_detail.txt +0 -149
- solace_agent_mesh/assets/docs/assets/js/05749d90.c70b2be9.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/15ba94aa.92fea363.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/15e40e79.36003774.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/17896441.a5e82f9b.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/240a0364.c39f8388.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.e4870a49.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/3ff0015d.b63ee53a.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/547e15cc.2f7790c1.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/55b7b518.f2b1d1ba.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.45b32c2b.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/64195356.c498c4d0.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/66d4869e.830d443f.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/6d84eae0.4a5fbf39.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/8024126c.fa0e7186.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.09ed9234.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.245ae0ef.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/c93cbaa0.eaff365e.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/cbe2e9ea.f902fad8.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/db5d6442.3daf1696.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e04b235d.c9c50c7b.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e3d9abda.d11c67a7.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e6f9706b.045d0fa1.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e92d0134.3bda61dd.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f284c35a.5099c51e.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/main.f213fe0c.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.d9606d6a.js +0 -1
- solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes-deployment/index.html +0 -47
- solace_agent_mesh/assets/docs/lunr-index-1762283454666.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1762283454666.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-CRYdKo2Q.js +0 -25
- solace_agent_mesh/client/webui/frontend/static/assets/main-CojeY_1w.css +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-ILja9MCG.js +0 -353
- solace_agent_mesh/common/a2a/a2a_llm.txt +0 -175
- solace_agent_mesh/common/a2a/a2a_llm_detail.txt +0 -193
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +0 -445
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm_detail.txt +0 -736
- solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +0 -330
- solace_agent_mesh/common/common_llm.txt +0 -230
- 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 -81
- solace_agent_mesh/common/services/services_llm.txt +0 -368
- 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 -335
- 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 -226
- solace_agent_mesh/gateway/base/base_llm_detail.txt +0 -235
- solace_agent_mesh/gateway/gateway_llm.txt +0 -369
- solace_agent_mesh/gateway/gateway_llm_detail.txt +0 -3885
- solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +0 -345
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_fulltext_search_indexes.py +0 -92
- solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +0 -161
- 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 -221
- solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +0 -257
- solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +0 -308
- solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +0 -450
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +0 -133
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +0 -123
- solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +0 -312
- solace_agent_mesh/gateway/http_sse/services/services_llm.txt +0 -303
- solace_agent_mesh/gateway/http_sse/shared/__init__.py +0 -146
- solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +0 -319
- 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/assets/docs/assets/js/{main.f213fe0c.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.7.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.7.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -20,6 +20,7 @@ from ...common.exceptions import MessageSizeExceededError
|
|
|
20
20
|
|
|
21
21
|
log = logging.getLogger(__name__)
|
|
22
22
|
|
|
23
|
+
|
|
23
24
|
class ArtifactIdentifier(BaseModel):
|
|
24
25
|
"""Identifies a specific version of an artifact."""
|
|
25
26
|
|
|
@@ -74,6 +75,81 @@ class PeerAgentTool(BaseTool):
|
|
|
74
75
|
"""Safely retrieves the AgentCard for the target peer."""
|
|
75
76
|
return self.host_component.peer_agents.get(self.target_agent_name)
|
|
76
77
|
|
|
78
|
+
def _build_enhanced_description(self, agent_card: AgentCard) -> str:
|
|
79
|
+
"""
|
|
80
|
+
Builds an enhanced description including skills.
|
|
81
|
+
Returns a structured, markdown-formatted description with:
|
|
82
|
+
- Base description
|
|
83
|
+
- Skills section (if skills are available)
|
|
84
|
+
- Summary format (counts + skill names, up to 8 skills before truncation)
|
|
85
|
+
- Soft limit of ~500 chars (allows overflow to ~600 for important info)
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
agent_card: The AgentCard to extract information from
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
Enhanced description string with markdown formatting
|
|
92
|
+
"""
|
|
93
|
+
# Start with base description - ensure it's clean (no extra whitespace)
|
|
94
|
+
base_desc = (
|
|
95
|
+
agent_card.description
|
|
96
|
+
or f"Interact with the {self.target_agent_name} agent."
|
|
97
|
+
)
|
|
98
|
+
base_desc = " ".join(base_desc.split()) # Normalize whitespace
|
|
99
|
+
|
|
100
|
+
# Extract skills information
|
|
101
|
+
if agent_card.skills and len(agent_card.skills) > 0:
|
|
102
|
+
skill_count = len(agent_card.skills)
|
|
103
|
+
# Get first 8 skill names
|
|
104
|
+
max_skills_to_show = 8
|
|
105
|
+
skill_names = []
|
|
106
|
+
for skill in agent_card.skills[:max_skills_to_show]:
|
|
107
|
+
# Prefer name, fallback to id
|
|
108
|
+
skill_name = getattr(skill, "name", None) or getattr(skill, "id", None)
|
|
109
|
+
if skill_name:
|
|
110
|
+
skill_names.append(skill_name)
|
|
111
|
+
|
|
112
|
+
skills_str = ", ".join(skill_names)
|
|
113
|
+
# Add truncation indicator with count if there are more skills
|
|
114
|
+
if skill_count > max_skills_to_show:
|
|
115
|
+
remaining = skill_count - max_skills_to_show
|
|
116
|
+
skills_str += f" ({remaining} more...)"
|
|
117
|
+
|
|
118
|
+
# Include skill count in the header
|
|
119
|
+
if skill_count > 1:
|
|
120
|
+
enhanced_desc = (
|
|
121
|
+
f"{base_desc}\n\n**Skills ({skill_count}):** {skills_str}"
|
|
122
|
+
)
|
|
123
|
+
else:
|
|
124
|
+
enhanced_desc = f"{base_desc}\n\n**Skills:** {skills_str}"
|
|
125
|
+
|
|
126
|
+
# Check length and truncate if needed (soft limit ~600 chars)
|
|
127
|
+
if len(enhanced_desc) > 600:
|
|
128
|
+
# Truncate to first 4 skills to keep it concise
|
|
129
|
+
skill_names = []
|
|
130
|
+
for skill in agent_card.skills[:4]:
|
|
131
|
+
skill_name = getattr(skill, "name", None) or getattr(
|
|
132
|
+
skill, "id", None
|
|
133
|
+
)
|
|
134
|
+
if skill_name:
|
|
135
|
+
skill_names.append(skill_name)
|
|
136
|
+
skills_str = ", ".join(skill_names)
|
|
137
|
+
if skill_count > 4:
|
|
138
|
+
remaining = skill_count - 4
|
|
139
|
+
skills_str += f" ({remaining} more...)"
|
|
140
|
+
|
|
141
|
+
if skill_count > 1:
|
|
142
|
+
enhanced_desc = (
|
|
143
|
+
f"{base_desc}\n\n**Skills ({skill_count}):** {skills_str}"
|
|
144
|
+
)
|
|
145
|
+
else:
|
|
146
|
+
enhanced_desc = f"{base_desc}\n\n**Skills:** {skills_str}"
|
|
147
|
+
else:
|
|
148
|
+
# No skills - just return base description
|
|
149
|
+
enhanced_desc = base_desc
|
|
150
|
+
|
|
151
|
+
return enhanced_desc
|
|
152
|
+
|
|
77
153
|
def _get_declaration(self) -> Optional[adk_types.FunctionDeclaration]:
|
|
78
154
|
"""
|
|
79
155
|
Dynamically generates the FunctionDeclaration based on the peer's AgentCard.
|
|
@@ -88,10 +164,8 @@ class PeerAgentTool(BaseTool):
|
|
|
88
164
|
)
|
|
89
165
|
return None
|
|
90
166
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
or f"Interact with the {self.target_agent_name} agent."
|
|
94
|
-
)
|
|
167
|
+
# Use enhanced description with capabilities information
|
|
168
|
+
self.description = self._build_enhanced_description(agent_card)
|
|
95
169
|
|
|
96
170
|
parameters_schema = adk_types.Schema(
|
|
97
171
|
type=adk_types.Type.OBJECT,
|
|
@@ -100,10 +174,6 @@ class PeerAgentTool(BaseTool):
|
|
|
100
174
|
type=adk_types.Type.STRING,
|
|
101
175
|
description="Detailed description of the task for the peer agent.",
|
|
102
176
|
),
|
|
103
|
-
"user_query": adk_types.Schema(
|
|
104
|
-
type=adk_types.Type.STRING,
|
|
105
|
-
description="The original user query or relevant context.",
|
|
106
|
-
),
|
|
107
177
|
"artifacts": adk_types.Schema(
|
|
108
178
|
type=adk_types.Type.ARRAY,
|
|
109
179
|
items=adk_types.Schema(
|
|
@@ -204,13 +274,10 @@ class PeerAgentTool(BaseTool):
|
|
|
204
274
|
f"TaskExecutionContext not found for task '{main_logical_task_id}'"
|
|
205
275
|
)
|
|
206
276
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
invocation_id,
|
|
212
|
-
task_context_obj.parallel_tool_calls.get(invocation_id),
|
|
213
|
-
)
|
|
277
|
+
# NOTE: register_parallel_call_sent is called in
|
|
278
|
+
# preregister_long_running_tools_callback (after_model_callback)
|
|
279
|
+
# BEFORE tool execution begins. This prevents race conditions where
|
|
280
|
+
# one tool completes before another registers.
|
|
214
281
|
|
|
215
282
|
a2a_message_parts = self._prepare_a2a_parts(args, tool_context)
|
|
216
283
|
a2a_metadata = {}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Collection of Python tools for time and date operations.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from zoneinfo import ZoneInfo
|
|
8
|
+
from typing import Any, Dict, Optional
|
|
9
|
+
|
|
10
|
+
from google.adk.tools import ToolContext
|
|
11
|
+
from google.genai import types as adk_types
|
|
12
|
+
|
|
13
|
+
from .tool_definition import BuiltinTool
|
|
14
|
+
from .registry import tool_registry
|
|
15
|
+
from ...agent.utils.context_helpers import get_user_timezone
|
|
16
|
+
|
|
17
|
+
log = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
CATEGORY_NAME = "Time & Date"
|
|
20
|
+
CATEGORY_DESCRIPTION = "Get current time and date information in the user's timezone."
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
async def get_current_time(
|
|
24
|
+
tool_context: ToolContext = None,
|
|
25
|
+
tool_config: Optional[Dict[str, Any]] = None,
|
|
26
|
+
) -> Dict[str, Any]:
|
|
27
|
+
"""
|
|
28
|
+
Gets the current date and time in the user's local timezone.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
tool_context: The context provided by the ADK framework.
|
|
32
|
+
tool_config: Optional. Configuration passed by the ADK, generally not used by this tool.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
A dictionary with status, current time information, and timezone details.
|
|
36
|
+
"""
|
|
37
|
+
log_identifier = "[TimeTools:get_current_time]"
|
|
38
|
+
|
|
39
|
+
if not tool_context:
|
|
40
|
+
log.error(f"{log_identifier} ToolContext is missing.")
|
|
41
|
+
return {"status": "error", "message": "ToolContext is missing."}
|
|
42
|
+
|
|
43
|
+
try:
|
|
44
|
+
inv_context = tool_context._invocation_context
|
|
45
|
+
if not inv_context:
|
|
46
|
+
raise ValueError("InvocationContext is not available.")
|
|
47
|
+
|
|
48
|
+
# Get user's timezone from context
|
|
49
|
+
user_timezone_str = get_user_timezone(inv_context)
|
|
50
|
+
log.info(f"{log_identifier} Retrieved timezone: {user_timezone_str}")
|
|
51
|
+
|
|
52
|
+
# Create timezone object
|
|
53
|
+
try:
|
|
54
|
+
user_tz = ZoneInfo(user_timezone_str)
|
|
55
|
+
except Exception as tz_error:
|
|
56
|
+
log.warning(
|
|
57
|
+
f"{log_identifier} Invalid timezone '{user_timezone_str}', falling back to UTC: {tz_error}"
|
|
58
|
+
)
|
|
59
|
+
user_tz = ZoneInfo("UTC")
|
|
60
|
+
user_timezone_str = "UTC"
|
|
61
|
+
|
|
62
|
+
# Get current time in user's timezone
|
|
63
|
+
current_time = datetime.now(user_tz)
|
|
64
|
+
|
|
65
|
+
# Calculate timezone offset
|
|
66
|
+
offset = current_time.strftime("%z")
|
|
67
|
+
# Format offset as "+HH:MM" or "-HH:MM"
|
|
68
|
+
if len(offset) == 5: # Format: +HHMM or -HHMM
|
|
69
|
+
timezone_offset = f"{offset[:3]}:{offset[3:]}"
|
|
70
|
+
else:
|
|
71
|
+
timezone_offset = "+00:00"
|
|
72
|
+
|
|
73
|
+
# Get timezone abbreviation (e.g., EST, PST)
|
|
74
|
+
tz_abbrev = current_time.strftime("%Z")
|
|
75
|
+
|
|
76
|
+
# Format various time representations
|
|
77
|
+
iso_format = current_time.isoformat()
|
|
78
|
+
formatted_time = current_time.strftime(f"%Y-%m-%d %H:%M:%S {tz_abbrev}")
|
|
79
|
+
date_only = current_time.strftime("%Y-%m-%d")
|
|
80
|
+
time_only = current_time.strftime("%H:%M:%S")
|
|
81
|
+
day_of_week = current_time.strftime("%A")
|
|
82
|
+
timestamp = int(current_time.timestamp())
|
|
83
|
+
|
|
84
|
+
log.info(
|
|
85
|
+
f"{log_identifier} Successfully retrieved time for timezone {user_timezone_str}: {formatted_time}"
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
"status": "success",
|
|
90
|
+
"current_time": iso_format,
|
|
91
|
+
"timezone": user_timezone_str,
|
|
92
|
+
"timezone_offset": timezone_offset,
|
|
93
|
+
"timezone_abbreviation": tz_abbrev,
|
|
94
|
+
"formatted_time": formatted_time,
|
|
95
|
+
"timestamp": timestamp,
|
|
96
|
+
"date": date_only,
|
|
97
|
+
"time": time_only,
|
|
98
|
+
"day_of_week": day_of_week,
|
|
99
|
+
"message": f"Current time in {user_timezone_str}: {formatted_time}",
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
except ValueError as ve:
|
|
103
|
+
log.error(f"{log_identifier} Value error: {ve}", exc_info=True)
|
|
104
|
+
return {"status": "error", "message": str(ve)}
|
|
105
|
+
except Exception as e:
|
|
106
|
+
log.exception(f"{log_identifier} Unexpected error in get_current_time: {e}")
|
|
107
|
+
return {"status": "error", "message": f"An unexpected error occurred: {e}"}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
get_current_time_tool_def = BuiltinTool(
|
|
111
|
+
name="get_current_time",
|
|
112
|
+
implementation=get_current_time,
|
|
113
|
+
description="Gets the current date and time in the user's local timezone. Returns comprehensive time information including formatted timestamps, timezone details, and date components. Use this tool when you need to know what time it is for the user.",
|
|
114
|
+
category="time",
|
|
115
|
+
category_name=CATEGORY_NAME,
|
|
116
|
+
category_description=CATEGORY_DESCRIPTION,
|
|
117
|
+
required_scopes=["tool:time:read"],
|
|
118
|
+
parameters=adk_types.Schema(
|
|
119
|
+
type=adk_types.Type.OBJECT,
|
|
120
|
+
properties={},
|
|
121
|
+
required=[],
|
|
122
|
+
),
|
|
123
|
+
examples=[],
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
tool_registry.register(get_current_time_tool_def)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Pydantic models for agent tool configurations defined in YAML.
|
|
3
3
|
"""
|
|
4
4
|
from typing import Any, Dict, List, Literal, Optional, Union
|
|
5
|
-
from pydantic import Field
|
|
5
|
+
from pydantic import Field, model_validator
|
|
6
6
|
from ...common.utils.pydantic_utils import SamConfigBase
|
|
7
7
|
|
|
8
8
|
|
|
@@ -47,15 +47,67 @@ class McpToolConfig(BaseToolConfig):
|
|
|
47
47
|
"""Configuration for an MCP tool or toolset."""
|
|
48
48
|
tool_type: Literal["mcp"]
|
|
49
49
|
connection_params: Dict[str, Any]
|
|
50
|
-
tool_name: Optional[str] = None
|
|
50
|
+
tool_name: Optional[str] = None # Single tool filter (backward compat)
|
|
51
|
+
tool_name_prefix: Optional[str] = None # Optional prefix for tool names
|
|
51
52
|
environment_variables: Optional[Dict[str, Any]] = None
|
|
52
53
|
auth: dict[str, Any] | None = None
|
|
53
54
|
manifest: list[dict[str, Any]] | None = None
|
|
54
55
|
|
|
56
|
+
# Tool filtering options (mutually exclusive with each other AND with tool_name)
|
|
57
|
+
allow_list: Optional[List[str]] = None # Include only these tools
|
|
58
|
+
deny_list: Optional[List[str]] = None # Exclude these tools
|
|
59
|
+
|
|
60
|
+
@model_validator(mode='after')
|
|
61
|
+
def validate_tool_filtering(self):
|
|
62
|
+
"""Ensure tool_name, allow_list, and deny_list are mutually exclusive."""
|
|
63
|
+
filters_specified = [
|
|
64
|
+
self.tool_name is not None,
|
|
65
|
+
self.allow_list is not None,
|
|
66
|
+
self.deny_list is not None,
|
|
67
|
+
]
|
|
68
|
+
if sum(filters_specified) > 1:
|
|
69
|
+
raise ValueError(
|
|
70
|
+
"MCP tool configuration error: 'tool_name', 'allow_list', and 'deny_list' "
|
|
71
|
+
"are mutually exclusive. Please use only one."
|
|
72
|
+
)
|
|
73
|
+
return self
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class OpenApiToolConfig(BaseToolConfig):
|
|
77
|
+
"""Configuration for OpenAPI-based tools."""
|
|
78
|
+
tool_type: Literal["openapi"]
|
|
79
|
+
|
|
80
|
+
# Specification input (mutually exclusive - only one should be provided)
|
|
81
|
+
specification_file: Optional[str] = None # Path to OpenAPI spec file
|
|
82
|
+
specification: Optional[str] = None # Inline OpenAPI spec (JSON/YAML)
|
|
83
|
+
specification_url: Optional[str] = None # URL to fetch OpenAPI spec from
|
|
84
|
+
specification_format: Optional[Literal["json", "yaml"]] = None # Optional format hint
|
|
85
|
+
|
|
86
|
+
# Server URL override
|
|
87
|
+
base_url: Optional[str] = None # Base URL to override/complete the server URL in the spec
|
|
88
|
+
|
|
89
|
+
# Tool filtering (mutually exclusive - only one should be provided)
|
|
90
|
+
allow_list: Optional[List[str]] = None # Include only these specific operations/endpoints
|
|
91
|
+
deny_list: Optional[List[str]] = None # Exclude these specific operations/endpoints
|
|
92
|
+
|
|
93
|
+
# Authentication
|
|
94
|
+
auth: Optional[Dict[str, Any]] = None
|
|
95
|
+
|
|
96
|
+
@model_validator(mode='after')
|
|
97
|
+
def validate_tool_filtering(self):
|
|
98
|
+
"""Ensure allow_list and deny_list are mutually exclusive."""
|
|
99
|
+
if self.allow_list is not None and self.deny_list is not None:
|
|
100
|
+
raise ValueError(
|
|
101
|
+
"OpenAPI tool configuration error: Cannot specify both 'allow_list' and 'deny_list'. "
|
|
102
|
+
"Please use only one."
|
|
103
|
+
)
|
|
104
|
+
return self
|
|
105
|
+
|
|
55
106
|
|
|
56
107
|
AnyToolConfig = Union[
|
|
57
108
|
BuiltinToolConfig,
|
|
58
109
|
BuiltinGroupToolConfig,
|
|
59
110
|
PythonToolConfig,
|
|
60
111
|
McpToolConfig,
|
|
112
|
+
OpenApiToolConfig,
|
|
61
113
|
]
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Web Search Tools for Solace Agent Mesh
|
|
3
|
+
Provides web search capabilities using Google Custom Search API.
|
|
4
|
+
|
|
5
|
+
For other search providers (e.g., Exa, Brave, Tavily), please use the corresponding
|
|
6
|
+
plugins from the solace-agent-mesh-plugins repository.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import logging
|
|
10
|
+
from typing import Any, Dict, Optional
|
|
11
|
+
from datetime import datetime, timezone
|
|
12
|
+
from google.adk.tools import ToolContext
|
|
13
|
+
|
|
14
|
+
from ...tools.web_search import GoogleSearchTool, SearchResult
|
|
15
|
+
from .tool_definition import BuiltinTool
|
|
16
|
+
from .registry import tool_registry
|
|
17
|
+
from ...common.rag_dto import create_rag_source, create_rag_search_result
|
|
18
|
+
|
|
19
|
+
log = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
CATEGORY_NAME = "web_search"
|
|
22
|
+
CATEGORY_DESCRIPTION = "Tools for searching the web and retrieving current information"
|
|
23
|
+
|
|
24
|
+
# State key for tracking search turns within a task/session
|
|
25
|
+
_SEARCH_TURN_STATE_KEY = "web_search_turn_counter"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _get_next_search_turn(tool_context: Optional[ToolContext]) -> int:
|
|
29
|
+
"""
|
|
30
|
+
Get the next search turn number using tool context state.
|
|
31
|
+
|
|
32
|
+
This approach stores the turn counter in the tool context state, which is:
|
|
33
|
+
- Per-task/session scoped (not global)
|
|
34
|
+
- Automatically cleaned up when the task ends
|
|
35
|
+
|
|
36
|
+
Each search within a task gets a unique turn number, so citations from
|
|
37
|
+
different searches never collide (e.g., s0r0, s0r1 for first search,
|
|
38
|
+
s1r0, s1r1 for second search).
|
|
39
|
+
"""
|
|
40
|
+
if not tool_context:
|
|
41
|
+
# Fallback: return 0 if no context (shouldn't happen in practice)
|
|
42
|
+
log.warning("[web_search] No tool_context provided, using turn=0")
|
|
43
|
+
return 0
|
|
44
|
+
|
|
45
|
+
# Get current turn from state, defaulting to 0
|
|
46
|
+
current_turn = tool_context.state.get(_SEARCH_TURN_STATE_KEY, 0)
|
|
47
|
+
|
|
48
|
+
# Increment for next search
|
|
49
|
+
tool_context.state[_SEARCH_TURN_STATE_KEY] = current_turn + 1
|
|
50
|
+
|
|
51
|
+
return current_turn
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
async def web_search_google(
|
|
55
|
+
query: str,
|
|
56
|
+
max_results: int = 5,
|
|
57
|
+
search_type: Optional[str] = None,
|
|
58
|
+
date_restrict: Optional[str] = None,
|
|
59
|
+
safe_search: Optional[str] = None,
|
|
60
|
+
tool_context: ToolContext = None,
|
|
61
|
+
tool_config: Optional[Dict[str, Any]] = None,
|
|
62
|
+
**kwargs
|
|
63
|
+
) -> str:
|
|
64
|
+
"""
|
|
65
|
+
Search the web using Google Custom Search API.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
query: The search query string
|
|
69
|
+
max_results: Maximum number of results to return (1-10)
|
|
70
|
+
search_type: Set to 'image' for image search
|
|
71
|
+
date_restrict: Restrict results by recency (e.g., 'd7' for last 7 days)
|
|
72
|
+
safe_search: Safe search level - 'off', 'medium', or 'high'
|
|
73
|
+
tool_context: ADK tool context
|
|
74
|
+
tool_config: Tool configuration containing API keys
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
JSON string containing search results with sources for citation
|
|
78
|
+
"""
|
|
79
|
+
log_identifier = "[web_search_google]"
|
|
80
|
+
|
|
81
|
+
try:
|
|
82
|
+
config = tool_config or {}
|
|
83
|
+
api_key = config.get("google_search_api_key")
|
|
84
|
+
search_engine_id = config.get("google_cse_id")
|
|
85
|
+
|
|
86
|
+
if not api_key or not search_engine_id:
|
|
87
|
+
error_msg = "google_search_api_key or google_cse_id not configured in tool_config"
|
|
88
|
+
log.error("%s %s", log_identifier, error_msg)
|
|
89
|
+
return f"Error: {error_msg}"
|
|
90
|
+
|
|
91
|
+
tool = GoogleSearchTool(
|
|
92
|
+
api_key=api_key,
|
|
93
|
+
search_engine_id=search_engine_id
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
result: SearchResult = await tool.search(
|
|
97
|
+
query=query,
|
|
98
|
+
max_results=max_results,
|
|
99
|
+
search_type=search_type,
|
|
100
|
+
date_restrict=date_restrict,
|
|
101
|
+
safe_search=safe_search,
|
|
102
|
+
**kwargs
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
if not result.success:
|
|
106
|
+
log.error("%s Search failed: %s", log_identifier, result.error)
|
|
107
|
+
return f"Error: {result.error}"
|
|
108
|
+
|
|
109
|
+
# Get unique search turn for this search to prevent citation ID collisions
|
|
110
|
+
# Uses tool context state (per-task scoped, automatically cleaned up)
|
|
111
|
+
search_turn = _get_next_search_turn(tool_context)
|
|
112
|
+
citation_prefix = f"s{search_turn}r" # e.g., s0r0, s0r1 for first search; s1r0, s1r1 for second
|
|
113
|
+
|
|
114
|
+
log.info(
|
|
115
|
+
"%s Search successful: %d results, %d images (turn=%d, citation_prefix=%s)",
|
|
116
|
+
log_identifier,
|
|
117
|
+
len(result.organic),
|
|
118
|
+
len(result.images),
|
|
119
|
+
search_turn,
|
|
120
|
+
citation_prefix
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
rag_sources = []
|
|
124
|
+
valid_citation_ids = []
|
|
125
|
+
|
|
126
|
+
# Log citation-to-source mapping for debugging
|
|
127
|
+
log.debug("%s === CITATION TO SOURCE MAPPING (turn %d) ===", log_identifier, search_turn)
|
|
128
|
+
|
|
129
|
+
for i, source in enumerate(result.organic):
|
|
130
|
+
citation_id = f"{citation_prefix}{i}"
|
|
131
|
+
valid_citation_ids.append(citation_id)
|
|
132
|
+
|
|
133
|
+
# Log each citation mapping at debug level
|
|
134
|
+
log.debug(
|
|
135
|
+
"%s Citation [[cite:%s]] -> URL: %s | Title: %s",
|
|
136
|
+
log_identifier,
|
|
137
|
+
citation_id,
|
|
138
|
+
source.link,
|
|
139
|
+
source.title[:50] if source.title else "N/A"
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
rag_source = create_rag_source(
|
|
143
|
+
citation_id=citation_id,
|
|
144
|
+
file_id=f"web_search_{search_turn}_{i}",
|
|
145
|
+
filename=source.attribution or source.title,
|
|
146
|
+
title=source.title,
|
|
147
|
+
source_url=source.link,
|
|
148
|
+
url=source.link,
|
|
149
|
+
content_preview=source.snippet,
|
|
150
|
+
relevance_score=1.0,
|
|
151
|
+
source_type="web",
|
|
152
|
+
retrieved_at=datetime.now(timezone.utc).isoformat(),
|
|
153
|
+
metadata={
|
|
154
|
+
"title": source.title,
|
|
155
|
+
"link": source.link,
|
|
156
|
+
"type": "web_search",
|
|
157
|
+
"favicon": f"https://www.google.com/s2/favicons?domain={source.link}&sz=32" if source.link else ""
|
|
158
|
+
}
|
|
159
|
+
)
|
|
160
|
+
rag_sources.append(rag_source)
|
|
161
|
+
|
|
162
|
+
log.debug("%s === END CITATION MAPPING ===", log_identifier)
|
|
163
|
+
log.debug("%s Valid citation IDs for this search: %s", log_identifier, valid_citation_ids)
|
|
164
|
+
|
|
165
|
+
for i, image in enumerate(result.images):
|
|
166
|
+
image_citation_id = f"img{search_turn}r{i}"
|
|
167
|
+
image_source = create_rag_source(
|
|
168
|
+
citation_id=image_citation_id,
|
|
169
|
+
file_id=f"web_search_image_{search_turn}_{i}",
|
|
170
|
+
filename=image.title or f"Image {i+1}",
|
|
171
|
+
title=image.title,
|
|
172
|
+
source_url=image.link,
|
|
173
|
+
url=image.link,
|
|
174
|
+
content_preview=image.title or "",
|
|
175
|
+
relevance_score=1.0,
|
|
176
|
+
source_type="image",
|
|
177
|
+
retrieved_at=datetime.now(timezone.utc).isoformat(),
|
|
178
|
+
metadata={
|
|
179
|
+
"title": image.title,
|
|
180
|
+
"link": image.link,
|
|
181
|
+
"imageUrl": image.imageUrl,
|
|
182
|
+
"type": "image",
|
|
183
|
+
}
|
|
184
|
+
)
|
|
185
|
+
rag_sources.append(image_source)
|
|
186
|
+
|
|
187
|
+
rag_metadata = create_rag_search_result(
|
|
188
|
+
query=query,
|
|
189
|
+
search_type="web_search",
|
|
190
|
+
timestamp=datetime.now(timezone.utc).isoformat(),
|
|
191
|
+
sources=rag_sources
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
# Build a formatted result string that clearly associates each citation ID with its content
|
|
195
|
+
# This helps the LLM correctly match citations to facts
|
|
196
|
+
formatted_results = []
|
|
197
|
+
formatted_results.append(f"=== SEARCH RESULTS (Turn {search_turn}) ===")
|
|
198
|
+
formatted_results.append(f"Query: {query}")
|
|
199
|
+
formatted_results.append(f"Valid citation IDs: {', '.join(valid_citation_ids)}")
|
|
200
|
+
formatted_results.append("")
|
|
201
|
+
|
|
202
|
+
for i, source in enumerate(result.organic):
|
|
203
|
+
citation_id = f"{citation_prefix}{i}"
|
|
204
|
+
formatted_results.append(f"--- RESULT {i+1} ---")
|
|
205
|
+
formatted_results.append(f"CITATION ID: [[cite:{citation_id}]]")
|
|
206
|
+
formatted_results.append(f"TITLE: {source.title}")
|
|
207
|
+
formatted_results.append(f"URL: {source.link}")
|
|
208
|
+
formatted_results.append(f"CONTENT: {source.snippet}")
|
|
209
|
+
formatted_results.append(f"USE [[cite:{citation_id}]] to cite facts from THIS result only")
|
|
210
|
+
formatted_results.append("")
|
|
211
|
+
|
|
212
|
+
formatted_results.append("=== END SEARCH RESULTS ===")
|
|
213
|
+
formatted_results.append("")
|
|
214
|
+
formatted_results.append("IMPORTANT: Each citation ID is UNIQUE to its result.")
|
|
215
|
+
formatted_results.append("Only use a citation ID for facts that appear in THAT specific result's CONTENT.")
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
"result": result.model_dump_json(),
|
|
219
|
+
"formatted_results": "\n".join(formatted_results),
|
|
220
|
+
"rag_metadata": rag_metadata,
|
|
221
|
+
"valid_citation_ids": valid_citation_ids,
|
|
222
|
+
"num_results": len(result.organic),
|
|
223
|
+
"search_turn": search_turn
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
except Exception as e:
|
|
227
|
+
log.exception("%s Unexpected error in Google search: %s", log_identifier, e)
|
|
228
|
+
return f"Error executing Google search: {str(e)}"
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
web_search_google_tool_def = BuiltinTool(
|
|
232
|
+
name="web_search_google",
|
|
233
|
+
implementation=web_search_google,
|
|
234
|
+
description=(
|
|
235
|
+
"Search the web using Google Custom Search API. "
|
|
236
|
+
"Use this when you need up-to-date information from Google. "
|
|
237
|
+
"Always cite text sources using the citation format provided in your instructions. "
|
|
238
|
+
"IMPORTANT: Image results will be displayed automatically in the UI - do NOT cite images, do NOT mention image URLs, and do NOT use citation markers like [[cite:imageX]] for images in your response text."
|
|
239
|
+
),
|
|
240
|
+
category=CATEGORY_NAME,
|
|
241
|
+
category_description=CATEGORY_DESCRIPTION,
|
|
242
|
+
required_scopes=["tool:web_search:execute"],
|
|
243
|
+
parameters={
|
|
244
|
+
"type": "object",
|
|
245
|
+
"properties": {
|
|
246
|
+
"query": {
|
|
247
|
+
"type": "string",
|
|
248
|
+
"description": "The search query"
|
|
249
|
+
},
|
|
250
|
+
"max_results": {
|
|
251
|
+
"type": "integer",
|
|
252
|
+
"description": "Maximum number of results (1-10)",
|
|
253
|
+
"minimum": 1,
|
|
254
|
+
"maximum": 10,
|
|
255
|
+
"default": 5
|
|
256
|
+
},
|
|
257
|
+
"search_type": {
|
|
258
|
+
"type": "string",
|
|
259
|
+
"enum": ["image"],
|
|
260
|
+
"description": "Set to 'image' for image search"
|
|
261
|
+
},
|
|
262
|
+
"date_restrict": {
|
|
263
|
+
"type": "string",
|
|
264
|
+
"description": "Restrict results by recency (e.g., 'd7' for last 7 days)"
|
|
265
|
+
},
|
|
266
|
+
"safe_search": {
|
|
267
|
+
"type": "string",
|
|
268
|
+
"enum": ["off", "medium", "high"],
|
|
269
|
+
"description": "Safe search level"
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
"required": ["query"]
|
|
273
|
+
},
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
tool_registry.register(web_search_google_tool_def)
|
|
277
|
+
|
|
278
|
+
log.info("Web search tools registered: web_search_google")
|
|
279
|
+
log.info("Note: For Exa, Brave, and Tavily search, use plugins from solace-agent-mesh-plugins")
|