solace-agent-mesh 1.6.1__py3-none-any.whl → 1.13.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of solace-agent-mesh might be problematic. Click here for more details.
- solace_agent_mesh/agent/adk/alembic/README +74 -0
- solace_agent_mesh/agent/adk/alembic/env.py +77 -0
- solace_agent_mesh/agent/adk/alembic/script.py.mako +28 -0
- solace_agent_mesh/agent/adk/alembic/versions/e2902798564d_adk_session_db_upgrade.py +52 -0
- solace_agent_mesh/agent/adk/alembic.ini +112 -0
- solace_agent_mesh/agent/adk/app_llm_agent.py +26 -0
- solace_agent_mesh/agent/adk/artifacts/filesystem_artifact_service.py +165 -1
- solace_agent_mesh/agent/adk/artifacts/s3_artifact_service.py +163 -0
- solace_agent_mesh/agent/adk/callbacks.py +852 -109
- solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +234 -36
- solace_agent_mesh/agent/adk/intelligent_mcp_callbacks.py +52 -5
- solace_agent_mesh/agent/adk/mcp_content_processor.py +1 -1
- solace_agent_mesh/agent/adk/models/lite_llm.py +77 -21
- solace_agent_mesh/agent/adk/models/oauth2_token_manager.py +24 -137
- solace_agent_mesh/agent/adk/runner.py +85 -20
- solace_agent_mesh/agent/adk/schema_migration.py +88 -0
- solace_agent_mesh/agent/adk/services.py +94 -18
- solace_agent_mesh/agent/adk/setup.py +281 -65
- solace_agent_mesh/agent/adk/stream_parser.py +231 -37
- solace_agent_mesh/agent/adk/tool_wrapper.py +3 -0
- solace_agent_mesh/agent/protocol/event_handlers.py +472 -137
- solace_agent_mesh/agent/proxies/a2a/app.py +3 -2
- solace_agent_mesh/agent/proxies/a2a/component.py +572 -75
- solace_agent_mesh/agent/proxies/a2a/config.py +80 -4
- solace_agent_mesh/agent/proxies/base/app.py +3 -2
- solace_agent_mesh/agent/proxies/base/component.py +188 -22
- solace_agent_mesh/agent/proxies/base/proxy_task_context.py +3 -1
- solace_agent_mesh/agent/sac/app.py +91 -3
- solace_agent_mesh/agent/sac/component.py +591 -157
- solace_agent_mesh/agent/sac/patch_adk.py +8 -16
- solace_agent_mesh/agent/sac/task_execution_context.py +146 -4
- solace_agent_mesh/agent/tools/__init__.py +3 -0
- solace_agent_mesh/agent/tools/audio_tools.py +3 -3
- solace_agent_mesh/agent/tools/builtin_artifact_tools.py +710 -171
- solace_agent_mesh/agent/tools/deep_research_tools.py +2161 -0
- solace_agent_mesh/agent/tools/dynamic_tool.py +2 -0
- solace_agent_mesh/agent/tools/peer_agent_tool.py +82 -15
- solace_agent_mesh/agent/tools/time_tools.py +126 -0
- solace_agent_mesh/agent/tools/tool_config_types.py +57 -2
- solace_agent_mesh/agent/tools/web_search_tools.py +279 -0
- solace_agent_mesh/agent/tools/web_tools.py +125 -17
- solace_agent_mesh/agent/utils/artifact_helpers.py +248 -6
- solace_agent_mesh/agent/utils/context_helpers.py +17 -0
- solace_agent_mesh/assets/docs/404.html +6 -6
- solace_agent_mesh/assets/docs/assets/css/{styles.906a1503.css → styles.8162edfb.css} +1 -1
- solace_agent_mesh/assets/docs/assets/js/05749d90.19ac4f35.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/15ba94aa.e186750d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/15e40e79.434bb30f.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/17896441.e612dfb4.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2279.550aa580.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/{17896441.a5e82f9b.js.LICENSE.txt → 2279.550aa580.js.LICENSE.txt} +6 -0
- solace_agent_mesh/assets/docs/assets/js/240a0364.83e37aa8.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2987107d.a80604f9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2e32b5e0.2f0db237.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3a6c6137.7e61915d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ac1795d.7f7ab1c1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ff0015d.e53c9b78.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/41adc471.0e95b87c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4667dc50.bf2ad456.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/49eed117.493d6f99.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{509e993c.4c7a1a6d.js → 509e993c.a1fbf45a.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/547e15cc.8e6da617.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/55b7b518.29d6e75d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5b8d9c11.d4eb37b8.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.1ee87753.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/60702c0e.a8bdd79b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/631738c7.fa471607.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/64195356.09dbd087.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/66d4869e.30340bd3.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6a520c9d.b6e3f2ce.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6aaedf65.7253541d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.a5b36a60.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6d84eae0.fd23ba4a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/71da7b71.374b9d54.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/729898df.7249e9fd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/7e294c01.7c5f6906.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8024126c.e3467286.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/81a99df0.7ed65d45.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/82fbfb93.161823a5.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8b032486.91a91afc.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/924ffdeb.975e428a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/94e8668d.16083b3f.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9bb13469.4523ae20.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/a7d42657.a956689d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/a94703ab.3e5fbcb3.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ab9708a8.3e563275.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ad87452a.9d73dad6.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/c93cbaa0.0e0d8baf.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/cab03b5b.6a073091.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/cbe2e9ea.07e170dd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/da0b5bad.b62f7b08.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/dd817ffc.c37a755e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/dd81e2b8.b682e9c2.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/de915948.44a432bc.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e04b235d.06d23db6.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e1b6eeb4.deb2b62e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e3d9abda.1476f570.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e6f9706b.acc800d3.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e92d0134.c147a429.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ee0c2fe7.94d0a351.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f284c35a.cc97854c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ff4d71f2.74710fc1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.d634009f.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.27bb82a7.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +68 -68
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/artifact-management/index.html +50 -50
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/audio-tools/index.html +42 -42
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/data-analysis-tools/index.html +55 -55
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/embeds/index.html +82 -68
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/image-tools/index.html +81 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/index.html +67 -50
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/research-tools/index.html +136 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/cli/index.html +178 -144
- solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +43 -42
- solace_agent_mesh/assets/docs/docs/documentation/components/index.html +20 -18
- solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +23 -23
- solace_agent_mesh/assets/docs/docs/documentation/components/platform-service/index.html +33 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +45 -45
- solace_agent_mesh/assets/docs/docs/documentation/components/projects/index.html +182 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/prompts/index.html +147 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/proxies/index.html +208 -125
- solace_agent_mesh/assets/docs/docs/documentation/components/speech/index.html +52 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +28 -49
- solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +29 -30
- solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +14 -14
- solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes/index.html +47 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes/kubernetes-deployment-guide/index.html +197 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/logging/index.html +90 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +17 -16
- solace_agent_mesh/assets/docs/docs/documentation/deploying/proxy_configuration/index.html +49 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-agents/index.html +38 -38
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-gateways/index.html +162 -171
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-python-tools/index.html +67 -49
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +17 -17
- solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +51 -51
- solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +22 -22
- solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +27 -27
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/bedrock-agents/index.html +135 -135
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/custom-agent/index.html +66 -66
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/event-mesh-gateway/index.html +51 -51
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mcp-integration/index.html +50 -38
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mongodb-integration/index.html +86 -86
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rag-integration/index.html +51 -51
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rest-gateway/index.html +24 -24
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +30 -30
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/sql-database/index.html +44 -44
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/teams-integration/index.html +115 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/agent-builder/index.html +86 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/connectors/index.html +67 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +23 -19
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +40 -37
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/openapi-tools/index.html +324 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +112 -87
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/secure-user-delegated-access/index.html +440 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +87 -64
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/wheel-installation/index.html +62 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/architecture/index.html +44 -44
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +39 -37
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +30 -30
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +18 -18
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/vibe_coding/index.html +62 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/artifact-storage/index.html +311 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +39 -42
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +14 -14
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +27 -25
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +69 -69
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +72 -72
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/session-storage/index.html +251 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/user-feedback/index.html +88 -0
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-gateway-upgrade-to-0.3.0/index.html +42 -42
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-technical-migration-map/index.html +20 -20
- solace_agent_mesh/assets/docs/docs/documentation/migrations/platform-service-split/index.html +85 -0
- solace_agent_mesh/assets/docs/lunr-index-1768329217460.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1768329217460.json +1 -0
- solace_agent_mesh/assets/docs/search-doc.json +1 -1
- solace_agent_mesh/assets/docs/sitemap.xml +1 -1
- solace_agent_mesh/cli/__init__.py +1 -1
- solace_agent_mesh/cli/commands/add_cmd/__init__.py +3 -1
- solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +6 -1
- solace_agent_mesh/cli/commands/add_cmd/proxy_cmd.py +100 -0
- solace_agent_mesh/cli/commands/docs_cmd.py +4 -1
- solace_agent_mesh/cli/commands/eval_cmd.py +1 -1
- solace_agent_mesh/cli/commands/init_cmd/__init__.py +15 -0
- solace_agent_mesh/cli/commands/init_cmd/directory_step.py +1 -1
- solace_agent_mesh/cli/commands/init_cmd/env_step.py +30 -3
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +3 -4
- solace_agent_mesh/cli/commands/init_cmd/platform_service_step.py +85 -0
- solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +16 -3
- solace_agent_mesh/cli/commands/plugin_cmd/add_cmd.py +2 -1
- solace_agent_mesh/cli/commands/plugin_cmd/catalog_cmd.py +1 -0
- solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +3 -3
- solace_agent_mesh/cli/commands/run_cmd.py +64 -49
- solace_agent_mesh/cli/commands/tools_cmd.py +315 -0
- solace_agent_mesh/cli/main.py +15 -0
- solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-BTf6dqwp.js → authCallback-KnKMP_vb.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/client-DpBL2stg.js +25 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-Cd498TV2.js +435 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-rSf8Vu29.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/vendor-CGk8Suyh.js +565 -0
- solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -3
- solace_agent_mesh/client/webui/frontend/static/index.html +4 -4
- solace_agent_mesh/client/webui/frontend/static/mockServiceWorker.js +336 -0
- solace_agent_mesh/client/webui/frontend/static/ui-version.json +6 -0
- solace_agent_mesh/common/a2a/events.py +2 -1
- solace_agent_mesh/common/a2a/protocol.py +5 -0
- solace_agent_mesh/common/a2a/types.py +2 -1
- solace_agent_mesh/common/a2a_spec/schemas/artifact_creation_progress.json +23 -6
- solace_agent_mesh/common/a2a_spec/schemas/feedback_event.json +51 -0
- solace_agent_mesh/common/agent_registry.py +38 -11
- solace_agent_mesh/common/data_parts.py +144 -4
- solace_agent_mesh/common/error_handlers.py +83 -0
- solace_agent_mesh/common/exceptions.py +24 -0
- solace_agent_mesh/common/oauth/__init__.py +17 -0
- solace_agent_mesh/common/oauth/oauth_client.py +408 -0
- solace_agent_mesh/common/oauth/utils.py +50 -0
- solace_agent_mesh/common/rag_dto.py +156 -0
- solace_agent_mesh/common/sac/sam_component_base.py +97 -19
- solace_agent_mesh/common/sam_events/event_service.py +2 -2
- solace_agent_mesh/common/services/employee_service.py +1 -1
- solace_agent_mesh/common/utils/embeds/constants.py +1 -0
- solace_agent_mesh/common/utils/embeds/converter.py +1 -8
- solace_agent_mesh/common/utils/embeds/modifiers.py +4 -28
- solace_agent_mesh/common/utils/embeds/resolver.py +152 -31
- solace_agent_mesh/common/utils/embeds/types.py +9 -0
- solace_agent_mesh/common/utils/log_formatters.py +20 -0
- solace_agent_mesh/common/utils/mime_helpers.py +12 -5
- solace_agent_mesh/common/utils/pydantic_utils.py +90 -3
- solace_agent_mesh/common/utils/rbac_utils.py +69 -0
- solace_agent_mesh/common/utils/templates/__init__.py +8 -0
- solace_agent_mesh/common/utils/templates/liquid_renderer.py +210 -0
- solace_agent_mesh/common/utils/templates/template_resolver.py +161 -0
- solace_agent_mesh/config_portal/backend/common.py +12 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-CljP4_mv.js +103 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/{components-Rk0n-9cK.js → components-CaC6hG8d.js} +22 -22
- solace_agent_mesh/config_portal/frontend/static/client/assets/{entry.client-mvZjNKiz.js → entry.client-H_TM0YBt.js} +3 -3
- solace_agent_mesh/config_portal/frontend/static/client/assets/{index-DzNKzXrc.js → index-CnFykb2v.js} +16 -16
- solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-f8439d40.js +1 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-BIMqslJB.css +1 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-mJmTIdIk.js +10 -0
- solace_agent_mesh/config_portal/frontend/static/client/index.html +3 -3
- solace_agent_mesh/core_a2a/service.py +3 -2
- solace_agent_mesh/gateway/adapter/__init__.py +1 -0
- solace_agent_mesh/gateway/adapter/base.py +170 -0
- solace_agent_mesh/gateway/adapter/types.py +230 -0
- solace_agent_mesh/gateway/base/app.py +39 -2
- solace_agent_mesh/gateway/base/auth_interface.py +103 -0
- solace_agent_mesh/gateway/base/component.py +1027 -151
- solace_agent_mesh/gateway/generic/__init__.py +1 -0
- solace_agent_mesh/gateway/generic/app.py +50 -0
- solace_agent_mesh/gateway/generic/component.py +894 -0
- solace_agent_mesh/gateway/http_sse/alembic/env.py +0 -7
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_project_users_table.py +72 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_soft_delete_and_search.py +109 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_default_agent_to_projects.py +26 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_projects_table.py +135 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251108_create_prompt_tables_with_sharing.py +154 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251115_add_parent_task_id.py +32 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251126_add_background_task_fields.py +47 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251202_add_versioned_fields_to_prompts.py +52 -0
- solace_agent_mesh/gateway/http_sse/alembic.ini +0 -36
- solace_agent_mesh/gateway/http_sse/app.py +40 -11
- solace_agent_mesh/gateway/http_sse/component.py +285 -160
- solace_agent_mesh/gateway/http_sse/dependencies.py +149 -114
- solace_agent_mesh/gateway/http_sse/main.py +68 -450
- solace_agent_mesh/gateway/http_sse/repository/__init__.py +19 -1
- solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +2 -2
- solace_agent_mesh/gateway/http_sse/repository/entities/project.py +81 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/project_user.py +47 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/session.py +26 -3
- solace_agent_mesh/gateway/http_sse/repository/entities/task.py +7 -0
- solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +47 -0
- solace_agent_mesh/gateway/http_sse/repository/interfaces.py +114 -6
- solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +13 -0
- solace_agent_mesh/gateway/http_sse/repository/models/project_model.py +51 -0
- solace_agent_mesh/gateway/http_sse/repository/models/project_user_model.py +75 -0
- solace_agent_mesh/gateway/http_sse/repository/models/prompt_model.py +159 -0
- solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +8 -2
- solace_agent_mesh/gateway/http_sse/repository/models/task_model.py +8 -1
- solace_agent_mesh/gateway/http_sse/repository/project_repository.py +172 -0
- solace_agent_mesh/gateway/http_sse/repository/project_user_repository.py +186 -0
- solace_agent_mesh/gateway/http_sse/repository/session_repository.py +177 -11
- solace_agent_mesh/gateway/http_sse/repository/task_repository.py +86 -2
- solace_agent_mesh/gateway/http_sse/routers/agent_cards.py +38 -7
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +256 -58
- solace_agent_mesh/gateway/http_sse/routers/auth.py +168 -134
- solace_agent_mesh/gateway/http_sse/routers/config.py +302 -8
- solace_agent_mesh/gateway/http_sse/routers/dto/project_dto.py +69 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/prompt_dto.py +255 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/project_requests.py +48 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +14 -1
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/base_responses.py +1 -1
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/project_responses.py +31 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +5 -2
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/version_responses.py +31 -0
- solace_agent_mesh/gateway/http_sse/routers/feedback.py +133 -2
- solace_agent_mesh/gateway/http_sse/routers/people.py +2 -2
- solace_agent_mesh/gateway/http_sse/routers/projects.py +768 -0
- solace_agent_mesh/gateway/http_sse/routers/prompts.py +1416 -0
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +167 -7
- solace_agent_mesh/gateway/http_sse/routers/speech.py +355 -0
- solace_agent_mesh/gateway/http_sse/routers/sse.py +131 -8
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +670 -18
- solace_agent_mesh/gateway/http_sse/routers/users.py +1 -1
- solace_agent_mesh/gateway/http_sse/routers/version.py +343 -0
- solace_agent_mesh/gateway/http_sse/routers/visualization.py +92 -9
- solace_agent_mesh/gateway/http_sse/services/audio_service.py +1227 -0
- solace_agent_mesh/gateway/http_sse/services/background_task_monitor.py +186 -0
- solace_agent_mesh/gateway/http_sse/services/data_retention_service.py +1 -1
- solace_agent_mesh/gateway/http_sse/services/feedback_service.py +1 -1
- solace_agent_mesh/gateway/http_sse/services/project_service.py +930 -0
- solace_agent_mesh/gateway/http_sse/services/prompt_builder_assistant.py +303 -0
- solace_agent_mesh/gateway/http_sse/services/session_service.py +361 -12
- solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +354 -4
- solace_agent_mesh/gateway/http_sse/session_manager.py +15 -15
- solace_agent_mesh/gateway/http_sse/sse_manager.py +286 -166
- solace_agent_mesh/gateway/http_sse/utils/artifact_copy_utils.py +370 -0
- solace_agent_mesh/gateway/http_sse/utils/stim_utils.py +41 -1
- solace_agent_mesh/services/__init__.py +0 -0
- solace_agent_mesh/services/platform/__init__.py +29 -0
- solace_agent_mesh/services/platform/alembic/env.py +85 -0
- solace_agent_mesh/services/platform/alembic/script.py.mako +28 -0
- solace_agent_mesh/services/platform/alembic.ini +109 -0
- solace_agent_mesh/services/platform/api/__init__.py +3 -0
- solace_agent_mesh/services/platform/api/dependencies.py +154 -0
- solace_agent_mesh/services/platform/api/main.py +314 -0
- solace_agent_mesh/services/platform/api/middleware.py +51 -0
- solace_agent_mesh/services/platform/api/routers/__init__.py +33 -0
- solace_agent_mesh/services/platform/api/routers/health_router.py +31 -0
- solace_agent_mesh/services/platform/app.py +215 -0
- solace_agent_mesh/services/platform/component.py +777 -0
- solace_agent_mesh/shared/__init__.py +14 -0
- solace_agent_mesh/shared/api/__init__.py +42 -0
- solace_agent_mesh/shared/auth/__init__.py +26 -0
- solace_agent_mesh/shared/auth/dependencies.py +204 -0
- solace_agent_mesh/shared/auth/middleware.py +347 -0
- solace_agent_mesh/shared/database/__init__.py +20 -0
- solace_agent_mesh/{gateway/http_sse/shared → shared/database}/base_repository.py +1 -1
- solace_agent_mesh/{gateway/http_sse/shared → shared/database}/database_exceptions.py +1 -1
- solace_agent_mesh/{gateway/http_sse/shared → shared/database}/database_helpers.py +1 -1
- solace_agent_mesh/shared/exceptions/__init__.py +36 -0
- solace_agent_mesh/{gateway/http_sse/shared → shared/exceptions}/exception_handlers.py +19 -5
- solace_agent_mesh/shared/utils/__init__.py +21 -0
- solace_agent_mesh/templates/logging_config_template.yaml +48 -0
- solace_agent_mesh/templates/main_orchestrator.yaml +12 -1
- solace_agent_mesh/templates/platform.yaml +49 -0
- solace_agent_mesh/templates/plugin_readme_template.md +3 -25
- solace_agent_mesh/templates/plugin_tool_config_template.yaml +109 -0
- solace_agent_mesh/templates/proxy_template.yaml +62 -0
- solace_agent_mesh/templates/webui.yaml +148 -6
- solace_agent_mesh/tools/web_search/__init__.py +18 -0
- solace_agent_mesh/tools/web_search/base.py +84 -0
- solace_agent_mesh/tools/web_search/google_search.py +247 -0
- solace_agent_mesh/tools/web_search/models.py +99 -0
- {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/METADATA +31 -12
- solace_agent_mesh-1.13.2.dist-info/RECORD +591 -0
- {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/WHEEL +1 -1
- solace_agent_mesh/agent/adk/adk_llm.txt +0 -232
- solace_agent_mesh/agent/adk/adk_llm_detail.txt +0 -566
- solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +0 -171
- solace_agent_mesh/agent/adk/models/models_llm.txt +0 -142
- solace_agent_mesh/agent/agent_llm.txt +0 -378
- solace_agent_mesh/agent/agent_llm_detail.txt +0 -1702
- solace_agent_mesh/agent/protocol/protocol_llm.txt +0 -81
- solace_agent_mesh/agent/protocol/protocol_llm_detail.txt +0 -92
- solace_agent_mesh/agent/sac/sac_llm.txt +0 -189
- solace_agent_mesh/agent/sac/sac_llm_detail.txt +0 -200
- solace_agent_mesh/agent/testing/testing_llm.txt +0 -57
- solace_agent_mesh/agent/testing/testing_llm_detail.txt +0 -68
- solace_agent_mesh/agent/tools/tools_llm.txt +0 -263
- solace_agent_mesh/agent/tools/tools_llm_detail.txt +0 -274
- solace_agent_mesh/agent/utils/utils_llm.txt +0 -138
- solace_agent_mesh/agent/utils/utils_llm_detail.txt +0 -149
- solace_agent_mesh/assets/docs/assets/js/15ba94aa.932dd2db.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/17896441.a5e82f9b.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/240a0364.7eac6021.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/2e32b5e0.33f5d75b.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/3a6c6137.f5940cfa.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/3ac1795d.76654dd9.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/3ff0015d.2be20244.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/547e15cc.2cbb060a.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/55b7b518.f2b1d1ba.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.eda4bcb2.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/631738c7.a8b1ef8b.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/6a520c9d.ba015d81.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.f4b15f3b.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/6d84eae0.4a5fbf39.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/71da7b71.38583438.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/8024126c.56e59919.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/81a99df0.07034dd9.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/82fbfb93.139a1a1f.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/924ffdeb.8095e148.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/94e8668d.b5ddb7a1.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/9bb13469.dd1c9b54.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/a94703ab.0438dbc2.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/ab9708a8.3e6dd091.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/c93cbaa0.eaff365e.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/da0b5bad.d08a9466.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/dd817ffc.0aa9630a.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/dd81e2b8.d590bc9e.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/de915948.27d6b065.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e3d9abda.6b9493d0.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e6f9706b.e74a984d.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e92d0134.cf6d6522.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f284c35a.42f59cdd.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/ff4d71f2.15b02f97.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/main.b12eac43.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.e268214e.js +0 -1
- solace_agent_mesh/assets/docs/lunr-index-1761248203150.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1761248203150.json +0 -1
- solace_agent_mesh/cli/commands/add_cmd/add_cmd_llm.txt +0 -250
- solace_agent_mesh/cli/commands/init_cmd/init_cmd_llm.txt +0 -365
- solace_agent_mesh/cli/commands/plugin_cmd/plugin_cmd_llm.txt +0 -305
- solace_agent_mesh/client/webui/frontend/static/assets/client-CaY59VuC.js +0 -25
- solace_agent_mesh/client/webui/frontend/static/assets/main-B32noGmR.js +0 -342
- solace_agent_mesh/client/webui/frontend/static/assets/main-DHJKSW1S.css +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/vendor-BEmvJSYz.js +0 -405
- solace_agent_mesh/common/a2a/a2a_llm.txt +0 -182
- solace_agent_mesh/common/a2a/a2a_llm_detail.txt +0 -193
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +0 -407
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm_detail.txt +0 -736
- solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +0 -313
- solace_agent_mesh/common/common_llm.txt +0 -251
- solace_agent_mesh/common/common_llm_detail.txt +0 -2562
- solace_agent_mesh/common/middleware/middleware_llm.txt +0 -174
- solace_agent_mesh/common/middleware/middleware_llm_detail.txt +0 -185
- solace_agent_mesh/common/sac/sac_llm.txt +0 -71
- solace_agent_mesh/common/sac/sac_llm_detail.txt +0 -82
- solace_agent_mesh/common/sam_events/sam_events_llm.txt +0 -104
- solace_agent_mesh/common/sam_events/sam_events_llm_detail.txt +0 -115
- solace_agent_mesh/common/services/providers/providers_llm.txt +0 -80
- solace_agent_mesh/common/services/services_llm.txt +0 -363
- solace_agent_mesh/common/services/services_llm_detail.txt +0 -459
- solace_agent_mesh/common/utils/embeds/embeds_llm.txt +0 -220
- solace_agent_mesh/common/utils/utils_llm.txt +0 -336
- solace_agent_mesh/common/utils/utils_llm_detail.txt +0 -572
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-ByU1X1HD.js +0 -98
- solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-61038fc6.js +0 -1
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-BWvk5-gF.js +0 -10
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-DxRwaWiE.css +0 -1
- solace_agent_mesh/core_a2a/core_a2a_llm.txt +0 -90
- solace_agent_mesh/core_a2a/core_a2a_llm_detail.txt +0 -101
- solace_agent_mesh/gateway/base/base_llm.txt +0 -224
- solace_agent_mesh/gateway/base/base_llm_detail.txt +0 -235
- solace_agent_mesh/gateway/gateway_llm.txt +0 -373
- solace_agent_mesh/gateway/gateway_llm_detail.txt +0 -3885
- solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +0 -295
- solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +0 -155
- solace_agent_mesh/gateway/http_sse/components/components_llm.txt +0 -105
- solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +0 -299
- solace_agent_mesh/gateway/http_sse/http_sse_llm_detail.txt +0 -3278
- solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +0 -263
- solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +0 -266
- solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +0 -340
- solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +0 -346
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +0 -83
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +0 -107
- solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +0 -314
- solace_agent_mesh/gateway/http_sse/services/services_llm.txt +0 -297
- solace_agent_mesh/gateway/http_sse/shared/__init__.py +0 -146
- solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +0 -285
- solace_agent_mesh/gateway/http_sse/utils/utils_llm.txt +0 -47
- solace_agent_mesh/llm.txt +0 -228
- solace_agent_mesh/llm_detail.txt +0 -2835
- solace_agent_mesh/solace_agent_mesh_llm.txt +0 -362
- solace_agent_mesh/solace_agent_mesh_llm_detail.txt +0 -8599
- solace_agent_mesh/templates/logging_config_template.ini +0 -45
- solace_agent_mesh/templates/templates_llm.txt +0 -147
- solace_agent_mesh-1.6.1.dist-info/RECORD +0 -525
- /solace_agent_mesh/assets/docs/assets/js/{main.b12eac43.js.LICENSE.txt → main.d634009f.js.LICENSE.txt} +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/api}/auth_utils.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/api}/pagination.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/api}/response_utils.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/exceptions}/error_dto.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/exceptions}/exceptions.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/enums.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/timestamp_utils.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/types.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/utils.py +0 -0
- {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
"""Pure OAuth 2.0 protocol implementation.
|
|
2
|
+
|
|
3
|
+
This module provides stateless OAuth 2.0 flow implementations without any
|
|
4
|
+
caching, retry logic, or domain-specific behavior. It implements the core
|
|
5
|
+
OAuth 2.0 flows as defined in RFC 6749.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import logging
|
|
10
|
+
import random
|
|
11
|
+
from typing import Any, Dict, Optional, Union
|
|
12
|
+
|
|
13
|
+
import httpx
|
|
14
|
+
|
|
15
|
+
from .utils import calculate_expires_at
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class OAuth2Client:
|
|
21
|
+
"""Pure OAuth 2.0 protocol implementation.
|
|
22
|
+
|
|
23
|
+
This class provides stateless OAuth 2.0 flow implementations without any
|
|
24
|
+
caching, retry logic, or domain-specific behavior. Each method makes a
|
|
25
|
+
single HTTP request to the token endpoint and returns the parsed response.
|
|
26
|
+
|
|
27
|
+
All OAuth 2.0 flows follow RFC 6749 specification.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
async def fetch_client_credentials_token(
|
|
31
|
+
self,
|
|
32
|
+
token_url: str,
|
|
33
|
+
client_id: str,
|
|
34
|
+
client_secret: str,
|
|
35
|
+
scope: Optional[str] = None,
|
|
36
|
+
verify: Union[bool, str] = True,
|
|
37
|
+
timeout: float = 30.0,
|
|
38
|
+
) -> Dict[str, Any]:
|
|
39
|
+
"""Execute OAuth 2.0 Client Credentials flow (RFC 6749 Section 4.4).
|
|
40
|
+
|
|
41
|
+
This flow is used for server-to-server authentication where the client
|
|
42
|
+
acts on its own behalf rather than on behalf of a user.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
token_url: OAuth 2.0 token endpoint URL
|
|
46
|
+
client_id: OAuth 2.0 client identifier
|
|
47
|
+
client_secret: OAuth 2.0 client secret
|
|
48
|
+
scope: Optional space-separated list of scopes
|
|
49
|
+
verify: SSL certificate verification (True, False, or path to CA bundle)
|
|
50
|
+
timeout: Request timeout in seconds
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
Token response dictionary containing:
|
|
54
|
+
- access_token: The access token string
|
|
55
|
+
- expires_in: Token lifetime in seconds
|
|
56
|
+
- token_type: Token type (usually "Bearer")
|
|
57
|
+
- scope: Granted scopes (optional)
|
|
58
|
+
- expires_at: Unix timestamp when token expires (added by this method)
|
|
59
|
+
|
|
60
|
+
Raises:
|
|
61
|
+
httpx.HTTPStatusError: If the token request fails
|
|
62
|
+
ValueError: If the response is missing required fields
|
|
63
|
+
"""
|
|
64
|
+
payload = {
|
|
65
|
+
"grant_type": "client_credentials",
|
|
66
|
+
"client_id": client_id,
|
|
67
|
+
"client_secret": client_secret,
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if scope:
|
|
71
|
+
payload["scope"] = scope
|
|
72
|
+
|
|
73
|
+
return await self._execute_token_request(
|
|
74
|
+
token_url=token_url,
|
|
75
|
+
payload=payload,
|
|
76
|
+
verify=verify,
|
|
77
|
+
timeout=timeout,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
async def fetch_authorization_code_token(
|
|
81
|
+
self,
|
|
82
|
+
token_url: str,
|
|
83
|
+
client_id: str,
|
|
84
|
+
client_secret: str,
|
|
85
|
+
code: str,
|
|
86
|
+
redirect_uri: str,
|
|
87
|
+
verify: Union[bool, str] = True,
|
|
88
|
+
timeout: float = 30.0,
|
|
89
|
+
) -> Dict[str, Any]:
|
|
90
|
+
"""Execute OAuth 2.0 Authorization Code flow (RFC 6749 Section 4.1).
|
|
91
|
+
|
|
92
|
+
This flow is used for user-delegated authentication where the application
|
|
93
|
+
acts on behalf of a user who has granted permission.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
token_url: OAuth 2.0 token endpoint URL
|
|
97
|
+
client_id: OAuth 2.0 client identifier
|
|
98
|
+
client_secret: OAuth 2.0 client secret
|
|
99
|
+
code: Authorization code received from authorization server
|
|
100
|
+
redirect_uri: Redirect URI used in authorization request (must match)
|
|
101
|
+
verify: SSL certificate verification (True, False, or path to CA bundle)
|
|
102
|
+
timeout: Request timeout in seconds
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
Token response dictionary containing:
|
|
106
|
+
- access_token: The access token string
|
|
107
|
+
- expires_in: Token lifetime in seconds
|
|
108
|
+
- refresh_token: Refresh token for obtaining new access tokens (optional)
|
|
109
|
+
- token_type: Token type (usually "Bearer")
|
|
110
|
+
- scope: Granted scopes (optional)
|
|
111
|
+
- expires_at: Unix timestamp when token expires (added by this method)
|
|
112
|
+
|
|
113
|
+
Raises:
|
|
114
|
+
httpx.HTTPStatusError: If the token request fails
|
|
115
|
+
ValueError: If the response is missing required fields
|
|
116
|
+
"""
|
|
117
|
+
payload = {
|
|
118
|
+
"grant_type": "authorization_code",
|
|
119
|
+
"code": code,
|
|
120
|
+
"redirect_uri": redirect_uri,
|
|
121
|
+
"client_id": client_id,
|
|
122
|
+
"client_secret": client_secret,
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return await self._execute_token_request(
|
|
126
|
+
token_url=token_url,
|
|
127
|
+
payload=payload,
|
|
128
|
+
verify=verify,
|
|
129
|
+
timeout=timeout,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
async def fetch_refresh_token(
|
|
133
|
+
self,
|
|
134
|
+
token_url: str,
|
|
135
|
+
client_id: str,
|
|
136
|
+
client_secret: str,
|
|
137
|
+
refresh_token: str,
|
|
138
|
+
scope: Optional[str] = None,
|
|
139
|
+
verify: Union[bool, str] = True,
|
|
140
|
+
timeout: float = 30.0,
|
|
141
|
+
) -> Dict[str, Any]:
|
|
142
|
+
"""Execute OAuth 2.0 Refresh Token flow (RFC 6749 Section 6).
|
|
143
|
+
|
|
144
|
+
This flow is used to obtain a new access token using a refresh token,
|
|
145
|
+
without requiring user interaction.
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
token_url: OAuth 2.0 token endpoint URL
|
|
149
|
+
client_id: OAuth 2.0 client identifier
|
|
150
|
+
client_secret: OAuth 2.0 client secret
|
|
151
|
+
refresh_token: The refresh token
|
|
152
|
+
scope: Optional space-separated list of scopes (must not exceed original grant)
|
|
153
|
+
verify: SSL certificate verification (True, False, or path to CA bundle)
|
|
154
|
+
timeout: Request timeout in seconds
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
Token response dictionary containing:
|
|
158
|
+
- access_token: The new access token string
|
|
159
|
+
- expires_in: Token lifetime in seconds
|
|
160
|
+
- refresh_token: New refresh token (optional, may be same as input)
|
|
161
|
+
- token_type: Token type (usually "Bearer")
|
|
162
|
+
- scope: Granted scopes (optional)
|
|
163
|
+
- expires_at: Unix timestamp when token expires (added by this method)
|
|
164
|
+
|
|
165
|
+
Raises:
|
|
166
|
+
httpx.HTTPStatusError: If the token request fails
|
|
167
|
+
ValueError: If the response is missing required fields
|
|
168
|
+
"""
|
|
169
|
+
payload = {
|
|
170
|
+
"grant_type": "refresh_token",
|
|
171
|
+
"refresh_token": refresh_token,
|
|
172
|
+
"client_id": client_id,
|
|
173
|
+
"client_secret": client_secret,
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if scope:
|
|
177
|
+
payload["scope"] = scope
|
|
178
|
+
|
|
179
|
+
return await self._execute_token_request(
|
|
180
|
+
token_url=token_url,
|
|
181
|
+
payload=payload,
|
|
182
|
+
verify=verify,
|
|
183
|
+
timeout=timeout,
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
async def _execute_token_request(
|
|
187
|
+
self,
|
|
188
|
+
token_url: str,
|
|
189
|
+
payload: Dict[str, str],
|
|
190
|
+
verify: Union[bool, str],
|
|
191
|
+
timeout: float,
|
|
192
|
+
) -> Dict[str, Any]:
|
|
193
|
+
"""Execute a token request to the OAuth 2.0 token endpoint.
|
|
194
|
+
|
|
195
|
+
This is the core HTTP operation shared by all OAuth flows.
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
token_url: OAuth 2.0 token endpoint URL
|
|
199
|
+
payload: Request payload (grant-specific parameters)
|
|
200
|
+
verify: SSL certificate verification
|
|
201
|
+
timeout: Request timeout in seconds
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
Token response dictionary with added expires_at field
|
|
205
|
+
|
|
206
|
+
Raises:
|
|
207
|
+
httpx.HTTPStatusError: If the token request fails
|
|
208
|
+
ValueError: If the response is missing required fields
|
|
209
|
+
"""
|
|
210
|
+
headers = {
|
|
211
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
212
|
+
"Accept": "application/json",
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async with httpx.AsyncClient(verify=verify) as client:
|
|
216
|
+
response = await client.post(
|
|
217
|
+
token_url,
|
|
218
|
+
data=payload,
|
|
219
|
+
headers=headers,
|
|
220
|
+
timeout=timeout,
|
|
221
|
+
)
|
|
222
|
+
response.raise_for_status()
|
|
223
|
+
|
|
224
|
+
token_data = response.json()
|
|
225
|
+
|
|
226
|
+
# Validate response contains required fields
|
|
227
|
+
if "access_token" not in token_data:
|
|
228
|
+
raise ValueError(
|
|
229
|
+
f"Token response missing 'access_token' field. "
|
|
230
|
+
f"Response keys: {list(token_data.keys())}"
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
# Add expiration timestamp for convenience
|
|
234
|
+
expires_in = token_data.get("expires_in", 3600) # Default 1 hour
|
|
235
|
+
token_data["expires_at"] = calculate_expires_at(expires_in)
|
|
236
|
+
|
|
237
|
+
return token_data
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
class OAuth2RetryClient:
|
|
241
|
+
"""OAuth 2.0 client with configurable retry logic.
|
|
242
|
+
|
|
243
|
+
This class wraps OAuth2Client and adds retry logic with exponential backoff
|
|
244
|
+
for handling transient failures. Retry behavior:
|
|
245
|
+
- 4xx errors (client errors): No retry - fail immediately
|
|
246
|
+
- 5xx errors (server errors): Retry with exponential backoff
|
|
247
|
+
- Network errors: Retry with exponential backoff
|
|
248
|
+
"""
|
|
249
|
+
|
|
250
|
+
def __init__(
|
|
251
|
+
self,
|
|
252
|
+
max_retries: int = 0,
|
|
253
|
+
backoff_base: float = 2.0,
|
|
254
|
+
backoff_jitter: bool = True,
|
|
255
|
+
):
|
|
256
|
+
"""Initialize the retry client.
|
|
257
|
+
|
|
258
|
+
Args:
|
|
259
|
+
max_retries: Maximum number of retry attempts (0 = no retries)
|
|
260
|
+
backoff_base: Base for exponential backoff (delay = base^attempt)
|
|
261
|
+
backoff_jitter: Whether to add random jitter to backoff delay
|
|
262
|
+
"""
|
|
263
|
+
self._base_client = OAuth2Client()
|
|
264
|
+
self._max_retries = max_retries
|
|
265
|
+
self._backoff_base = backoff_base
|
|
266
|
+
self._backoff_jitter = backoff_jitter
|
|
267
|
+
|
|
268
|
+
async def fetch_client_credentials_token(
|
|
269
|
+
self,
|
|
270
|
+
token_url: str,
|
|
271
|
+
client_id: str,
|
|
272
|
+
client_secret: str,
|
|
273
|
+
scope: Optional[str] = None,
|
|
274
|
+
verify: Union[bool, str] = True,
|
|
275
|
+
timeout: float = 30.0,
|
|
276
|
+
) -> Dict[str, Any]:
|
|
277
|
+
"""Execute Client Credentials flow with retry logic.
|
|
278
|
+
|
|
279
|
+
See OAuth2Client.fetch_client_credentials_token for parameter details.
|
|
280
|
+
"""
|
|
281
|
+
return await self._execute_with_retry(
|
|
282
|
+
self._base_client.fetch_client_credentials_token,
|
|
283
|
+
token_url=token_url,
|
|
284
|
+
client_id=client_id,
|
|
285
|
+
client_secret=client_secret,
|
|
286
|
+
scope=scope,
|
|
287
|
+
verify=verify,
|
|
288
|
+
timeout=timeout,
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
async def fetch_authorization_code_token(
|
|
292
|
+
self,
|
|
293
|
+
token_url: str,
|
|
294
|
+
client_id: str,
|
|
295
|
+
client_secret: str,
|
|
296
|
+
code: str,
|
|
297
|
+
redirect_uri: str,
|
|
298
|
+
verify: Union[bool, str] = True,
|
|
299
|
+
timeout: float = 30.0,
|
|
300
|
+
) -> Dict[str, Any]:
|
|
301
|
+
"""Execute Authorization Code flow with retry logic.
|
|
302
|
+
|
|
303
|
+
See OAuth2Client.fetch_authorization_code_token for parameter details.
|
|
304
|
+
"""
|
|
305
|
+
return await self._execute_with_retry(
|
|
306
|
+
self._base_client.fetch_authorization_code_token,
|
|
307
|
+
token_url=token_url,
|
|
308
|
+
client_id=client_id,
|
|
309
|
+
client_secret=client_secret,
|
|
310
|
+
code=code,
|
|
311
|
+
redirect_uri=redirect_uri,
|
|
312
|
+
verify=verify,
|
|
313
|
+
timeout=timeout,
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
async def fetch_refresh_token(
|
|
317
|
+
self,
|
|
318
|
+
token_url: str,
|
|
319
|
+
client_id: str,
|
|
320
|
+
client_secret: str,
|
|
321
|
+
refresh_token: str,
|
|
322
|
+
scope: Optional[str] = None,
|
|
323
|
+
verify: Union[bool, str] = True,
|
|
324
|
+
timeout: float = 30.0,
|
|
325
|
+
) -> Dict[str, Any]:
|
|
326
|
+
"""Execute Refresh Token flow with retry logic.
|
|
327
|
+
|
|
328
|
+
See OAuth2Client.fetch_refresh_token for parameter details.
|
|
329
|
+
"""
|
|
330
|
+
return await self._execute_with_retry(
|
|
331
|
+
self._base_client.fetch_refresh_token,
|
|
332
|
+
token_url=token_url,
|
|
333
|
+
client_id=client_id,
|
|
334
|
+
client_secret=client_secret,
|
|
335
|
+
refresh_token=refresh_token,
|
|
336
|
+
scope=scope,
|
|
337
|
+
verify=verify,
|
|
338
|
+
timeout=timeout,
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
async def _execute_with_retry(self, func, **kwargs) -> Dict[str, Any]:
|
|
342
|
+
"""Execute a function with retry logic.
|
|
343
|
+
|
|
344
|
+
Args:
|
|
345
|
+
func: Async function to execute
|
|
346
|
+
**kwargs: Arguments to pass to the function
|
|
347
|
+
|
|
348
|
+
Returns:
|
|
349
|
+
Result from the function
|
|
350
|
+
|
|
351
|
+
Raises:
|
|
352
|
+
Exception: Last exception if all retries are exhausted
|
|
353
|
+
"""
|
|
354
|
+
last_exception = None
|
|
355
|
+
|
|
356
|
+
for attempt in range(self._max_retries + 1):
|
|
357
|
+
try:
|
|
358
|
+
return await func(**kwargs)
|
|
359
|
+
|
|
360
|
+
except httpx.HTTPStatusError as e:
|
|
361
|
+
last_exception = e
|
|
362
|
+
# Don't retry on 4xx errors (client errors)
|
|
363
|
+
if 400 <= e.response.status_code < 500:
|
|
364
|
+
logger.error(
|
|
365
|
+
"OAuth token request failed with client error %d: %s",
|
|
366
|
+
e.response.status_code,
|
|
367
|
+
e.response.text,
|
|
368
|
+
)
|
|
369
|
+
raise
|
|
370
|
+
|
|
371
|
+
logger.warning(
|
|
372
|
+
"OAuth token request failed with status %d (attempt %d/%d): %s",
|
|
373
|
+
e.response.status_code,
|
|
374
|
+
attempt + 1,
|
|
375
|
+
self._max_retries + 1,
|
|
376
|
+
e.response.text,
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
except httpx.RequestError as e:
|
|
380
|
+
last_exception = e
|
|
381
|
+
logger.warning(
|
|
382
|
+
"OAuth token request failed (attempt %d/%d): %s",
|
|
383
|
+
attempt + 1,
|
|
384
|
+
self._max_retries + 1,
|
|
385
|
+
str(e),
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
except Exception as e:
|
|
389
|
+
last_exception = e
|
|
390
|
+
logger.error("Unexpected error during OAuth token fetch: %s", str(e))
|
|
391
|
+
raise
|
|
392
|
+
|
|
393
|
+
# Exponential backoff with optional jitter
|
|
394
|
+
if attempt < self._max_retries:
|
|
395
|
+
delay = self._backoff_base**attempt
|
|
396
|
+
if self._backoff_jitter:
|
|
397
|
+
delay += random.uniform(0, 1)
|
|
398
|
+
logger.info("Retrying OAuth token request in %.2f seconds", delay)
|
|
399
|
+
await asyncio.sleep(delay)
|
|
400
|
+
|
|
401
|
+
# All retries exhausted
|
|
402
|
+
logger.error(
|
|
403
|
+
"OAuth token request failed after %d attempts", self._max_retries + 1
|
|
404
|
+
)
|
|
405
|
+
if last_exception:
|
|
406
|
+
raise last_exception
|
|
407
|
+
else:
|
|
408
|
+
raise RuntimeError("OAuth token request failed after all retries")
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""Utility functions for OAuth 2.0 operations."""
|
|
2
|
+
|
|
3
|
+
import time
|
|
4
|
+
from urllib.parse import urlparse
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def validate_https_url(url: str) -> None:
|
|
8
|
+
"""Validate that a URL uses HTTPS scheme.
|
|
9
|
+
|
|
10
|
+
OAuth 2.0 requires HTTPS for security when transmitting credentials.
|
|
11
|
+
|
|
12
|
+
Args:
|
|
13
|
+
url: The URL to validate
|
|
14
|
+
|
|
15
|
+
Raises:
|
|
16
|
+
ValueError: If the URL does not use HTTPS scheme
|
|
17
|
+
"""
|
|
18
|
+
parsed_url = urlparse(url)
|
|
19
|
+
if parsed_url.scheme != "https":
|
|
20
|
+
raise ValueError(
|
|
21
|
+
f"OAuth 2.0 URLs must use HTTPS for security. "
|
|
22
|
+
f"Got scheme: {parsed_url.scheme}"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def calculate_expires_at(expires_in: int) -> float:
|
|
27
|
+
"""Calculate expiration timestamp from expires_in seconds.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
expires_in: Number of seconds until token expires
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
Unix timestamp (float) when the token will expire
|
|
34
|
+
"""
|
|
35
|
+
return time.time() + expires_in
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def is_token_expired(expires_at: float, buffer_seconds: int = 0) -> bool:
|
|
39
|
+
"""Check if a token is expired or will expire within buffer time.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
expires_at: Unix timestamp when token expires
|
|
43
|
+
buffer_seconds: Optional buffer to consider token expired early
|
|
44
|
+
(useful for proactive refresh)
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
True if token is expired or within buffer time of expiring
|
|
48
|
+
"""
|
|
49
|
+
current_time = time.time()
|
|
50
|
+
return current_time >= (expires_at - buffer_seconds)
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pydantic models for RAG (Retrieval-Augmented Generation) metadata.
|
|
3
|
+
Handles automatic conversion between snake_case (backend) and camelCase (frontend).
|
|
4
|
+
|
|
5
|
+
This module is placed in common/ to be shared across different components
|
|
6
|
+
(agent tools, gateway, etc.) without creating cross-layer dependencies.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Any, Dict, List, Optional
|
|
10
|
+
from pydantic import BaseModel, Field
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class RAGSourceResponse(BaseModel):
|
|
14
|
+
"""Schema for RAG source with automatic snake_case to camelCase conversion"""
|
|
15
|
+
citation_id: str = Field(..., alias="citationId", description="Unique citation ID")
|
|
16
|
+
file_id: Optional[str] = Field(None, alias="fileId", description="File identifier")
|
|
17
|
+
filename: Optional[str] = Field(None, description="Filename or title")
|
|
18
|
+
title: Optional[str] = Field(None, description="Source title")
|
|
19
|
+
source_type: Optional[str] = Field(None, alias="sourceType", description="Type of source (web, kb, etc.)")
|
|
20
|
+
source_url: Optional[str] = Field(None, alias="sourceUrl", description="Source URL")
|
|
21
|
+
url: Optional[str] = Field(None, description="Alternative URL field")
|
|
22
|
+
content_preview: str = Field(..., alias="contentPreview", description="Preview of content")
|
|
23
|
+
relevance_score: float = Field(..., alias="relevanceScore", description="Relevance score (0-1)")
|
|
24
|
+
retrieved_at: Optional[str] = Field(None, alias="retrievedAt", description="Timestamp when retrieved")
|
|
25
|
+
metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
|
|
26
|
+
|
|
27
|
+
class Config:
|
|
28
|
+
from_attributes = True
|
|
29
|
+
populate_by_name = True # Accept both snake_case and camelCase
|
|
30
|
+
by_alias = True # Serialize using aliases (camelCase)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class RAGQueryInfo(BaseModel):
|
|
34
|
+
"""Schema for query information in RAG metadata"""
|
|
35
|
+
query: str = Field(..., description="Search query")
|
|
36
|
+
timestamp: str = Field(..., description="Query timestamp")
|
|
37
|
+
source_citation_ids: List[str] = Field(..., alias="sourceCitationIds", description="Citation IDs for this query")
|
|
38
|
+
|
|
39
|
+
class Config:
|
|
40
|
+
populate_by_name = True
|
|
41
|
+
by_alias = True
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class RAGMetadata(BaseModel):
|
|
45
|
+
"""Schema for RAG metadata"""
|
|
46
|
+
queries: Optional[List[RAGQueryInfo]] = Field(None, description="Query breakdown for timeline")
|
|
47
|
+
|
|
48
|
+
class Config:
|
|
49
|
+
populate_by_name = True
|
|
50
|
+
by_alias = True
|
|
51
|
+
extra = "allow" # Allow additional fields
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class RAGSearchResultResponse(BaseModel):
|
|
55
|
+
"""Schema for RAG search result with automatic snake_case to camelCase conversion"""
|
|
56
|
+
query: str = Field(..., description="Search query")
|
|
57
|
+
title: Optional[str] = Field(None, description="Human-readable title for the research (generated by LLM)")
|
|
58
|
+
search_type: str = Field(..., alias="searchType", description="Type of search (file_search, kb_search, deep_research, web_search)")
|
|
59
|
+
turn_number: Optional[int] = Field(None, alias="turnNumber", description="Turn number for citation tracking")
|
|
60
|
+
timestamp: str = Field(..., description="Search timestamp")
|
|
61
|
+
sources: List[RAGSourceResponse] = Field(default_factory=list, description="List of sources")
|
|
62
|
+
task_id: Optional[str] = Field(None, alias="taskId", description="Associated task ID")
|
|
63
|
+
metadata: Optional[RAGMetadata] = Field(None, description="Additional metadata")
|
|
64
|
+
|
|
65
|
+
class Config:
|
|
66
|
+
from_attributes = True
|
|
67
|
+
populate_by_name = True
|
|
68
|
+
by_alias = True
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def create_rag_source(
|
|
72
|
+
citation_id: str,
|
|
73
|
+
content_preview: str,
|
|
74
|
+
relevance_score: float,
|
|
75
|
+
file_id: Optional[str] = None,
|
|
76
|
+
filename: Optional[str] = None,
|
|
77
|
+
title: Optional[str] = None,
|
|
78
|
+
source_type: Optional[str] = None,
|
|
79
|
+
source_url: Optional[str] = None,
|
|
80
|
+
url: Optional[str] = None,
|
|
81
|
+
retrieved_at: Optional[str] = None,
|
|
82
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
83
|
+
) -> Dict[str, Any]:
|
|
84
|
+
"""
|
|
85
|
+
Helper function to create a RAG source dict that will be automatically
|
|
86
|
+
converted to camelCase when serialized through RAGSourceResponse.
|
|
87
|
+
|
|
88
|
+
Returns a dict that can be passed to RAGSourceResponse for serialization.
|
|
89
|
+
"""
|
|
90
|
+
source = RAGSourceResponse(
|
|
91
|
+
citation_id=citation_id,
|
|
92
|
+
file_id=file_id,
|
|
93
|
+
filename=filename,
|
|
94
|
+
title=title,
|
|
95
|
+
source_type=source_type,
|
|
96
|
+
source_url=source_url,
|
|
97
|
+
url=url,
|
|
98
|
+
content_preview=content_preview,
|
|
99
|
+
relevance_score=relevance_score,
|
|
100
|
+
retrieved_at=retrieved_at,
|
|
101
|
+
metadata=metadata or {}
|
|
102
|
+
)
|
|
103
|
+
return source.model_dump(by_alias=True)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def create_rag_search_result(
|
|
107
|
+
query: str,
|
|
108
|
+
search_type: str,
|
|
109
|
+
timestamp: str,
|
|
110
|
+
sources: List[Dict[str, Any]],
|
|
111
|
+
task_id: Optional[str] = None,
|
|
112
|
+
turn_number: Optional[int] = None,
|
|
113
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
114
|
+
title: Optional[str] = None
|
|
115
|
+
) -> Dict[str, Any]:
|
|
116
|
+
"""
|
|
117
|
+
Helper function to create a RAG search result dict that will be automatically
|
|
118
|
+
converted to camelCase when serialized through RAGSearchResultResponse.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
query: Search query
|
|
122
|
+
search_type: Type of search (file_search, kb_search, deep_research, web_search)
|
|
123
|
+
timestamp: Search timestamp
|
|
124
|
+
sources: List of source dicts (will be converted to RAGSourceResponse)
|
|
125
|
+
task_id: Optional task ID
|
|
126
|
+
turn_number: Optional turn number
|
|
127
|
+
metadata: Optional metadata dict
|
|
128
|
+
title: Optional human-readable title (generated by LLM for deep research)
|
|
129
|
+
|
|
130
|
+
Returns a dict with camelCase keys ready for frontend consumption.
|
|
131
|
+
"""
|
|
132
|
+
# Convert source dicts to RAGSourceResponse for proper serialization
|
|
133
|
+
source_responses = [RAGSourceResponse(**src) for src in sources]
|
|
134
|
+
|
|
135
|
+
# Create metadata if provided
|
|
136
|
+
rag_metadata = None
|
|
137
|
+
if metadata:
|
|
138
|
+
# Convert queries if present
|
|
139
|
+
if "queries" in metadata:
|
|
140
|
+
query_infos = [RAGQueryInfo(**q) for q in metadata["queries"]]
|
|
141
|
+
rag_metadata = RAGMetadata(queries=query_infos, **{k: v for k, v in metadata.items() if k != "queries"})
|
|
142
|
+
else:
|
|
143
|
+
rag_metadata = RAGMetadata(**metadata)
|
|
144
|
+
|
|
145
|
+
result = RAGSearchResultResponse(
|
|
146
|
+
query=query,
|
|
147
|
+
title=title,
|
|
148
|
+
search_type=search_type,
|
|
149
|
+
timestamp=timestamp,
|
|
150
|
+
sources=source_responses,
|
|
151
|
+
task_id=task_id,
|
|
152
|
+
turn_number=turn_number,
|
|
153
|
+
metadata=rag_metadata
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
return result.model_dump(by_alias=True)
|