solace-agent-mesh 1.11.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.
- solace_agent_mesh/__init__.py +0 -0
- solace_agent_mesh/agent/__init__.py +0 -0
- solace_agent_mesh/agent/adk/__init__.py +0 -0
- solace_agent_mesh/agent/adk/adk_llm.txt +226 -0
- solace_agent_mesh/agent/adk/adk_llm_detail.txt +566 -0
- 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 +52 -0
- solace_agent_mesh/agent/adk/artifacts/__init__.py +1 -0
- solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +171 -0
- solace_agent_mesh/agent/adk/artifacts/filesystem_artifact_service.py +545 -0
- solace_agent_mesh/agent/adk/artifacts/s3_artifact_service.py +609 -0
- solace_agent_mesh/agent/adk/callbacks.py +2318 -0
- solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +406 -0
- solace_agent_mesh/agent/adk/intelligent_mcp_callbacks.py +415 -0
- solace_agent_mesh/agent/adk/mcp_content_processor.py +666 -0
- solace_agent_mesh/agent/adk/models/lite_llm.py +1026 -0
- solace_agent_mesh/agent/adk/models/models_llm.txt +189 -0
- solace_agent_mesh/agent/adk/models/oauth2_token_manager.py +132 -0
- solace_agent_mesh/agent/adk/runner.py +390 -0
- solace_agent_mesh/agent/adk/schema_migration.py +88 -0
- solace_agent_mesh/agent/adk/services.py +468 -0
- solace_agent_mesh/agent/adk/setup.py +1325 -0
- solace_agent_mesh/agent/adk/stream_parser.py +415 -0
- solace_agent_mesh/agent/adk/tool_wrapper.py +165 -0
- solace_agent_mesh/agent/agent_llm.txt +369 -0
- solace_agent_mesh/agent/agent_llm_detail.txt +1702 -0
- solace_agent_mesh/agent/protocol/__init__.py +0 -0
- solace_agent_mesh/agent/protocol/event_handlers.py +2041 -0
- solace_agent_mesh/agent/protocol/protocol_llm.txt +81 -0
- solace_agent_mesh/agent/protocol/protocol_llm_detail.txt +92 -0
- solace_agent_mesh/agent/proxies/__init__.py +0 -0
- solace_agent_mesh/agent/proxies/a2a/__init__.py +3 -0
- solace_agent_mesh/agent/proxies/a2a/a2a_llm.txt +190 -0
- solace_agent_mesh/agent/proxies/a2a/app.py +56 -0
- solace_agent_mesh/agent/proxies/a2a/component.py +1585 -0
- solace_agent_mesh/agent/proxies/a2a/config.py +216 -0
- solace_agent_mesh/agent/proxies/a2a/oauth_token_cache.py +104 -0
- solace_agent_mesh/agent/proxies/base/__init__.py +3 -0
- solace_agent_mesh/agent/proxies/base/app.py +100 -0
- solace_agent_mesh/agent/proxies/base/base_llm.txt +148 -0
- solace_agent_mesh/agent/proxies/base/component.py +816 -0
- solace_agent_mesh/agent/proxies/base/config.py +85 -0
- solace_agent_mesh/agent/proxies/base/proxy_task_context.py +19 -0
- solace_agent_mesh/agent/proxies/proxies_llm.txt +283 -0
- solace_agent_mesh/agent/sac/__init__.py +0 -0
- solace_agent_mesh/agent/sac/app.py +595 -0
- solace_agent_mesh/agent/sac/component.py +3668 -0
- solace_agent_mesh/agent/sac/patch_adk.py +103 -0
- solace_agent_mesh/agent/sac/sac_llm.txt +189 -0
- solace_agent_mesh/agent/sac/sac_llm_detail.txt +200 -0
- solace_agent_mesh/agent/sac/task_execution_context.py +415 -0
- solace_agent_mesh/agent/testing/__init__.py +3 -0
- solace_agent_mesh/agent/testing/debug_utils.py +135 -0
- solace_agent_mesh/agent/testing/testing_llm.txt +58 -0
- solace_agent_mesh/agent/testing/testing_llm_detail.txt +68 -0
- solace_agent_mesh/agent/tools/__init__.py +16 -0
- solace_agent_mesh/agent/tools/audio_tools.py +1740 -0
- solace_agent_mesh/agent/tools/builtin_artifact_tools.py +2500 -0
- solace_agent_mesh/agent/tools/builtin_data_analysis_tools.py +244 -0
- solace_agent_mesh/agent/tools/dynamic_tool.py +396 -0
- solace_agent_mesh/agent/tools/general_agent_tools.py +572 -0
- solace_agent_mesh/agent/tools/image_tools.py +1185 -0
- solace_agent_mesh/agent/tools/peer_agent_tool.py +363 -0
- solace_agent_mesh/agent/tools/registry.py +38 -0
- solace_agent_mesh/agent/tools/test_tools.py +136 -0
- solace_agent_mesh/agent/tools/time_tools.py +126 -0
- solace_agent_mesh/agent/tools/tool_config_types.py +93 -0
- solace_agent_mesh/agent/tools/tool_definition.py +53 -0
- solace_agent_mesh/agent/tools/tools_llm.txt +276 -0
- solace_agent_mesh/agent/tools/tools_llm_detail.txt +275 -0
- solace_agent_mesh/agent/tools/web_tools.py +392 -0
- solace_agent_mesh/agent/utils/__init__.py +0 -0
- solace_agent_mesh/agent/utils/artifact_helpers.py +1353 -0
- solace_agent_mesh/agent/utils/config_parser.py +49 -0
- solace_agent_mesh/agent/utils/context_helpers.py +77 -0
- solace_agent_mesh/agent/utils/utils_llm.txt +152 -0
- solace_agent_mesh/agent/utils/utils_llm_detail.txt +149 -0
- solace_agent_mesh/assets/docs/404.html +16 -0
- solace_agent_mesh/assets/docs/assets/css/styles.8162edfb.css +1 -0
- solace_agent_mesh/assets/docs/assets/images/Solace_AI_Framework_With_Broker-85f0a306a9bcdd20b390b7a949f6d862.png +0 -0
- solace_agent_mesh/assets/docs/assets/images/sam-enterprise-credentials-b269f095349473118b2b33bdfcc40122.png +0 -0
- solace_agent_mesh/assets/docs/assets/js/032c2d61.f3d37824.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/05749d90.19ac4f35.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/0bcf40b7.c019ad46.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/1001.0182a8bd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/1039.0bd46aa1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/149.b797a808.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/15ba94aa.92fea363.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/15e40e79.434bb30f.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/165.6a39807d.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/165.6a39807d.js.LICENSE.txt +9 -0
- solace_agent_mesh/assets/docs/assets/js/17896441.e612dfb4.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2130.ab9fd314.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2131ec11.5c7a1f6e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2237.5e477fc6.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2279.550aa580.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/2279.550aa580.js.LICENSE.txt +13 -0
- solace_agent_mesh/assets/docs/assets/js/2334.1cf50a20.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/240a0364.9ad94d1b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2987107d.a80604f9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2e32b5e0.33f5d75b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3219.adc1d663.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/341393d4.0fac2613.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3624.0eaa1fd0.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/375.708d48db.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3834.b6cd790e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3a6c6137.f5940cfa.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ac1795d.28b7c67b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ff0015d.2ddc75c0.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/41adc471.48b12a4e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4250.95455b28.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4356.d169ab5b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4458.518e66fa.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4488.c7cc3442.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4494.6ee23046.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4855.fc4444b6.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4866.22daefc0.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4950.ca4caeda.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/509e993c.a1fbf45a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5388.7a136447.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/547e15cc.2f7790c1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/55b7b518.29d6e75d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5607.081356f8.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5864.b0d0e9de.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.90a87880.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5e95c892.558d5167.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6063ff4c.ef84f702.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/60702c0e.a8bdd79b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6143.0a1464c9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/631738c7.fa471607.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6395.e9c73649.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/64195356.c498c4d0.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/66d4869e.b77431fc.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6796.51d2c9b7.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6976.379be23b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6978.ee0b945c.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/6fdfefc7.99de744e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/7040.cb436723.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/7195.412f418a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/71da7b71.374b9d54.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/722f809d.965da774.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/7280.3fb73bdb.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/742f027b.46c07808.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/77cf947d.48cb18a2.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/7845.e33e7c4c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/7900.69516146.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8024126c.fa0e7186.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/81a99df0.2484b8d9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/82fbfb93.161823a5.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8356.8a379c04.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8567.4732c6b7.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8573.cb04eda5.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8577.1d54e766.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8591.5d015485.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/8591.5d015485.js.LICENSE.txt +61 -0
- solace_agent_mesh/assets/docs/assets/js/8709.7ecd4047.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8731.6c1dbf0c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8908.f9d1b506.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8b032486.91a91afc.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9157.b4093d07.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/924ffdeb.975e428a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9278.a4fd875d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/945fb41e.6f4cdffd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/94e8668d.16083b3f.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9616.b75c2f6d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9793.c6d16376.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9bb13469.b2333011.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9e9d0a82.570c057b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/a7bd4aaa.2204d2f7.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/a94703ab.3e5fbcb3.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ab9708a8.245ae0ef.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/aba21aa0.c42a534c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ad71b5ed.af3ecfd1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ad87452a.9d73dad6.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/c198a0dc.8f31f867.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/ceb2a7a6.5d92d7d0.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/da0b5bad.b62f7b08.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/db5d6442.3daf1696.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/db924877.e98d12a1.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/de5f4c65.e8241890.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/de915948.44a432bc.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e04b235d.52cb25ed.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e1b6eeb4.b1068f9b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e3d9abda.1476f570.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e6f9706b.4488e34c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e92d0134.3bda61dd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f284c35a.250993bf.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ff4d71f2.74710fc1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.7acf7ace.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/main.7acf7ace.js.LICENSE.txt +81 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.9e0813a2.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +154 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/artifact-management/index.html +99 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/audio-tools/index.html +90 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/data-analysis-tools/index.html +107 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/embeds/index.html +166 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/index.html +101 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/cli/index.html +219 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +92 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/index.html +29 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +55 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +110 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/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 +345 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/speech/index.html +52 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +83 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +84 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +25 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes-deployment/index.html +47 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/logging/index.html +85 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +60 -0
- 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 +144 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-gateways/index.html +191 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-python-tools/index.html +128 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +54 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +135 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +34 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +55 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/bedrock-agents/index.html +267 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/custom-agent/index.html +142 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/event-mesh-gateway/index.html +116 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mcp-integration/index.html +86 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mongodb-integration/index.html +164 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rag-integration/index.html +140 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rest-gateway/index.html +57 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +72 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/sql-database/index.html +102 -0
- 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 +37 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +86 -0
- 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 +247 -0
- 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 +184 -0
- 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 +75 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +54 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +85 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +41 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/artifact-storage/index.html +290 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +78 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +25 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +78 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +160 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +142 -0
- solace_agent_mesh/assets/docs/docs/documentation/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 +100 -0
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-technical-migration-map/index.html +52 -0
- solace_agent_mesh/assets/docs/img/Solace_AI_Framework_With_Broker.png +0 -0
- solace_agent_mesh/assets/docs/img/logo.png +0 -0
- solace_agent_mesh/assets/docs/img/sac-flows.png +0 -0
- solace_agent_mesh/assets/docs/img/sac_parts_of_a_component.png +0 -0
- solace_agent_mesh/assets/docs/img/sam-enterprise-credentials.png +0 -0
- solace_agent_mesh/assets/docs/img/solace-logo-text.svg +18 -0
- solace_agent_mesh/assets/docs/img/solace-logo.png +0 -0
- solace_agent_mesh/assets/docs/lunr-index-1765810064709.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -0
- solace_agent_mesh/assets/docs/search-doc-1765810064709.json +1 -0
- solace_agent_mesh/assets/docs/search-doc.json +1 -0
- solace_agent_mesh/assets/docs/sitemap.xml +1 -0
- solace_agent_mesh/cli/__init__.py +1 -0
- solace_agent_mesh/cli/commands/__init__.py +0 -0
- solace_agent_mesh/cli/commands/add_cmd/__init__.py +15 -0
- solace_agent_mesh/cli/commands/add_cmd/add_cmd_llm.txt +250 -0
- solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +729 -0
- solace_agent_mesh/cli/commands/add_cmd/gateway_cmd.py +322 -0
- solace_agent_mesh/cli/commands/add_cmd/web_add_agent_step.py +102 -0
- solace_agent_mesh/cli/commands/add_cmd/web_add_gateway_step.py +114 -0
- solace_agent_mesh/cli/commands/docs_cmd.py +60 -0
- solace_agent_mesh/cli/commands/eval_cmd.py +46 -0
- solace_agent_mesh/cli/commands/init_cmd/__init__.py +439 -0
- solace_agent_mesh/cli/commands/init_cmd/broker_step.py +201 -0
- solace_agent_mesh/cli/commands/init_cmd/database_step.py +91 -0
- solace_agent_mesh/cli/commands/init_cmd/directory_step.py +28 -0
- solace_agent_mesh/cli/commands/init_cmd/env_step.py +238 -0
- solace_agent_mesh/cli/commands/init_cmd/init_cmd_llm.txt +365 -0
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +464 -0
- solace_agent_mesh/cli/commands/init_cmd/project_files_step.py +38 -0
- solace_agent_mesh/cli/commands/init_cmd/web_init_step.py +119 -0
- solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +215 -0
- solace_agent_mesh/cli/commands/plugin_cmd/__init__.py +20 -0
- solace_agent_mesh/cli/commands/plugin_cmd/add_cmd.py +137 -0
- solace_agent_mesh/cli/commands/plugin_cmd/build_cmd.py +86 -0
- solace_agent_mesh/cli/commands/plugin_cmd/catalog_cmd.py +144 -0
- solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +306 -0
- solace_agent_mesh/cli/commands/plugin_cmd/install_cmd.py +283 -0
- solace_agent_mesh/cli/commands/plugin_cmd/official_registry.py +175 -0
- solace_agent_mesh/cli/commands/plugin_cmd/plugin_cmd_llm.txt +305 -0
- solace_agent_mesh/cli/commands/run_cmd.py +215 -0
- solace_agent_mesh/cli/main.py +52 -0
- solace_agent_mesh/cli/utils.py +262 -0
- solace_agent_mesh/client/webui/frontend/static/assets/authCallback-Dj3JtK42.js +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/client-ZKk9kEJ5.js +25 -0
- solace_agent_mesh/client/webui/frontend/static/assets/favicon-BLgzUch9.ico +0 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-BcUaNZ-Q.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-vjch4RYc.js +435 -0
- solace_agent_mesh/client/webui/frontend/static/assets/vendor-BNV4kZN0.js +535 -0
- solace_agent_mesh/client/webui/frontend/static/auth-callback.html +15 -0
- solace_agent_mesh/client/webui/frontend/static/index.html +16 -0
- 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/__init__.py +1 -0
- solace_agent_mesh/common/a2a/__init__.py +241 -0
- solace_agent_mesh/common/a2a/a2a_llm.txt +175 -0
- solace_agent_mesh/common/a2a/a2a_llm_detail.txt +193 -0
- solace_agent_mesh/common/a2a/artifact.py +368 -0
- solace_agent_mesh/common/a2a/events.py +213 -0
- solace_agent_mesh/common/a2a/message.py +375 -0
- solace_agent_mesh/common/a2a/protocol.py +689 -0
- solace_agent_mesh/common/a2a/task.py +127 -0
- solace_agent_mesh/common/a2a/translation.py +655 -0
- solace_agent_mesh/common/a2a/types.py +55 -0
- solace_agent_mesh/common/a2a_spec/a2a.json +2576 -0
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +445 -0
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm_detail.txt +736 -0
- solace_agent_mesh/common/a2a_spec/schemas/agent_progress_update.json +18 -0
- solace_agent_mesh/common/a2a_spec/schemas/artifact_creation_progress.json +48 -0
- solace_agent_mesh/common/a2a_spec/schemas/feedback_event.json +51 -0
- solace_agent_mesh/common/a2a_spec/schemas/llm_invocation.json +41 -0
- solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +330 -0
- solace_agent_mesh/common/a2a_spec/schemas/tool_invocation_start.json +26 -0
- solace_agent_mesh/common/a2a_spec/schemas/tool_result.json +48 -0
- solace_agent_mesh/common/agent_registry.py +122 -0
- solace_agent_mesh/common/common_llm.txt +230 -0
- solace_agent_mesh/common/common_llm_detail.txt +2562 -0
- solace_agent_mesh/common/constants.py +6 -0
- solace_agent_mesh/common/data_parts.py +150 -0
- solace_agent_mesh/common/exceptions.py +49 -0
- solace_agent_mesh/common/middleware/__init__.py +12 -0
- solace_agent_mesh/common/middleware/config_resolver.py +132 -0
- solace_agent_mesh/common/middleware/middleware_llm.txt +174 -0
- solace_agent_mesh/common/middleware/middleware_llm_detail.txt +185 -0
- solace_agent_mesh/common/middleware/registry.py +127 -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/sac/__init__.py +0 -0
- solace_agent_mesh/common/sac/sac_llm.txt +71 -0
- solace_agent_mesh/common/sac/sac_llm_detail.txt +82 -0
- solace_agent_mesh/common/sac/sam_component_base.py +730 -0
- solace_agent_mesh/common/sam_events/__init__.py +9 -0
- solace_agent_mesh/common/sam_events/event_service.py +208 -0
- solace_agent_mesh/common/sam_events/sam_events_llm.txt +104 -0
- solace_agent_mesh/common/sam_events/sam_events_llm_detail.txt +115 -0
- solace_agent_mesh/common/services/__init__.py +4 -0
- solace_agent_mesh/common/services/employee_service.py +164 -0
- solace_agent_mesh/common/services/identity_service.py +134 -0
- solace_agent_mesh/common/services/providers/__init__.py +4 -0
- solace_agent_mesh/common/services/providers/local_file_identity_service.py +151 -0
- solace_agent_mesh/common/services/providers/providers_llm.txt +81 -0
- solace_agent_mesh/common/services/services_llm.txt +368 -0
- solace_agent_mesh/common/services/services_llm_detail.txt +459 -0
- solace_agent_mesh/common/utils/__init__.py +7 -0
- solace_agent_mesh/common/utils/artifact_utils.py +31 -0
- solace_agent_mesh/common/utils/asyncio_macos_fix.py +88 -0
- solace_agent_mesh/common/utils/embeds/__init__.py +33 -0
- solace_agent_mesh/common/utils/embeds/constants.py +56 -0
- solace_agent_mesh/common/utils/embeds/converter.py +447 -0
- solace_agent_mesh/common/utils/embeds/embeds_llm.txt +220 -0
- solace_agent_mesh/common/utils/embeds/evaluators.py +395 -0
- solace_agent_mesh/common/utils/embeds/modifiers.py +793 -0
- solace_agent_mesh/common/utils/embeds/resolver.py +967 -0
- solace_agent_mesh/common/utils/embeds/types.py +23 -0
- solace_agent_mesh/common/utils/in_memory_cache.py +108 -0
- solace_agent_mesh/common/utils/initializer.py +52 -0
- solace_agent_mesh/common/utils/log_formatters.py +64 -0
- solace_agent_mesh/common/utils/message_utils.py +80 -0
- solace_agent_mesh/common/utils/mime_helpers.py +172 -0
- solace_agent_mesh/common/utils/push_notification_auth.py +135 -0
- solace_agent_mesh/common/utils/pydantic_utils.py +159 -0
- 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/common/utils/type_utils.py +28 -0
- solace_agent_mesh/common/utils/utils_llm.txt +335 -0
- solace_agent_mesh/common/utils/utils_llm_detail.txt +572 -0
- solace_agent_mesh/config_portal/__init__.py +0 -0
- solace_agent_mesh/config_portal/backend/__init__.py +0 -0
- solace_agent_mesh/config_portal/backend/common.py +77 -0
- solace_agent_mesh/config_portal/backend/plugin_catalog/__init__.py +0 -0
- solace_agent_mesh/config_portal/backend/plugin_catalog/constants.py +24 -0
- solace_agent_mesh/config_portal/backend/plugin_catalog/models.py +49 -0
- solace_agent_mesh/config_portal/backend/plugin_catalog/registry_manager.py +166 -0
- solace_agent_mesh/config_portal/backend/plugin_catalog/scraper.py +521 -0
- solace_agent_mesh/config_portal/backend/plugin_catalog_server.py +217 -0
- solace_agent_mesh/config_portal/backend/server.py +644 -0
- solace_agent_mesh/config_portal/frontend/static/client/Solace_community_logo.png +0 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-DiOiAjzL.js +103 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/components-Rk0n-9cK.js +140 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/entry.client-mvZjNKiz.js +19 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/index-DzNKzXrc.js +68 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-ba77705e.js +1 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-B17tZKK7.css +1 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-V2BeTIUc.js +10 -0
- solace_agent_mesh/config_portal/frontend/static/client/favicon.ico +0 -0
- solace_agent_mesh/config_portal/frontend/static/client/index.html +7 -0
- solace_agent_mesh/core_a2a/__init__.py +1 -0
- solace_agent_mesh/core_a2a/core_a2a_llm.txt +90 -0
- solace_agent_mesh/core_a2a/core_a2a_llm_detail.txt +101 -0
- solace_agent_mesh/core_a2a/service.py +307 -0
- solace_agent_mesh/evaluation/__init__.py +0 -0
- solace_agent_mesh/evaluation/evaluator.py +691 -0
- solace_agent_mesh/evaluation/message_organizer.py +553 -0
- solace_agent_mesh/evaluation/report/benchmark_info.html +35 -0
- solace_agent_mesh/evaluation/report/chart_section.html +141 -0
- solace_agent_mesh/evaluation/report/detailed_breakdown.html +28 -0
- solace_agent_mesh/evaluation/report/modal.html +59 -0
- solace_agent_mesh/evaluation/report/modal_chart_functions.js +411 -0
- solace_agent_mesh/evaluation/report/modal_script.js +296 -0
- solace_agent_mesh/evaluation/report/modal_styles.css +340 -0
- solace_agent_mesh/evaluation/report/performance_metrics_styles.css +93 -0
- solace_agent_mesh/evaluation/report/templates/footer.html +2 -0
- solace_agent_mesh/evaluation/report/templates/header.html +340 -0
- solace_agent_mesh/evaluation/report_data_processor.py +970 -0
- solace_agent_mesh/evaluation/report_generator.py +607 -0
- solace_agent_mesh/evaluation/run.py +954 -0
- solace_agent_mesh/evaluation/shared/__init__.py +92 -0
- solace_agent_mesh/evaluation/shared/constants.py +47 -0
- solace_agent_mesh/evaluation/shared/exceptions.py +50 -0
- solace_agent_mesh/evaluation/shared/helpers.py +35 -0
- solace_agent_mesh/evaluation/shared/test_case_loader.py +167 -0
- solace_agent_mesh/evaluation/shared/test_suite_loader.py +280 -0
- solace_agent_mesh/evaluation/subscriber.py +776 -0
- solace_agent_mesh/evaluation/summary_builder.py +880 -0
- solace_agent_mesh/gateway/__init__.py +0 -0
- solace_agent_mesh/gateway/adapter/__init__.py +1 -0
- solace_agent_mesh/gateway/adapter/base.py +143 -0
- solace_agent_mesh/gateway/adapter/types.py +221 -0
- solace_agent_mesh/gateway/base/__init__.py +1 -0
- solace_agent_mesh/gateway/base/app.py +345 -0
- solace_agent_mesh/gateway/base/base_llm.txt +226 -0
- solace_agent_mesh/gateway/base/base_llm_detail.txt +235 -0
- solace_agent_mesh/gateway/base/component.py +2030 -0
- solace_agent_mesh/gateway/base/task_context.py +75 -0
- solace_agent_mesh/gateway/gateway_llm.txt +369 -0
- solace_agent_mesh/gateway/gateway_llm_detail.txt +3885 -0
- 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 +727 -0
- solace_agent_mesh/gateway/http_sse/__init__.py +0 -0
- solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +345 -0
- solace_agent_mesh/gateway/http_sse/alembic/env.py +87 -0
- solace_agent_mesh/gateway/http_sse/alembic/script.py.mako +28 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20250910_d5b3f8f2e9a0_create_initial_database.py +58 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20250911_b1c2d3e4f5g6_add_database_indexes.py +83 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20250916_f6e7d8c9b0a1_convert_timestamps_to_epoch_and_align_columns.py +412 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251006_98882922fa59_add_tasks_events_feedback_chat_tasks.py +190 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251015_add_session_performance_indexes.py +70 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_project_users_table.py +72 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_soft_delete_and_search.py +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/versions/versions_llm.txt +161 -0
- solace_agent_mesh/gateway/http_sse/alembic.ini +109 -0
- solace_agent_mesh/gateway/http_sse/app.py +351 -0
- solace_agent_mesh/gateway/http_sse/component.py +2360 -0
- solace_agent_mesh/gateway/http_sse/components/__init__.py +7 -0
- solace_agent_mesh/gateway/http_sse/components/components_llm.txt +105 -0
- solace_agent_mesh/gateway/http_sse/components/task_logger_forwarder.py +109 -0
- solace_agent_mesh/gateway/http_sse/components/visualization_forwarder_component.py +110 -0
- solace_agent_mesh/gateway/http_sse/dependencies.py +653 -0
- solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +299 -0
- solace_agent_mesh/gateway/http_sse/http_sse_llm_detail.txt +3278 -0
- solace_agent_mesh/gateway/http_sse/main.py +789 -0
- solace_agent_mesh/gateway/http_sse/repository/__init__.py +46 -0
- solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +102 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/__init__.py +11 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/chat_task.py +75 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +221 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/feedback.py +20 -0
- 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 +66 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/session_history.py +0 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/task.py +32 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/task_event.py +21 -0
- solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +125 -0
- solace_agent_mesh/gateway/http_sse/repository/interfaces.py +239 -0
- solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +34 -0
- solace_agent_mesh/gateway/http_sse/repository/models/base.py +7 -0
- solace_agent_mesh/gateway/http_sse/repository/models/chat_task_model.py +31 -0
- solace_agent_mesh/gateway/http_sse/repository/models/feedback_model.py +21 -0
- solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +257 -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 +53 -0
- solace_agent_mesh/gateway/http_sse/repository/models/task_event_model.py +25 -0
- solace_agent_mesh/gateway/http_sse/repository/models/task_model.py +39 -0
- solace_agent_mesh/gateway/http_sse/repository/project_repository.py +172 -0
- solace_agent_mesh/gateway/http_sse/repository/project_user_repository.py +186 -0
- solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +308 -0
- solace_agent_mesh/gateway/http_sse/repository/session_repository.py +268 -0
- solace_agent_mesh/gateway/http_sse/repository/task_repository.py +248 -0
- solace_agent_mesh/gateway/http_sse/routers/__init__.py +4 -0
- solace_agent_mesh/gateway/http_sse/routers/agent_cards.py +74 -0
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +1137 -0
- solace_agent_mesh/gateway/http_sse/routers/auth.py +311 -0
- solace_agent_mesh/gateway/http_sse/routers/config.py +371 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/__init__.py +10 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +450 -0
- 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/__init__.py +15 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/project_requests.py +48 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +133 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +33 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/task_requests.py +58 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/__init__.py +18 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/base_responses.py +42 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/project_responses.py +31 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +123 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +33 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/task_responses.py +30 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/version_responses.py +31 -0
- solace_agent_mesh/gateway/http_sse/routers/feedback.py +168 -0
- solace_agent_mesh/gateway/http_sse/routers/people.py +38 -0
- solace_agent_mesh/gateway/http_sse/routers/projects.py +767 -0
- solace_agent_mesh/gateway/http_sse/routers/prompts.py +1415 -0
- solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +312 -0
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +634 -0
- solace_agent_mesh/gateway/http_sse/routers/speech.py +355 -0
- solace_agent_mesh/gateway/http_sse/routers/sse.py +230 -0
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +1089 -0
- solace_agent_mesh/gateway/http_sse/routers/users.py +83 -0
- solace_agent_mesh/gateway/http_sse/routers/version.py +343 -0
- solace_agent_mesh/gateway/http_sse/routers/visualization.py +1220 -0
- solace_agent_mesh/gateway/http_sse/services/__init__.py +4 -0
- solace_agent_mesh/gateway/http_sse/services/agent_card_service.py +71 -0
- 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 +273 -0
- solace_agent_mesh/gateway/http_sse/services/feedback_service.py +250 -0
- solace_agent_mesh/gateway/http_sse/services/people_service.py +78 -0
- 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/services_llm.txt +303 -0
- solace_agent_mesh/gateway/http_sse/services/session_service.py +702 -0
- solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +593 -0
- solace_agent_mesh/gateway/http_sse/services/task_service.py +119 -0
- solace_agent_mesh/gateway/http_sse/session_manager.py +219 -0
- solace_agent_mesh/gateway/http_sse/shared/__init__.py +146 -0
- solace_agent_mesh/gateway/http_sse/shared/auth_utils.py +29 -0
- solace_agent_mesh/gateway/http_sse/shared/base_repository.py +252 -0
- solace_agent_mesh/gateway/http_sse/shared/database_exceptions.py +274 -0
- solace_agent_mesh/gateway/http_sse/shared/database_helpers.py +43 -0
- solace_agent_mesh/gateway/http_sse/shared/enums.py +40 -0
- solace_agent_mesh/gateway/http_sse/shared/error_dto.py +107 -0
- solace_agent_mesh/gateway/http_sse/shared/exception_handlers.py +217 -0
- solace_agent_mesh/gateway/http_sse/shared/exceptions.py +192 -0
- solace_agent_mesh/gateway/http_sse/shared/pagination.py +138 -0
- solace_agent_mesh/gateway/http_sse/shared/response_utils.py +134 -0
- solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +319 -0
- solace_agent_mesh/gateway/http_sse/shared/timestamp_utils.py +97 -0
- solace_agent_mesh/gateway/http_sse/shared/types.py +50 -0
- solace_agent_mesh/gateway/http_sse/shared/utils.py +22 -0
- solace_agent_mesh/gateway/http_sse/sse_event_buffer.py +88 -0
- solace_agent_mesh/gateway/http_sse/sse_manager.py +491 -0
- solace_agent_mesh/gateway/http_sse/utils/__init__.py +1 -0
- solace_agent_mesh/gateway/http_sse/utils/artifact_copy_utils.py +370 -0
- solace_agent_mesh/gateway/http_sse/utils/stim_utils.py +72 -0
- solace_agent_mesh/gateway/http_sse/utils/utils_llm.txt +47 -0
- solace_agent_mesh/llm.txt +228 -0
- solace_agent_mesh/llm_detail.txt +2835 -0
- solace_agent_mesh/services/__init__.py +0 -0
- solace_agent_mesh/services/platform/__init__.py +18 -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 +147 -0
- solace_agent_mesh/services/platform/api/main.py +280 -0
- solace_agent_mesh/services/platform/api/middleware.py +51 -0
- solace_agent_mesh/services/platform/api/routers/__init__.py +24 -0
- solace_agent_mesh/services/platform/app.py +114 -0
- solace_agent_mesh/services/platform/component.py +235 -0
- solace_agent_mesh/solace_agent_mesh_llm.txt +362 -0
- solace_agent_mesh/solace_agent_mesh_llm_detail.txt +8599 -0
- solace_agent_mesh/templates/agent_template.yaml +53 -0
- solace_agent_mesh/templates/eval_backend_template.yaml +54 -0
- solace_agent_mesh/templates/gateway_app_template.py +75 -0
- solace_agent_mesh/templates/gateway_component_template.py +484 -0
- solace_agent_mesh/templates/gateway_config_template.yaml +38 -0
- solace_agent_mesh/templates/logging_config_template.yaml +48 -0
- solace_agent_mesh/templates/main_orchestrator.yaml +66 -0
- solace_agent_mesh/templates/plugin_agent_config_template.yaml +122 -0
- solace_agent_mesh/templates/plugin_custom_config_template.yaml +27 -0
- solace_agent_mesh/templates/plugin_custom_template.py +10 -0
- solace_agent_mesh/templates/plugin_gateway_config_template.yaml +60 -0
- solace_agent_mesh/templates/plugin_pyproject_template.toml +32 -0
- solace_agent_mesh/templates/plugin_readme_template.md +12 -0
- solace_agent_mesh/templates/plugin_tool_config_template.yaml +109 -0
- solace_agent_mesh/templates/plugin_tools_template.py +224 -0
- solace_agent_mesh/templates/shared_config.yaml +112 -0
- solace_agent_mesh/templates/templates_llm.txt +147 -0
- solace_agent_mesh/templates/webui.yaml +177 -0
- solace_agent_mesh-1.11.2.dist-info/METADATA +504 -0
- solace_agent_mesh-1.11.2.dist-info/RECORD +624 -0
- solace_agent_mesh-1.11.2.dist-info/WHEEL +4 -0
- solace_agent_mesh-1.11.2.dist-info/entry_points.txt +3 -0
- solace_agent_mesh-1.11.2.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,1026 @@
|
|
|
1
|
+
# Copyright 2025 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import base64
|
|
18
|
+
import hashlib
|
|
19
|
+
import json
|
|
20
|
+
import logging
|
|
21
|
+
from typing import Any
|
|
22
|
+
from typing import AsyncGenerator
|
|
23
|
+
from typing import cast
|
|
24
|
+
from typing import Dict
|
|
25
|
+
from typing import Generator
|
|
26
|
+
from typing import Iterable
|
|
27
|
+
from typing import List
|
|
28
|
+
from typing import Literal
|
|
29
|
+
from typing import Optional
|
|
30
|
+
from typing import Tuple
|
|
31
|
+
from typing import Union
|
|
32
|
+
|
|
33
|
+
from google.genai import types
|
|
34
|
+
from litellm import acompletion
|
|
35
|
+
from litellm import ChatCompletionAssistantMessage
|
|
36
|
+
from litellm import ChatCompletionAssistantToolCall
|
|
37
|
+
from litellm import ChatCompletionDeveloperMessage
|
|
38
|
+
from litellm import ChatCompletionImageUrlObject
|
|
39
|
+
from litellm import ChatCompletionMessageToolCall
|
|
40
|
+
from litellm import ChatCompletionTextObject
|
|
41
|
+
from litellm import ChatCompletionToolMessage
|
|
42
|
+
from litellm import ChatCompletionUserMessage
|
|
43
|
+
from litellm import ChatCompletionVideoUrlObject
|
|
44
|
+
from litellm import completion
|
|
45
|
+
from litellm import CustomStreamWrapper
|
|
46
|
+
from litellm import Function
|
|
47
|
+
from litellm import Message
|
|
48
|
+
from litellm import ModelResponse
|
|
49
|
+
from litellm import OpenAIMessageContent
|
|
50
|
+
from pydantic import BaseModel
|
|
51
|
+
from pydantic import Field
|
|
52
|
+
from typing_extensions import override
|
|
53
|
+
|
|
54
|
+
from google.adk.models.base_llm import BaseLlm
|
|
55
|
+
from google.adk.models.llm_request import LlmRequest
|
|
56
|
+
from google.adk.models.llm_response import LlmResponse
|
|
57
|
+
from .oauth2_token_manager import OAuth2ClientCredentialsTokenManager
|
|
58
|
+
|
|
59
|
+
logger = logging.getLogger("google_adk." + __name__)
|
|
60
|
+
|
|
61
|
+
_NEW_LINE = "\n"
|
|
62
|
+
_EXCLUDED_PART_FIELD = {"inline_data": {"data"}}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class FunctionChunk(BaseModel):
|
|
66
|
+
id: Optional[str]
|
|
67
|
+
name: Optional[str]
|
|
68
|
+
args: Optional[str]
|
|
69
|
+
index: Optional[int] = 0
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class TextChunk(BaseModel):
|
|
73
|
+
text: str
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class UsageMetadataChunk(BaseModel):
|
|
77
|
+
prompt_tokens: int
|
|
78
|
+
completion_tokens: int
|
|
79
|
+
total_tokens: int
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class LiteLLMClient:
|
|
83
|
+
"""Provides acompletion method (for better testability)."""
|
|
84
|
+
|
|
85
|
+
async def acompletion(
|
|
86
|
+
self, model, messages, tools, **kwargs
|
|
87
|
+
) -> Union[ModelResponse, CustomStreamWrapper]:
|
|
88
|
+
"""Asynchronously calls acompletion.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
model: The model name.
|
|
92
|
+
messages: The messages to send to the model.
|
|
93
|
+
tools: The tools to use for the model.
|
|
94
|
+
**kwargs: Additional arguments to pass to acompletion.
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
The model response as a message.
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
return await acompletion(
|
|
101
|
+
model=model,
|
|
102
|
+
messages=messages,
|
|
103
|
+
tools=tools,
|
|
104
|
+
**kwargs,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
def completion(
|
|
108
|
+
self, model, messages, tools, stream=False, **kwargs
|
|
109
|
+
) -> Union[ModelResponse, CustomStreamWrapper]:
|
|
110
|
+
"""Synchronously calls completion. This is used for streaming only.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
model: The model to use.
|
|
114
|
+
messages: The messages to send.
|
|
115
|
+
tools: The tools to use for the model.
|
|
116
|
+
stream: Whether to stream the response.
|
|
117
|
+
**kwargs: Additional arguments to pass to completion.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
The response from the model.
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
return completion(
|
|
124
|
+
model=model,
|
|
125
|
+
messages=messages,
|
|
126
|
+
tools=tools,
|
|
127
|
+
stream=stream,
|
|
128
|
+
**kwargs,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _safe_json_serialize(obj) -> str:
|
|
133
|
+
"""Convert any Python object to a JSON-serializable type or string.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
obj: The object to serialize.
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
The JSON-serialized object string or string.
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
try:
|
|
143
|
+
return json.dumps(obj, ensure_ascii=False)
|
|
144
|
+
except (TypeError, OverflowError):
|
|
145
|
+
return str(obj)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def _truncate_tool_call_id(tool_call_id: str, max_length: int = 40) -> str:
|
|
149
|
+
"""Truncates tool call ID to meet OpenAI's maximum length requirement.
|
|
150
|
+
|
|
151
|
+
OpenAI requires tool_call_id to be at most 40 characters. If the ID exceeds
|
|
152
|
+
this limit, we create a deterministic hash-based truncation to ensure:
|
|
153
|
+
1. The ID stays within the limit
|
|
154
|
+
2. The same input always produces the same output (deterministic)
|
|
155
|
+
3. Collisions are extremely unlikely
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
tool_call_id: The original tool call ID
|
|
159
|
+
max_length: Maximum allowed length (default: 40 for OpenAI)
|
|
160
|
+
|
|
161
|
+
Returns:
|
|
162
|
+
Truncated tool call ID that meets the length requirement
|
|
163
|
+
"""
|
|
164
|
+
if len(tool_call_id) <= max_length:
|
|
165
|
+
return tool_call_id
|
|
166
|
+
|
|
167
|
+
# Use first part of ID + hash of full ID to maintain uniqueness
|
|
168
|
+
# Format: prefix_hash where prefix is from original and hash ensures uniqueness
|
|
169
|
+
prefix_length = max_length - 33 # Reserve 33 chars for hash (32) + underscore (1)
|
|
170
|
+
if prefix_length < 1:
|
|
171
|
+
prefix_length = 1
|
|
172
|
+
|
|
173
|
+
prefix = tool_call_id[:prefix_length]
|
|
174
|
+
# Use SHA256 and take first 32 hex characters for uniqueness
|
|
175
|
+
hash_suffix = hashlib.sha256(tool_call_id.encode()).hexdigest()[:32]
|
|
176
|
+
|
|
177
|
+
return f"{prefix}_{hash_suffix}"
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def _content_to_message_param(
|
|
181
|
+
content: types.Content,
|
|
182
|
+
) -> Union[Message, list[Message]]:
|
|
183
|
+
"""Converts a types.Content to a litellm Message or list of Messages.
|
|
184
|
+
|
|
185
|
+
Handles multipart function responses by returning a list of
|
|
186
|
+
ChatCompletionToolMessage objects if multiple function_response parts exist.
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
content: The content to convert.
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
A litellm Message, a list of litellm Messages.
|
|
193
|
+
"""
|
|
194
|
+
|
|
195
|
+
tool_messages = []
|
|
196
|
+
for part in content.parts:
|
|
197
|
+
if part.function_response:
|
|
198
|
+
tool_messages.append(
|
|
199
|
+
ChatCompletionToolMessage(
|
|
200
|
+
role="tool",
|
|
201
|
+
tool_call_id=_truncate_tool_call_id(part.function_response.id),
|
|
202
|
+
content=_safe_json_serialize(part.function_response.response),
|
|
203
|
+
)
|
|
204
|
+
)
|
|
205
|
+
if tool_messages:
|
|
206
|
+
return tool_messages if len(tool_messages) > 1 else tool_messages[0]
|
|
207
|
+
|
|
208
|
+
role = _to_litellm_role(content.role)
|
|
209
|
+
message_content = _get_content(content.parts) or None
|
|
210
|
+
|
|
211
|
+
if role == "user":
|
|
212
|
+
return ChatCompletionUserMessage(role="user", content=message_content)
|
|
213
|
+
else: # assistant/model
|
|
214
|
+
tool_calls = []
|
|
215
|
+
content_present = False
|
|
216
|
+
for part in content.parts:
|
|
217
|
+
if part.function_call:
|
|
218
|
+
tool_calls.append(
|
|
219
|
+
ChatCompletionAssistantToolCall(
|
|
220
|
+
type="function",
|
|
221
|
+
id=_truncate_tool_call_id(part.function_call.id),
|
|
222
|
+
function=Function(
|
|
223
|
+
name=part.function_call.name,
|
|
224
|
+
arguments=_safe_json_serialize(part.function_call.args),
|
|
225
|
+
),
|
|
226
|
+
)
|
|
227
|
+
)
|
|
228
|
+
elif part.text or part.inline_data:
|
|
229
|
+
content_present = True
|
|
230
|
+
|
|
231
|
+
final_content = message_content if content_present else None
|
|
232
|
+
if final_content and isinstance(final_content, list):
|
|
233
|
+
# when the content is a single text object, we can use it directly.
|
|
234
|
+
# this is needed for ollama_chat provider which fails if content is a list
|
|
235
|
+
final_content = (
|
|
236
|
+
final_content[0].get("text", "")
|
|
237
|
+
if final_content[0].get("type", None) == "text"
|
|
238
|
+
else final_content
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
return ChatCompletionAssistantMessage(
|
|
242
|
+
role=role,
|
|
243
|
+
content=final_content,
|
|
244
|
+
tool_calls=tool_calls or None,
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def _get_content(
|
|
249
|
+
parts: Iterable[types.Part],
|
|
250
|
+
) -> Union[OpenAIMessageContent, str]:
|
|
251
|
+
"""Converts a list of parts to litellm content.
|
|
252
|
+
|
|
253
|
+
Args:
|
|
254
|
+
parts: The parts to convert.
|
|
255
|
+
|
|
256
|
+
Returns:
|
|
257
|
+
The litellm content.
|
|
258
|
+
"""
|
|
259
|
+
|
|
260
|
+
content_objects = []
|
|
261
|
+
for part in parts:
|
|
262
|
+
if part.text:
|
|
263
|
+
if len(parts) == 1:
|
|
264
|
+
return part.text
|
|
265
|
+
content_objects.append(
|
|
266
|
+
ChatCompletionTextObject(
|
|
267
|
+
type="text",
|
|
268
|
+
text=part.text,
|
|
269
|
+
)
|
|
270
|
+
)
|
|
271
|
+
elif part.inline_data and part.inline_data.data and part.inline_data.mime_type:
|
|
272
|
+
base64_string = base64.b64encode(part.inline_data.data).decode("utf-8")
|
|
273
|
+
data_uri = f"data:{part.inline_data.mime_type};base64,{base64_string}"
|
|
274
|
+
|
|
275
|
+
if part.inline_data.mime_type.startswith("image"):
|
|
276
|
+
content_objects.append(
|
|
277
|
+
ChatCompletionImageUrlObject(
|
|
278
|
+
type="image_url",
|
|
279
|
+
image_url=data_uri,
|
|
280
|
+
)
|
|
281
|
+
)
|
|
282
|
+
elif part.inline_data.mime_type.startswith("video"):
|
|
283
|
+
content_objects.append(
|
|
284
|
+
ChatCompletionVideoUrlObject(
|
|
285
|
+
type="video_url",
|
|
286
|
+
video_url=data_uri,
|
|
287
|
+
)
|
|
288
|
+
)
|
|
289
|
+
else:
|
|
290
|
+
raise ValueError("LiteLlm(BaseLlm) does not support this content part.")
|
|
291
|
+
|
|
292
|
+
return content_objects
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
def _to_litellm_role(role: Optional[str]) -> Literal["user", "assistant"]:
|
|
296
|
+
"""Converts a types.Content role to a litellm role.
|
|
297
|
+
|
|
298
|
+
Args:
|
|
299
|
+
role: The types.Content role.
|
|
300
|
+
|
|
301
|
+
Returns:
|
|
302
|
+
The litellm role.
|
|
303
|
+
"""
|
|
304
|
+
|
|
305
|
+
if role in ["model", "assistant"]:
|
|
306
|
+
return "assistant"
|
|
307
|
+
return "user"
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
TYPE_LABELS = {
|
|
311
|
+
"STRING": "string",
|
|
312
|
+
"NUMBER": "number",
|
|
313
|
+
"BOOLEAN": "boolean",
|
|
314
|
+
"OBJECT": "object",
|
|
315
|
+
"ARRAY": "array",
|
|
316
|
+
"INTEGER": "integer",
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
def _schema_to_dict(schema: types.Schema) -> dict:
|
|
321
|
+
"""Recursively converts a types.Schema to a dictionary.
|
|
322
|
+
|
|
323
|
+
Args:
|
|
324
|
+
schema: The schema to convert.
|
|
325
|
+
|
|
326
|
+
Returns:
|
|
327
|
+
The dictionary representation of the schema.
|
|
328
|
+
"""
|
|
329
|
+
|
|
330
|
+
schema_dict = schema.model_dump(exclude_none=True)
|
|
331
|
+
if "type" in schema_dict:
|
|
332
|
+
schema_dict["type"] = schema_dict["type"].lower()
|
|
333
|
+
if "items" in schema_dict:
|
|
334
|
+
if isinstance(schema_dict["items"], dict):
|
|
335
|
+
schema_dict["items"] = _schema_to_dict(
|
|
336
|
+
types.Schema.model_validate(schema_dict["items"])
|
|
337
|
+
)
|
|
338
|
+
elif isinstance(schema_dict["items"]["type"], types.Type):
|
|
339
|
+
schema_dict["items"]["type"] = TYPE_LABELS[
|
|
340
|
+
schema_dict["items"]["type"].value
|
|
341
|
+
]
|
|
342
|
+
if "properties" in schema_dict:
|
|
343
|
+
properties = {}
|
|
344
|
+
for key, value in schema_dict["properties"].items():
|
|
345
|
+
if isinstance(value, types.Schema):
|
|
346
|
+
properties[key] = _schema_to_dict(value)
|
|
347
|
+
else:
|
|
348
|
+
properties[key] = value
|
|
349
|
+
if "type" in properties[key]:
|
|
350
|
+
properties[key]["type"] = properties[key]["type"].lower()
|
|
351
|
+
schema_dict["properties"] = properties
|
|
352
|
+
return schema_dict
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
def _function_declaration_to_tool_param(
|
|
356
|
+
function_declaration: types.FunctionDeclaration,
|
|
357
|
+
) -> dict:
|
|
358
|
+
"""Converts a types.FunctionDeclaration to a openapi spec dictionary.
|
|
359
|
+
|
|
360
|
+
Args:
|
|
361
|
+
function_declaration: The function declaration to convert.
|
|
362
|
+
|
|
363
|
+
Returns:
|
|
364
|
+
The openapi spec dictionary representation of the function declaration.
|
|
365
|
+
"""
|
|
366
|
+
|
|
367
|
+
assert function_declaration.name
|
|
368
|
+
|
|
369
|
+
properties = {}
|
|
370
|
+
if function_declaration.parameters and function_declaration.parameters.properties:
|
|
371
|
+
for key, value in function_declaration.parameters.properties.items():
|
|
372
|
+
properties[key] = _schema_to_dict(value)
|
|
373
|
+
|
|
374
|
+
return {
|
|
375
|
+
"type": "function",
|
|
376
|
+
"function": {
|
|
377
|
+
"name": function_declaration.name,
|
|
378
|
+
"description": function_declaration.description or "",
|
|
379
|
+
"parameters": {
|
|
380
|
+
"type": "object",
|
|
381
|
+
"properties": properties,
|
|
382
|
+
},
|
|
383
|
+
},
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
def _model_response_to_chunk(
|
|
388
|
+
response: ModelResponse,
|
|
389
|
+
) -> Generator[
|
|
390
|
+
Tuple[
|
|
391
|
+
Optional[Union[TextChunk, FunctionChunk, UsageMetadataChunk]],
|
|
392
|
+
Optional[str],
|
|
393
|
+
],
|
|
394
|
+
None,
|
|
395
|
+
None,
|
|
396
|
+
]:
|
|
397
|
+
"""Converts a litellm message to text, function or usage metadata chunk.
|
|
398
|
+
|
|
399
|
+
Args:
|
|
400
|
+
response: The response from the model.
|
|
401
|
+
|
|
402
|
+
Yields:
|
|
403
|
+
A tuple of text or function or usage metadata chunk and finish reason.
|
|
404
|
+
"""
|
|
405
|
+
|
|
406
|
+
message = None
|
|
407
|
+
if response.get("choices", None):
|
|
408
|
+
message = response["choices"][0].get("message", None)
|
|
409
|
+
finish_reason = response["choices"][0].get("finish_reason", None)
|
|
410
|
+
# check streaming delta
|
|
411
|
+
if message is None and response["choices"][0].get("delta", None):
|
|
412
|
+
message = response["choices"][0]["delta"]
|
|
413
|
+
|
|
414
|
+
if message.get("content", None):
|
|
415
|
+
yield TextChunk(text=message.get("content")), finish_reason
|
|
416
|
+
|
|
417
|
+
if message.get("tool_calls", None):
|
|
418
|
+
for tool_call in message.get("tool_calls"):
|
|
419
|
+
if tool_call.type == "function":
|
|
420
|
+
yield FunctionChunk(
|
|
421
|
+
id=tool_call.id,
|
|
422
|
+
name=tool_call.function.name,
|
|
423
|
+
args=tool_call.function.arguments,
|
|
424
|
+
index=tool_call.index,
|
|
425
|
+
), finish_reason
|
|
426
|
+
|
|
427
|
+
if finish_reason and not (
|
|
428
|
+
message.get("content", None) or message.get("tool_calls", None)
|
|
429
|
+
):
|
|
430
|
+
yield None, finish_reason
|
|
431
|
+
|
|
432
|
+
if not message:
|
|
433
|
+
yield None, None
|
|
434
|
+
|
|
435
|
+
# Ideally usage would be expected with the last ModelResponseStream with a
|
|
436
|
+
# finish_reason set. But this is not the case we are observing from litellm.
|
|
437
|
+
# So we are sending it as a separate chunk to be set on the llm_response.
|
|
438
|
+
if response.get("usage", None):
|
|
439
|
+
yield UsageMetadataChunk(
|
|
440
|
+
prompt_tokens=response["usage"].get("prompt_tokens", 0),
|
|
441
|
+
completion_tokens=response["usage"].get("completion_tokens", 0),
|
|
442
|
+
total_tokens=response["usage"].get("total_tokens", 0),
|
|
443
|
+
), None
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
def _model_response_to_generate_content_response(
|
|
447
|
+
response: ModelResponse,
|
|
448
|
+
) -> LlmResponse:
|
|
449
|
+
"""Converts a litellm response to LlmResponse. Also adds usage metadata.
|
|
450
|
+
|
|
451
|
+
Args:
|
|
452
|
+
response: The model response.
|
|
453
|
+
|
|
454
|
+
Returns:
|
|
455
|
+
The LlmResponse.
|
|
456
|
+
"""
|
|
457
|
+
|
|
458
|
+
message = None
|
|
459
|
+
if response.get("choices", None):
|
|
460
|
+
message = response["choices"][0].get("message", None)
|
|
461
|
+
|
|
462
|
+
if not message:
|
|
463
|
+
raise ValueError("No message in response")
|
|
464
|
+
|
|
465
|
+
llm_response = _message_to_generate_content_response(message)
|
|
466
|
+
if response.get("usage", None):
|
|
467
|
+
llm_response.usage_metadata = types.GenerateContentResponseUsageMetadata(
|
|
468
|
+
prompt_token_count=response["usage"].get("prompt_tokens", 0),
|
|
469
|
+
candidates_token_count=response["usage"].get("completion_tokens", 0),
|
|
470
|
+
total_token_count=response["usage"].get("total_tokens", 0),
|
|
471
|
+
)
|
|
472
|
+
return llm_response
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
def _message_to_generate_content_response(
|
|
476
|
+
message: Message, is_partial: bool = False
|
|
477
|
+
) -> LlmResponse:
|
|
478
|
+
"""Converts a litellm message to LlmResponse.
|
|
479
|
+
|
|
480
|
+
Args:
|
|
481
|
+
message: The message to convert.
|
|
482
|
+
is_partial: Whether the message is partial.
|
|
483
|
+
|
|
484
|
+
Returns:
|
|
485
|
+
The LlmResponse.
|
|
486
|
+
"""
|
|
487
|
+
|
|
488
|
+
parts = []
|
|
489
|
+
if message.get("content", None):
|
|
490
|
+
parts.append(types.Part.from_text(text=message.get("content")))
|
|
491
|
+
|
|
492
|
+
if message.get("tool_calls", None):
|
|
493
|
+
for tool_call in message.get("tool_calls"):
|
|
494
|
+
if tool_call.type == "function":
|
|
495
|
+
try:
|
|
496
|
+
part = types.Part.from_function_call(
|
|
497
|
+
name=tool_call.function.name,
|
|
498
|
+
args=json.loads(tool_call.function.arguments or "{}"),
|
|
499
|
+
)
|
|
500
|
+
part.function_call.id = _truncate_tool_call_id(tool_call.id)
|
|
501
|
+
parts.append(part)
|
|
502
|
+
except json.JSONDecodeError as e:
|
|
503
|
+
logger.error(
|
|
504
|
+
"Failed to decode function call arguments: %s. Arguments: %s",
|
|
505
|
+
e,
|
|
506
|
+
tool_call.function.arguments,
|
|
507
|
+
)
|
|
508
|
+
|
|
509
|
+
return LlmResponse(
|
|
510
|
+
content=types.Content(role="model", parts=parts), partial=is_partial
|
|
511
|
+
)
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
def _get_completion_inputs(
|
|
515
|
+
llm_request: LlmRequest,
|
|
516
|
+
cache_strategy: str = "5m",
|
|
517
|
+
) -> Tuple[
|
|
518
|
+
List[Message],
|
|
519
|
+
Optional[List[Dict]],
|
|
520
|
+
Optional[types.SchemaUnion],
|
|
521
|
+
Optional[Dict],
|
|
522
|
+
]:
|
|
523
|
+
"""Converts an LlmRequest to litellm inputs and extracts generation params.
|
|
524
|
+
|
|
525
|
+
Args:
|
|
526
|
+
llm_request: The LlmRequest to convert.
|
|
527
|
+
cache_strategy: Cache strategy to apply ("none", "5m", "1h").
|
|
528
|
+
|
|
529
|
+
Returns:
|
|
530
|
+
The litellm inputs (message list, tool dictionary and response format).
|
|
531
|
+
"""
|
|
532
|
+
messages: List[Message] = []
|
|
533
|
+
for content in llm_request.contents or []:
|
|
534
|
+
message_param_or_list = _content_to_message_param(content)
|
|
535
|
+
if isinstance(message_param_or_list, list):
|
|
536
|
+
messages.extend(message_param_or_list)
|
|
537
|
+
elif message_param_or_list: # Ensure it's not None before appending
|
|
538
|
+
messages.append(message_param_or_list)
|
|
539
|
+
|
|
540
|
+
if llm_request.config and llm_request.config.system_instruction:
|
|
541
|
+
# Build system instruction content with optional cache control
|
|
542
|
+
system_content = {
|
|
543
|
+
"type": "text",
|
|
544
|
+
"text": llm_request.config.system_instruction,
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
# Add cache control based on strategy
|
|
548
|
+
# LiteLLM translates this to provider-specific format (Anthropic, OpenAI, Bedrock, Deepseek)
|
|
549
|
+
if cache_strategy == "5m":
|
|
550
|
+
# 5-minute ephemeral cache (Anthropic default)
|
|
551
|
+
system_content["cache_control"] = {"type": "ephemeral"}
|
|
552
|
+
elif cache_strategy == "1h":
|
|
553
|
+
# 1-hour extended cache (Anthropic extended)
|
|
554
|
+
system_content["cache_control"] = {"type": "ephemeral", "ttl": "1h"}
|
|
555
|
+
# For "none", no cache_control is added
|
|
556
|
+
|
|
557
|
+
messages.insert(
|
|
558
|
+
0,
|
|
559
|
+
ChatCompletionDeveloperMessage(
|
|
560
|
+
role="developer",
|
|
561
|
+
content=[system_content],
|
|
562
|
+
),
|
|
563
|
+
)
|
|
564
|
+
|
|
565
|
+
# 2. Convert tool declarations with caching support
|
|
566
|
+
tools: Optional[List[Dict]] = None
|
|
567
|
+
if (
|
|
568
|
+
llm_request.config
|
|
569
|
+
and llm_request.config.tools
|
|
570
|
+
and llm_request.config.tools[0].function_declarations
|
|
571
|
+
):
|
|
572
|
+
tools = [
|
|
573
|
+
_function_declaration_to_tool_param(tool)
|
|
574
|
+
for tool in llm_request.config.tools[0].function_declarations
|
|
575
|
+
]
|
|
576
|
+
|
|
577
|
+
# Enable tool caching via LiteLLM's generic interface
|
|
578
|
+
# LiteLLM handles provider-specific translation (Anthropic, OpenAI, Bedrock, Deepseek)
|
|
579
|
+
# Tools are stable because peer agents are alphabetically sorted (component.py)
|
|
580
|
+
if tools and cache_strategy != "none":
|
|
581
|
+
# Add cache_control to the LAST tool (required by caching providers)
|
|
582
|
+
if cache_strategy == "5m":
|
|
583
|
+
tools[-1]["cache_control"] = {"type": "ephemeral"}
|
|
584
|
+
elif cache_strategy == "1h":
|
|
585
|
+
tools[-1]["cache_control"] = {"type": "ephemeral", "ttl": "1h"}
|
|
586
|
+
|
|
587
|
+
# 3. Handle response format
|
|
588
|
+
response_format: Optional[types.SchemaUnion] = None
|
|
589
|
+
if llm_request.config and llm_request.config.response_schema:
|
|
590
|
+
response_format = llm_request.config.response_schema
|
|
591
|
+
|
|
592
|
+
# 4. Extract generation parameters
|
|
593
|
+
generation_params: Optional[Dict] = None
|
|
594
|
+
if llm_request.config:
|
|
595
|
+
config_dict = llm_request.config.model_dump(exclude_none=True)
|
|
596
|
+
# Generate LiteLlm parameters here,
|
|
597
|
+
# Following https://docs.litellm.ai/docs/completion/input.
|
|
598
|
+
generation_params = {}
|
|
599
|
+
param_mapping = {
|
|
600
|
+
"max_output_tokens": "max_completion_tokens",
|
|
601
|
+
"stop_sequences": "stop",
|
|
602
|
+
}
|
|
603
|
+
for key in (
|
|
604
|
+
"temperature",
|
|
605
|
+
"max_output_tokens",
|
|
606
|
+
"top_p",
|
|
607
|
+
"top_k",
|
|
608
|
+
"stop_sequences",
|
|
609
|
+
"presence_penalty",
|
|
610
|
+
"frequency_penalty",
|
|
611
|
+
):
|
|
612
|
+
if key in config_dict:
|
|
613
|
+
mapped_key = param_mapping.get(key, key)
|
|
614
|
+
generation_params[mapped_key] = config_dict[key]
|
|
615
|
+
|
|
616
|
+
if not generation_params:
|
|
617
|
+
generation_params = None
|
|
618
|
+
|
|
619
|
+
return messages, tools, response_format, generation_params
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
def _build_function_declaration_log(
|
|
623
|
+
func_decl: types.FunctionDeclaration,
|
|
624
|
+
) -> str:
|
|
625
|
+
"""Builds a function declaration log.
|
|
626
|
+
|
|
627
|
+
Args:
|
|
628
|
+
func_decl: The function declaration to convert.
|
|
629
|
+
|
|
630
|
+
Returns:
|
|
631
|
+
The function declaration log.
|
|
632
|
+
"""
|
|
633
|
+
|
|
634
|
+
param_str = "{}"
|
|
635
|
+
if func_decl.parameters and func_decl.parameters.properties:
|
|
636
|
+
param_str = str(
|
|
637
|
+
{
|
|
638
|
+
k: v.model_dump(exclude_none=True)
|
|
639
|
+
for k, v in func_decl.parameters.properties.items()
|
|
640
|
+
}
|
|
641
|
+
)
|
|
642
|
+
return_str = "None"
|
|
643
|
+
if func_decl.response:
|
|
644
|
+
return_str = str(func_decl.response.model_dump(exclude_none=True))
|
|
645
|
+
return f"{func_decl.name}: {param_str} -> {return_str}"
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
def _build_request_log(req: LlmRequest) -> str:
|
|
649
|
+
"""Builds a request log.
|
|
650
|
+
|
|
651
|
+
Args:
|
|
652
|
+
req: The request to convert.
|
|
653
|
+
|
|
654
|
+
Returns:
|
|
655
|
+
The request log.
|
|
656
|
+
"""
|
|
657
|
+
|
|
658
|
+
function_decls: list[types.FunctionDeclaration] = cast(
|
|
659
|
+
list[types.FunctionDeclaration],
|
|
660
|
+
req.config.tools[0].function_declarations if req.config and req.config.tools else [],
|
|
661
|
+
)
|
|
662
|
+
function_logs = (
|
|
663
|
+
[_build_function_declaration_log(func_decl) for func_decl in function_decls]
|
|
664
|
+
if function_decls
|
|
665
|
+
else []
|
|
666
|
+
)
|
|
667
|
+
contents_logs = [
|
|
668
|
+
content.model_dump_json(
|
|
669
|
+
exclude_none=True,
|
|
670
|
+
exclude={
|
|
671
|
+
"parts": {i: _EXCLUDED_PART_FIELD for i in range(len(content.parts))}
|
|
672
|
+
},
|
|
673
|
+
)
|
|
674
|
+
for content in req.contents
|
|
675
|
+
]
|
|
676
|
+
|
|
677
|
+
return f"""
|
|
678
|
+
LLM Request:
|
|
679
|
+
-----------------------------------------------------------
|
|
680
|
+
System Instruction:
|
|
681
|
+
{req.config.system_instruction if req.config else None}
|
|
682
|
+
-----------------------------------------------------------
|
|
683
|
+
Contents:
|
|
684
|
+
{_NEW_LINE.join(contents_logs)}
|
|
685
|
+
-----------------------------------------------------------
|
|
686
|
+
Functions:
|
|
687
|
+
{_NEW_LINE.join(function_logs)}
|
|
688
|
+
-----------------------------------------------------------
|
|
689
|
+
"""
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
class LiteLlm(BaseLlm):
|
|
693
|
+
"""Wrapper around litellm.
|
|
694
|
+
|
|
695
|
+
This wrapper can be used with any of the models supported by litellm. The
|
|
696
|
+
environment variable(s) needed for authenticating with the model endpoint must
|
|
697
|
+
be set prior to instantiating this class.
|
|
698
|
+
|
|
699
|
+
Example usage:
|
|
700
|
+
```
|
|
701
|
+
os.environ["VERTEXAI_PROJECT"] = "your-gcp-project-id"
|
|
702
|
+
os.environ["VERTEXAI_LOCATION"] = "your-gcp-location"
|
|
703
|
+
|
|
704
|
+
agent = Agent(
|
|
705
|
+
model=LiteLlm(model="vertex_ai/claude-3-7-sonnet@20250219"),
|
|
706
|
+
...
|
|
707
|
+
)
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
Attributes:
|
|
711
|
+
model: The name of the LiteLlm model.
|
|
712
|
+
llm_client: The LLM client to use for the model.
|
|
713
|
+
"""
|
|
714
|
+
|
|
715
|
+
llm_client: LiteLLMClient = Field(default_factory=LiteLLMClient)
|
|
716
|
+
"""The LLM client to use for the model."""
|
|
717
|
+
|
|
718
|
+
_additional_args: Dict[str, Any] = None
|
|
719
|
+
_oauth_token_manager: Optional[OAuth2ClientCredentialsTokenManager] = None
|
|
720
|
+
_cache_strategy: str = "5m" # Default to 5-minute ephemeral cache
|
|
721
|
+
|
|
722
|
+
def __init__(self, model: str, cache_strategy: str = "5m", **kwargs):
|
|
723
|
+
"""Initializes the LiteLlm class.
|
|
724
|
+
|
|
725
|
+
Args:
|
|
726
|
+
model: The name of the LiteLlm model.
|
|
727
|
+
cache_strategy: Cache strategy to use. Options: "none", "5m" (ephemeral), "1h" (extended).
|
|
728
|
+
Defaults to "5m" for backward compatibility.
|
|
729
|
+
**kwargs: Additional arguments to pass to the litellm completion api.
|
|
730
|
+
Can include OAuth configuration parameters.
|
|
731
|
+
"""
|
|
732
|
+
super().__init__(model=model, **kwargs)
|
|
733
|
+
self._additional_args = kwargs.copy()
|
|
734
|
+
|
|
735
|
+
# Remove handlers added by LiteLLM as they produce duplicate and misformatted logs.
|
|
736
|
+
# Logging is an application concern and libraries should not set handlers/formatters.
|
|
737
|
+
for logger_name in ["LiteLLM", "LiteLLM Proxy", "LiteLLM Router", "litellm"]:
|
|
738
|
+
logging.getLogger(logger_name).handlers.clear()
|
|
739
|
+
|
|
740
|
+
# Validate and store cache strategy
|
|
741
|
+
valid_strategies = ["none", "5m", "1h"]
|
|
742
|
+
if cache_strategy not in valid_strategies:
|
|
743
|
+
logger.warning(
|
|
744
|
+
"Invalid cache_strategy '%s'. Valid options are: %s. Defaulting to '5m'.",
|
|
745
|
+
cache_strategy,
|
|
746
|
+
valid_strategies,
|
|
747
|
+
)
|
|
748
|
+
cache_strategy = "5m"
|
|
749
|
+
self._cache_strategy = cache_strategy
|
|
750
|
+
logger.info("LiteLlm initialized with cache strategy: %s", self._cache_strategy)
|
|
751
|
+
|
|
752
|
+
# Extract OAuth configuration if present
|
|
753
|
+
oauth_config = self._extract_oauth_config(self._additional_args)
|
|
754
|
+
if oauth_config:
|
|
755
|
+
self._oauth_token_manager = OAuth2ClientCredentialsTokenManager(**oauth_config)
|
|
756
|
+
logger.info("OAuth2 token manager initialized for model: %s", model)
|
|
757
|
+
else:
|
|
758
|
+
self._oauth_token_manager = None
|
|
759
|
+
|
|
760
|
+
# preventing generation call with llm_client
|
|
761
|
+
# and overriding messages, tools and stream which are managed internally
|
|
762
|
+
self._additional_args.pop("llm_client", None)
|
|
763
|
+
self._additional_args.pop("messages", None)
|
|
764
|
+
self._additional_args.pop("tools", None)
|
|
765
|
+
# public api called from runner determines to stream or not
|
|
766
|
+
self._additional_args.pop("stream", None)
|
|
767
|
+
|
|
768
|
+
def _extract_oauth_config(self, kwargs: Dict[str, Any]) -> Optional[Dict[str, Any]]:
|
|
769
|
+
"""Extract OAuth configuration from kwargs.
|
|
770
|
+
|
|
771
|
+
Args:
|
|
772
|
+
kwargs: Keyword arguments that may contain OAuth parameters
|
|
773
|
+
|
|
774
|
+
Returns:
|
|
775
|
+
OAuth configuration dictionary or None if no OAuth config found
|
|
776
|
+
"""
|
|
777
|
+
oauth_params = [
|
|
778
|
+
"oauth_token_url",
|
|
779
|
+
"oauth_client_id",
|
|
780
|
+
"oauth_client_secret",
|
|
781
|
+
"oauth_scope",
|
|
782
|
+
"oauth_ca_cert",
|
|
783
|
+
"oauth_token_refresh_buffer_seconds",
|
|
784
|
+
"oauth_max_retries"
|
|
785
|
+
]
|
|
786
|
+
|
|
787
|
+
oauth_config = {}
|
|
788
|
+
for param in oauth_params:
|
|
789
|
+
if param in kwargs:
|
|
790
|
+
# Map parameter names to OAuth2ClientCredentialsTokenManager constructor
|
|
791
|
+
if param == "oauth_ca_cert":
|
|
792
|
+
oauth_config["ca_cert_path"] = kwargs.pop(param)
|
|
793
|
+
elif param == "oauth_token_refresh_buffer_seconds":
|
|
794
|
+
oauth_config["refresh_buffer_seconds"] = kwargs.pop(param)
|
|
795
|
+
elif param == "oauth_max_retries":
|
|
796
|
+
oauth_config["max_retries"] = kwargs.pop(param)
|
|
797
|
+
else:
|
|
798
|
+
# Remove oauth_ prefix for the token manager
|
|
799
|
+
key = param.replace("oauth_", "")
|
|
800
|
+
oauth_config[key] = kwargs.pop(param)
|
|
801
|
+
|
|
802
|
+
# Return config only if we have the required parameters
|
|
803
|
+
if "token_url" in oauth_config and "client_id" in oauth_config and "client_secret" in oauth_config:
|
|
804
|
+
return oauth_config
|
|
805
|
+
elif oauth_config:
|
|
806
|
+
logger.warning("Incomplete OAuth configuration found, missing required parameters")
|
|
807
|
+
|
|
808
|
+
return None
|
|
809
|
+
|
|
810
|
+
async def generate_content_async(
|
|
811
|
+
self, llm_request: LlmRequest, stream: bool = False
|
|
812
|
+
) -> AsyncGenerator[LlmResponse, None]:
|
|
813
|
+
"""Generates content asynchronously.
|
|
814
|
+
|
|
815
|
+
Args:
|
|
816
|
+
llm_request: LlmRequest, the request to send to the LiteLlm model.
|
|
817
|
+
stream: bool = False, whether to do streaming call.
|
|
818
|
+
|
|
819
|
+
Yields:
|
|
820
|
+
LlmResponse: The model response.
|
|
821
|
+
"""
|
|
822
|
+
|
|
823
|
+
if not llm_request.contents or llm_request.contents[-1].role not in [
|
|
824
|
+
"user",
|
|
825
|
+
"tool",
|
|
826
|
+
]:
|
|
827
|
+
self._maybe_append_user_content(llm_request)
|
|
828
|
+
logger.debug(_build_request_log(llm_request))
|
|
829
|
+
|
|
830
|
+
messages, tools, response_format, generation_params = _get_completion_inputs(
|
|
831
|
+
llm_request, self._cache_strategy
|
|
832
|
+
)
|
|
833
|
+
completion_args = {
|
|
834
|
+
"model": self.model,
|
|
835
|
+
"messages": messages,
|
|
836
|
+
"tools": tools,
|
|
837
|
+
"response_format": response_format,
|
|
838
|
+
"stream_options": {"include_usage": True},
|
|
839
|
+
}
|
|
840
|
+
completion_args.update(self._additional_args)
|
|
841
|
+
|
|
842
|
+
# Inject OAuth token if OAuth is configured
|
|
843
|
+
if self._oauth_token_manager:
|
|
844
|
+
try:
|
|
845
|
+
access_token = await self._oauth_token_manager.get_token()
|
|
846
|
+
# Inject Bearer token via extra_headers
|
|
847
|
+
extra_headers = completion_args.get("extra_headers", {})
|
|
848
|
+
extra_headers["Authorization"] = f"Bearer {access_token}"
|
|
849
|
+
completion_args["extra_headers"] = extra_headers
|
|
850
|
+
logger.debug("OAuth token injected into request headers")
|
|
851
|
+
except Exception as e:
|
|
852
|
+
logger.error("Failed to get OAuth token: %s", str(e))
|
|
853
|
+
# Check if we have a fallback API key
|
|
854
|
+
if "api_key" in completion_args:
|
|
855
|
+
logger.info("Falling back to API key authentication")
|
|
856
|
+
else:
|
|
857
|
+
logger.error("No fallback authentication available")
|
|
858
|
+
raise
|
|
859
|
+
|
|
860
|
+
if generation_params:
|
|
861
|
+
completion_args.update(generation_params)
|
|
862
|
+
|
|
863
|
+
if not tools and completion_args.get("parallel_tool_calls", False):
|
|
864
|
+
# Setting parallel_tool_calls without any tools causes an error from Anthropic.
|
|
865
|
+
completion_args.pop("parallel_tool_calls")
|
|
866
|
+
|
|
867
|
+
if stream:
|
|
868
|
+
text = ""
|
|
869
|
+
function_calls = {} # index -> {name, args, id}
|
|
870
|
+
completion_args["stream"] = True
|
|
871
|
+
aggregated_llm_response = None
|
|
872
|
+
aggregated_llm_response_with_tool_call = None
|
|
873
|
+
usage_metadata = None
|
|
874
|
+
fallback_index = 0
|
|
875
|
+
async for part in await self.llm_client.acompletion(**completion_args):
|
|
876
|
+
for chunk, finish_reason in _model_response_to_chunk(part):
|
|
877
|
+
if isinstance(chunk, FunctionChunk):
|
|
878
|
+
index = chunk.index or fallback_index
|
|
879
|
+
if index not in function_calls:
|
|
880
|
+
function_calls[index] = {"name": "", "args": "", "id": None}
|
|
881
|
+
|
|
882
|
+
if chunk.name:
|
|
883
|
+
function_calls[index]["name"] += chunk.name
|
|
884
|
+
if chunk.args:
|
|
885
|
+
function_calls[index]["args"] += chunk.args
|
|
886
|
+
|
|
887
|
+
# check if args is completed (workaround for improper chunk
|
|
888
|
+
# indexing)
|
|
889
|
+
try:
|
|
890
|
+
json.loads(function_calls[index]["args"])
|
|
891
|
+
fallback_index += 1
|
|
892
|
+
except json.JSONDecodeError:
|
|
893
|
+
pass
|
|
894
|
+
|
|
895
|
+
function_calls[index]["id"] = (
|
|
896
|
+
chunk.id or function_calls[index]["id"] or str(index)
|
|
897
|
+
)
|
|
898
|
+
elif isinstance(chunk, TextChunk):
|
|
899
|
+
text += chunk.text
|
|
900
|
+
yield _message_to_generate_content_response(
|
|
901
|
+
ChatCompletionAssistantMessage(
|
|
902
|
+
role="assistant",
|
|
903
|
+
content=chunk.text,
|
|
904
|
+
),
|
|
905
|
+
is_partial=True,
|
|
906
|
+
)
|
|
907
|
+
elif isinstance(chunk, UsageMetadataChunk):
|
|
908
|
+
usage_metadata = types.GenerateContentResponseUsageMetadata(
|
|
909
|
+
prompt_token_count=chunk.prompt_tokens,
|
|
910
|
+
candidates_token_count=chunk.completion_tokens,
|
|
911
|
+
total_token_count=chunk.total_tokens,
|
|
912
|
+
)
|
|
913
|
+
|
|
914
|
+
if (
|
|
915
|
+
finish_reason == "tool_calls" or finish_reason == "stop"
|
|
916
|
+
) and function_calls:
|
|
917
|
+
tool_calls = []
|
|
918
|
+
for index, func_data in function_calls.items():
|
|
919
|
+
if func_data["id"]:
|
|
920
|
+
tool_calls.append(
|
|
921
|
+
ChatCompletionMessageToolCall(
|
|
922
|
+
type="function",
|
|
923
|
+
id=_truncate_tool_call_id(func_data["id"]),
|
|
924
|
+
function=Function(
|
|
925
|
+
name=func_data["name"],
|
|
926
|
+
arguments=func_data["args"],
|
|
927
|
+
index=index,
|
|
928
|
+
),
|
|
929
|
+
)
|
|
930
|
+
)
|
|
931
|
+
aggregated_llm_response_with_tool_call = (
|
|
932
|
+
_message_to_generate_content_response(
|
|
933
|
+
ChatCompletionAssistantMessage(
|
|
934
|
+
role="assistant",
|
|
935
|
+
content=text or "",
|
|
936
|
+
tool_calls=tool_calls,
|
|
937
|
+
)
|
|
938
|
+
)
|
|
939
|
+
)
|
|
940
|
+
function_calls.clear()
|
|
941
|
+
text = ""
|
|
942
|
+
elif finish_reason == "length":
|
|
943
|
+
# The stream was interrupted due to token limit.
|
|
944
|
+
# Create a final response indicating interruption, including any
|
|
945
|
+
# buffered text AND any buffered tool calls.
|
|
946
|
+
tool_calls = []
|
|
947
|
+
for index, func_data in function_calls.items():
|
|
948
|
+
if func_data["id"]:
|
|
949
|
+
tool_calls.append(
|
|
950
|
+
ChatCompletionMessageToolCall(
|
|
951
|
+
type="function",
|
|
952
|
+
id=_truncate_tool_call_id(func_data["id"]),
|
|
953
|
+
function=Function(
|
|
954
|
+
name=func_data["name"],
|
|
955
|
+
arguments=func_data["args"],
|
|
956
|
+
index=index,
|
|
957
|
+
),
|
|
958
|
+
)
|
|
959
|
+
)
|
|
960
|
+
|
|
961
|
+
aggregated_llm_response = _message_to_generate_content_response(
|
|
962
|
+
ChatCompletionAssistantMessage(
|
|
963
|
+
role="assistant",
|
|
964
|
+
content=text or None,
|
|
965
|
+
tool_calls=tool_calls or None,
|
|
966
|
+
)
|
|
967
|
+
)
|
|
968
|
+
aggregated_llm_response.interrupted = True
|
|
969
|
+
|
|
970
|
+
# Yield the interrupted response immediately and stop processing this stream.
|
|
971
|
+
# This ensures the partial text and tool calls are preserved.
|
|
972
|
+
if usage_metadata:
|
|
973
|
+
aggregated_llm_response.usage_metadata = usage_metadata
|
|
974
|
+
yield aggregated_llm_response
|
|
975
|
+
return
|
|
976
|
+
elif finish_reason == "MALFORMED_FUNCTION_CALL":
|
|
977
|
+
# Create an error response that will allow the LLM to continue
|
|
978
|
+
aggregated_llm_response = _message_to_generate_content_response(
|
|
979
|
+
ChatCompletionAssistantMessage(
|
|
980
|
+
role="assistant",
|
|
981
|
+
content="I attempted to call a function that doesn't exist or with invalid parameters. Let me try a different approach or provide a direct response instead.",
|
|
982
|
+
),
|
|
983
|
+
is_partial=True,
|
|
984
|
+
)
|
|
985
|
+
text = ""
|
|
986
|
+
elif finish_reason == "stop" and text:
|
|
987
|
+
aggregated_llm_response = _message_to_generate_content_response(
|
|
988
|
+
ChatCompletionAssistantMessage(
|
|
989
|
+
role="assistant", content=text
|
|
990
|
+
)
|
|
991
|
+
)
|
|
992
|
+
text = ""
|
|
993
|
+
|
|
994
|
+
# waiting until streaming ends to yield the llm_response as litellm tends
|
|
995
|
+
# to send chunk that contains usage_metadata after the chunk with
|
|
996
|
+
# finish_reason set to tool_calls or stop.
|
|
997
|
+
if aggregated_llm_response:
|
|
998
|
+
if usage_metadata:
|
|
999
|
+
aggregated_llm_response.usage_metadata = usage_metadata
|
|
1000
|
+
usage_metadata = None
|
|
1001
|
+
yield aggregated_llm_response
|
|
1002
|
+
|
|
1003
|
+
if aggregated_llm_response_with_tool_call:
|
|
1004
|
+
if usage_metadata:
|
|
1005
|
+
aggregated_llm_response_with_tool_call.usage_metadata = (
|
|
1006
|
+
usage_metadata
|
|
1007
|
+
)
|
|
1008
|
+
yield aggregated_llm_response_with_tool_call
|
|
1009
|
+
|
|
1010
|
+
else:
|
|
1011
|
+
response = await self.llm_client.acompletion(**completion_args)
|
|
1012
|
+
yield _model_response_to_generate_content_response(response)
|
|
1013
|
+
|
|
1014
|
+
@staticmethod
|
|
1015
|
+
@override
|
|
1016
|
+
def supported_models() -> list[str]:
|
|
1017
|
+
"""Provides the list of supported models.
|
|
1018
|
+
|
|
1019
|
+
LiteLlm supports all models supported by litellm. We do not keep track of
|
|
1020
|
+
these models here. So we return an empty list.
|
|
1021
|
+
|
|
1022
|
+
Returns:
|
|
1023
|
+
A list of supported models.
|
|
1024
|
+
"""
|
|
1025
|
+
|
|
1026
|
+
return []
|