agentengine-sdk-python 0.7.0__py3-none-any.whl → 0.8.1__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.
- {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/METADATA +52 -20
- agentengine_sdk_python-0.8.1.dist-info/RECORD +644 -0
- {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/WHEEL +1 -1
- ksadk/a2a/__init__.py +180 -11
- ksadk/a2a/bootstrap.py +332 -0
- ksadk/a2a/card.py +15 -0
- ksadk/a2a/context_store.py +203 -0
- ksadk/a2a/control_plane.py +1056 -0
- ksadk/a2a/credential.py +99 -0
- ksadk/a2a/event_adapter.py +149 -0
- ksadk/a2a/executor.py +361 -137
- ksadk/a2a/external_transport.py +516 -0
- ksadk/a2a/identity.py +304 -0
- ksadk/a2a/ids.py +22 -0
- ksadk/a2a/langgraph.py +285 -0
- ksadk/a2a/resume_store.py +201 -0
- ksadk/a2a/routes.py +112 -0
- ksadk/a2a/server.py +102 -62
- ksadk/a2a/service_env.py +33 -0
- ksadk/a2a/space_client.py +1122 -0
- ksadk/a2a/task_adapter.py +423 -0
- ksadk/a2a/task_event_dispatcher.py +167 -0
- ksadk/a2a/task_event_outbox.py +326 -0
- ksadk/a2a/task_store.py +206 -0
- ksadk/a2a_card.py +101 -0
- ksadk/a2ui/__init__.py +27 -0
- ksadk/a2ui/core.py +186 -0
- ksadk/a2ui/models.py +166 -0
- ksadk/a2ui/renderer.py +198 -0
- ksadk/agui/__init__.py +9 -0
- ksadk/agui/a2ui_projection.py +92 -0
- ksadk/agui/agent.py +872 -0
- ksadk/agui/config.py +92 -0
- ksadk/agui/routes.py +47 -0
- ksadk/api/client.py +238 -204
- ksadk/api/environment.py +27 -0
- ksadk/builders/__init__.py +2 -0
- ksadk/builders/base.py +16 -14
- ksadk/builders/code_builder.py +375 -270
- ksadk/builders/container_builder.py +240 -200
- ksadk/builders/framework_requirements.py +31 -12
- ksadk/builders/ks3_uploader.py +60 -29
- ksadk/builders/managed_runtime_builder.py +173 -0
- ksadk/builders/mcp_builder.py +91 -92
- ksadk/builders/requirements_utils.py +1 -5
- ksadk/cli/__init__.py +97 -171
- ksadk/cli/cmd_a2a.py +255 -84
- ksadk/cli/cmd_agent.py +19 -5
- ksadk/cli/cmd_build.py +158 -29
- ksadk/cli/cmd_completion.py +47 -35
- ksadk/cli/cmd_config.py +267 -198
- ksadk/cli/cmd_create.py +507 -740
- ksadk/cli/cmd_dashboard.py +120 -45
- ksadk/cli/cmd_deploy.py +135 -59
- ksadk/cli/cmd_destroy.py +44 -14
- ksadk/cli/cmd_eval.py +386 -0
- ksadk/cli/cmd_files.py +63 -24
- ksadk/cli/cmd_hermes.py +313 -135
- ksadk/cli/cmd_invoke.py +184 -122
- ksadk/cli/cmd_launch.py +76 -28
- ksadk/cli/cmd_mcp.py +98 -64
- ksadk/cli/cmd_model.py +14 -5
- ksadk/cli/cmd_openclaw.py +564 -268
- ksadk/cli/cmd_replay.py +71 -0
- ksadk/cli/cmd_run.py +58 -73
- ksadk/cli/cmd_status.py +80 -31
- ksadk/cli/cmd_studio.py +110 -0
- ksadk/cli/cmd_version.py +20 -13
- ksadk/cli/cmd_web.py +95 -18
- ksadk/cli/deploy_utils.py +20 -20
- ksadk/cli/dry_run.py +7 -4
- ksadk/cli/env_options.py +83 -0
- ksadk/cli/error_utils.py +37 -12
- ksadk/cli/global_options.py +4 -3
- ksadk/cli/local_runtime.py +1 -2
- ksadk/cli/model_catalog.py +6 -2
- ksadk/cli/network_options.py +41 -19
- ksadk/cli/resource_common.py +6 -2
- ksadk/cli/runtime_bootstrap.py +51 -0
- ksadk/cli/storage.py +0 -1
- ksadk/cli/ui.py +11 -3
- ksadk/cli/workflow_common.py +52 -18
- ksadk/codex/__init__.py +12 -0
- ksadk/codex/client.py +1042 -0
- ksadk/codex/phase.py +143 -0
- ksadk/codex/runtime.py +940 -0
- ksadk/common/aicp_env.py +0 -1
- ksadk/common/auth.py +2 -2
- ksadk/common/constants.py +1 -3
- ksadk/common/kop_client.py +232 -0
- ksadk/common/llm_utils.py +17 -13
- ksadk/compat/__init__.py +5 -0
- ksadk/compat/adk_compat.py +200 -0
- ksadk/compat/copilotkit_a2ui.py +330 -0
- ksadk/configs/__init__.py +12 -14
- ksadk/configs/env_registry.py +661 -116
- ksadk/configs/global_config.py +3 -2
- ksadk/configs/settings.py +133 -209
- ksadk/conversations/__init__.py +85 -92
- ksadk/conversations/attachment_storage.py +16 -11
- ksadk/conversations/attachments.py +44 -36
- ksadk/conversations/compaction_pipeline.py +12 -12
- ksadk/conversations/compaction_prompt.py +9 -5
- ksadk/conversations/context.py +221 -6
- ksadk/conversations/message_projection.py +438 -51
- ksadk/conversations/model_context.py +12 -6
- ksadk/conversations/model_options.py +0 -1
- ksadk/conversations/normalize.py +20 -16
- ksadk/conversations/reasoning_markup.py +1 -1
- ksadk/conversations/runtime.py +339 -5255
- ksadk/conversations/runtime_compaction.py +333 -0
- ksadk/conversations/runtime_constants.py +27 -0
- ksadk/conversations/runtime_governance.py +185 -0
- ksadk/conversations/runtime_input.py +660 -0
- ksadk/conversations/runtime_invocation.py +395 -0
- ksadk/conversations/runtime_metadata.py +475 -0
- ksadk/conversations/runtime_observability.py +367 -0
- ksadk/conversations/runtime_payloads.py +272 -0
- ksadk/conversations/runtime_persistence.py +440 -0
- ksadk/conversations/runtime_preparation.py +426 -0
- ksadk/conversations/runtime_resume.py +836 -0
- ksadk/conversations/runtime_stream_events.py +902 -0
- ksadk/conversations/runtime_streaming.py +700 -0
- ksadk/conversations/semantic_summary.py +17 -5
- ksadk/conversations/session_title.py +6 -3
- ksadk/deployment/__init__.py +15 -16
- ksadk/deployment/agent_access.py +12 -23
- ksadk/deployment/base.py +51 -38
- ksadk/deployment/managed_runtime.py +33 -0
- ksadk/deployment/manager.py +85 -71
- ksadk/deployment/providers/serverless.py +379 -210
- ksadk/deployment/registry.py +38 -32
- ksadk/deployment/state.py +11 -11
- ksadk/deployment/ui_config.py +1 -1
- ksadk/detection/__init__.py +1 -1
- ksadk/detection/detector.py +146 -83
- ksadk/detection/mcp_detector.py +9 -6
- ksadk/evaluation/__init__.py +84 -0
- ksadk/evaluation/a2a_adapter.py +444 -0
- ksadk/evaluation/adapters.py +54 -0
- ksadk/evaluation/contracts.py +409 -0
- ksadk/evaluation/evalset.py +351 -0
- ksadk/evaluation/evaluators.py +461 -0
- ksadk/evaluation/executor.py +118 -0
- ksadk/evaluation/storage.py +68 -0
- ksadk/evaluation/target.py +73 -0
- ksadk/events/__init__.py +25 -0
- ksadk/events/parser.py +191 -0
- ksadk/events/replay.py +37 -0
- ksadk/events/runtime_event.py +273 -0
- ksadk/events/store.py +317 -0
- ksadk/harness/__init__.py +35 -0
- ksadk/harness/app.py +269 -0
- ksadk/harness/config.py +181 -0
- ksadk/harness/reasoner.py +105 -0
- ksadk/harness/runtime.py +364 -0
- ksadk/harness/sandbox.py +141 -0
- ksadk/harness/tools.py +222 -0
- ksadk/hermes_terminal.py +28 -12
- ksadk/identity/resolver.py +15 -9
- ksadk/ids.py +32 -0
- ksadk/knowledge_base/adk_tool.py +1 -1
- ksadk/knowledge_base/client.py +38 -33
- ksadk/managed_a2a_card.py +160 -0
- ksadk/managed_runtime.py +195 -0
- ksadk/markdown.py +5 -2
- ksadk/mcp_runtime/__init__.py +9 -6
- ksadk/memory/__init__.py +1 -1
- ksadk/memory/adk/__init__.py +2 -0
- ksadk/memory/adk/backends/base_ltm_backend.py +2 -6
- ksadk/memory/adk/backends/http_ltm_backend.py +13 -21
- ksadk/memory/adk/backends/inmemory_ltm_backend.py +7 -13
- ksadk/memory/adk/backends/sdk_ltm_backend.py +36 -36
- ksadk/memory/adk/long_term_memory.py +34 -37
- ksadk/memory/adk/resilient_session_service.py +4 -5
- ksadk/memory/adk/short_term_memory.py +12 -21
- ksadk/memory/adk_tool.py +3 -2
- ksadk/memory/backends/base.py +19 -19
- ksadk/memory/backends/memory.py +24 -25
- ksadk/memory/backends/redis.py +31 -30
- ksadk/memory/langchain_tool.py +2 -1
- ksadk/memory/manager.py +52 -47
- ksadk/memory/service.py +16 -6
- ksadk/memory/tool.py +4 -0
- ksadk/model_policy.py +15 -7
- ksadk/model_proxy/__init__.py +51 -0
- ksadk/model_proxy/bootstrap.py +80 -0
- ksadk/model_proxy/cache.py +165 -0
- ksadk/model_proxy/config.py +66 -0
- ksadk/model_proxy/demo_webui.py +115 -0
- ksadk/model_proxy/detect.py +145 -0
- ksadk/model_proxy/gate.py +68 -0
- ksadk/model_proxy/namespace.py +201 -0
- ksadk/model_proxy/protocol_proxy.py +22 -0
- ksadk/model_proxy/server.py +443 -0
- ksadk/model_proxy/transform.py +735 -0
- ksadk/openclaw_gateway.py +29 -14
- ksadk/runners/adk_runner.py +354 -146
- ksadk/runners/base_runner.py +71 -29
- ksadk/runners/deepagents_runner.py +0 -1
- ksadk/runners/factory.py +18 -5
- ksadk/runners/langchain_runner.py +29 -742
- ksadk/runners/langgraph_runner.py +417 -97
- ksadk/runners/patch_langchain.py +16 -16
- ksadk/runners/remote_runner.py +134 -33
- ksadk/runners/usage_accumulator.py +1 -0
- ksadk/runners/utils/__init__.py +0 -10
- ksadk/runners/utils/loader.py +23 -7
- ksadk/runtime/__init__.py +67 -0
- ksadk/runtime/adapter.py +412 -0
- ksadk/runtime/conversation_execution.py +553 -0
- ksadk/runtime/executor.py +251 -0
- ksadk/runtime/factory.py +156 -0
- ksadk/runtime/framework_adapters.py +118 -0
- ksadk/runtime/launch.py +48 -0
- ksadk/runtime/preprocessing.py +131 -0
- ksadk/runtime/runner_adapter.py +1032 -0
- ksadk/runtime/runner_loading.py +36 -0
- ksadk/runtime_context.py +18 -3
- ksadk/runtime_state.py +0 -1
- ksadk/sandbox/__init__.py +4 -1
- ksadk/sandbox/backends/__init__.py +4 -1
- ksadk/sandbox/backends/e2b.py +13 -5
- ksadk/sandbox/backends/local_process.py +11 -3
- ksadk/sandbox/base.py +10 -15
- ksadk/sandbox/factory.py +14 -4
- ksadk/sandbox/registry.py +57 -6
- ksadk/server/__init__.py +39 -4
- ksadk/server/api_models.py +15 -5
- ksadk/server/app.py +24 -3928
- ksadk/server/composition.py +47 -0
- ksadk/server/factory.py +622 -0
- ksadk/server/routes/__init__.py +1 -0
- ksadk/server/routes/checkpoint_resolution.py +116 -0
- ksadk/server/routes/common.py +682 -0
- ksadk/server/routes/control.py +331 -0
- ksadk/server/routes/dependencies.py +98 -0
- ksadk/server/routes/misc.py +425 -0
- ksadk/server/routes/models.py +451 -0
- ksadk/server/routes/openai_compat.py +229 -0
- ksadk/server/routes/projection.py +848 -0
- ksadk/server/routes/routers.py +52 -0
- ksadk/server/routes/run.py +519 -0
- ksadk/server/routes/sessions.py +644 -0
- ksadk/server/routes/streaming.py +265 -0
- ksadk/server/routes/workspace.py +414 -0
- ksadk/server/static/assets/{ArtifactsPanel-D-SSn2ee.js → ArtifactsPanel-CakCqxEN.js} +1 -1
- ksadk/server/static/assets/CodeBlock-CynLknyO.js +9 -0
- ksadk/server/static/assets/MathMessageMarkdown-3sQdOysS.js +8 -0
- ksadk/server/static/assets/MermaidBlock-NERD_ef7.js +303 -0
- ksadk/server/static/assets/NativeTerminalPanel-CiHWf82q.js +1 -0
- ksadk/server/static/assets/{arc-BA13sHc9.js → arc-DrgjcKhl.js} +1 -1
- ksadk/server/static/assets/architecture-7EHR7CIX-CpZLRCcY.js +1 -0
- ksadk/server/static/assets/{architectureDiagram-3BPJPVTR-DzJzgVoL.js → architectureDiagram-3BPJPVTR-BXoVRbQ6.js} +1 -1
- ksadk/server/static/assets/{blockDiagram-GPEHLZMM-UTdVcZhn.js → blockDiagram-GPEHLZMM-BnaB3Ywv.js} +1 -1
- ksadk/server/static/assets/{c4Diagram-AAUBKEIU-Dix0GD4m.js → c4Diagram-AAUBKEIU-Dw4weZcp.js} +1 -1
- ksadk/server/static/assets/channel-Dt3rQTFI.js +1 -0
- ksadk/server/static/assets/{chunk-2J33WTMH-C2JxuZ42.js → chunk-2J33WTMH-ChjpLK7j.js} +1 -1
- ksadk/server/static/assets/{chunk-4BX2VUAB-Be57QPgD.js → chunk-4BX2VUAB-B9drTgOW.js} +1 -1
- ksadk/server/static/assets/{chunk-55IACEB6-WjSuy4nv.js → chunk-55IACEB6-CK4ROATy.js} +1 -1
- ksadk/server/static/assets/{chunk-727SXJPM-BOovP-b5.js → chunk-727SXJPM-B9KtTTgw.js} +1 -1
- ksadk/server/static/assets/{chunk-AQP2D5EJ-DOmZNmWj.js → chunk-AQP2D5EJ-1O1mki3m.js} +1 -1
- ksadk/server/static/assets/{chunk-FMBD7UC4-DzwlodkU.js → chunk-FMBD7UC4-B_fH2YuH.js} +1 -1
- ksadk/server/static/assets/{chunk-ND2GUHAM-DMqAikEU.js → chunk-ND2GUHAM-D6rFLaVV.js} +1 -1
- ksadk/server/static/assets/chunk-QZHKN3VN-iXEZtKQc.js +1 -0
- ksadk/server/static/assets/classDiagram-4FO5ZUOK-DIveV17Q.js +1 -0
- ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-DIveV17Q.js +1 -0
- ksadk/server/static/assets/{cose-bilkent-S5V4N54A-Zhy2GBnP.js → cose-bilkent-S5V4N54A-ChNs_Mdk.js} +1 -1
- ksadk/server/static/assets/{dagre-BM42HDAG-CbKrtIUz.js → dagre-BM42HDAG-D0QXg_MQ.js} +1 -1
- ksadk/server/static/assets/{diagram-2AECGRRQ-BRApgQRK.js → diagram-2AECGRRQ-DBDDKwBQ.js} +1 -1
- ksadk/server/static/assets/{diagram-5GNKFQAL-D0xbnDiK.js → diagram-5GNKFQAL-BkwDOxmO.js} +1 -1
- ksadk/server/static/assets/{diagram-KO2AKTUF-CVugVI9L.js → diagram-KO2AKTUF-Bv8waYvY.js} +1 -1
- ksadk/server/static/assets/{diagram-LMA3HP47-DozUGgee.js → diagram-LMA3HP47-e1VECDdu.js} +1 -1
- ksadk/server/static/assets/{diagram-OG6HWLK6-ZOYsKlru.js → diagram-OG6HWLK6-Ds9adfRl.js} +1 -1
- ksadk/server/static/assets/{dist-DpKtt4Bo.js → dist-4N2NMVYg.js} +1 -1
- ksadk/server/static/assets/{dist-CkEKJFtk.js → dist-B-jNR6Vn.js} +1 -1
- ksadk/server/static/assets/{dist-D57wnGWd.js → dist-B5J2uhNk.js} +1 -1
- ksadk/server/static/assets/{dist-8_SfK1IP.js → dist-B5oS1zcj.js} +1 -1
- ksadk/server/static/assets/{dist-DMezvBGJ.js → dist-BB3-OwTQ.js} +1 -1
- ksadk/server/static/assets/{dist-2hInLS_J.js → dist-BIlKoW0k.js} +1 -1
- ksadk/server/static/assets/{dist-BrCcQ47T.js → dist-BjOdlDjj.js} +1 -1
- ksadk/server/static/assets/{dist-BmlMPsCc.js → dist-C1sz5Eo3.js} +1 -1
- ksadk/server/static/assets/{dist-B0NP_Z0z.js → dist-CWV4lDr1.js} +1 -1
- ksadk/server/static/assets/{dist-D-xOD048.js → dist-CmZHzlwZ.js} +1 -1
- ksadk/server/static/assets/{dist-DL_NKc_z.js → dist-D6MpCZtz.js} +1 -1
- ksadk/server/static/assets/{dist-DyOkZmze.js → dist-DJN_6Y39.js} +1 -1
- ksadk/server/static/assets/{dist-DmFaq_Iy.js → dist-DQU9EWw-.js} +1 -1
- ksadk/server/static/assets/{dist-gX6GOLKq.js → dist-DWKByxWV.js} +1 -1
- ksadk/server/static/assets/{dist-DyWsb78Q.js → dist-Dli7qW-B.js} +1 -1
- ksadk/server/static/assets/{dist-BIJVDMuB.js → dist-DsHPdk3W.js} +1 -1
- ksadk/server/static/assets/{dist-Dp0k7bWI.js → dist-X4TnqwOK.js} +1 -1
- ksadk/server/static/assets/{dist-8EEyGgDx.js → dist-_pHPTyZ-.js} +1 -1
- ksadk/server/static/assets/{dist-CPBtqRTW.js → dist-fhOuWds5.js} +1 -1
- ksadk/server/static/assets/{dist-D-JMdWPQ.js → dist-gLnrGsoU.js} +1 -1
- ksadk/server/static/assets/{dist-BssVmjIo.js → dist-j6Dxmf_j.js} +1 -1
- ksadk/server/static/assets/{dist-C3HIIaN5.js → dist-o2OVmKvt.js} +1 -1
- ksadk/server/static/assets/{erDiagram-TEJ5UH35-Bk-9bgE5.js → erDiagram-TEJ5UH35-BPItFKH6.js} +1 -1
- ksadk/server/static/assets/eventmodeling-FCH6USID-DYFSxbqr.js +1 -0
- ksadk/server/static/assets/{flowDiagram-I6XJVG4X-Dn9kZVuZ.js → flowDiagram-I6XJVG4X-BbYB9w5Y.js} +1 -1
- ksadk/server/static/assets/{ganttDiagram-6RSMTGT7-BGxXlJqm.js → ganttDiagram-6RSMTGT7-TQXa0KXv.js} +1 -1
- ksadk/server/static/assets/gitGraph-WXDBUCRP-DyNYp6BN.js +1 -0
- ksadk/server/static/assets/{gitGraphDiagram-PVQCEYII-C7Q0X-wi.js → gitGraphDiagram-PVQCEYII-bKblCnpa.js} +1 -1
- ksadk/server/static/assets/index-R52pJJvg.js +177 -0
- ksadk/server/static/assets/index-jJr3_955.css +2 -0
- ksadk/server/static/assets/info-J43DQDTF-WUx7qTde.js +1 -0
- ksadk/server/static/assets/{infoDiagram-5YYISTIA-BO_CSqq5.js → infoDiagram-5YYISTIA-BGVT7J_i.js} +1 -1
- ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-eYLPLd46.js → ishikawaDiagram-YF4QCWOH-K0OOfVna.js} +1 -1
- ksadk/server/static/assets/{journeyDiagram-JHISSGLW-De9geSb0.js → journeyDiagram-JHISSGLW-8LeOJaZp.js} +1 -1
- ksadk/server/static/assets/{kanban-definition-UN3LZRKU-Cs80kQto.js → kanban-definition-UN3LZRKU-C6uCgZrW.js} +1 -1
- ksadk/server/static/assets/{katex-DSrCFD8n.js → katex-CYWseY5E.js} +1 -1
- ksadk/server/static/assets/{linear-CN9sbKTF.js → linear-hdBcYzM8.js} +1 -1
- ksadk/server/static/assets/{mermaid-parser.core-DlgSBU8l.js → mermaid-parser.core-BWrDjSZM.js} +2 -2
- ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-9afz7Oug.js → mindmap-definition-RKZ34NQL-Bjy_2v4_.js} +1 -1
- ksadk/server/static/assets/packet-YPE3B663-BN13y_xl.js +1 -0
- ksadk/server/static/assets/pie-LRSECV5Y-ftSLXhhc.js +1 -0
- ksadk/server/static/assets/{pieDiagram-4H26LBE5-DPv_VstN.js → pieDiagram-4H26LBE5-GmmqNiVH.js} +1 -1
- ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-o77wZ1XK.js → quadrantDiagram-W4KKPZXB-BmkRbwCg.js} +1 -1
- ksadk/server/static/assets/radar-GUYGQ44K-jaICkIeO.js +1 -0
- ksadk/server/static/assets/{requirementDiagram-4Y6WPE33-BYVw81VC.js → requirementDiagram-4Y6WPE33-DSWFqL7c.js} +1 -1
- ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-B7nZFMKT.js → sankeyDiagram-5OEKKPKP-l6iXmU65.js} +1 -1
- ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-BGRRrFw5.js → sequenceDiagram-3UESZ5HK-Cq6UBeQB.js} +1 -1
- ksadk/server/static/assets/{stateDiagram-AJRCARHV-BUfHCoPs.js → stateDiagram-AJRCARHV-qzTQpg3Y.js} +1 -1
- ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-BYCoYGAN.js +1 -0
- ksadk/server/static/assets/{timeline-definition-PNZ67QCA-FbCTGrf9.js → timeline-definition-PNZ67QCA-DEz24vV0.js} +1 -1
- ksadk/server/static/assets/treeView-BLDUP644-Cpib_vlz.js +1 -0
- ksadk/server/static/assets/treemap-LRROVOQU-DQxfmVHK.js +1 -0
- ksadk/server/static/assets/{vennDiagram-CIIHVFJN-DWgwtPsJ.js → vennDiagram-CIIHVFJN-CMCixki2.js} +1 -1
- ksadk/server/static/assets/wardley-L42UT6IY-BQYHnnkU.js +1 -0
- ksadk/server/static/assets/{wardleyDiagram-YWT4CUSO-2x8G-tTM.js → wardleyDiagram-YWT4CUSO-CVzB8F9K.js} +1 -1
- ksadk/server/static/assets/{xychartDiagram-2RQKCTM6-Drma3AYl.js → xychartDiagram-2RQKCTM6-BFBqBLc1.js} +1 -1
- ksadk/server/static/index.html +2 -2
- ksadk/server/terminal_sessions.py +111 -58
- ksadk/sessions/__init__.py +69 -19
- ksadk/sessions/base.py +31 -11
- ksadk/sessions/continuity.py +2 -3
- ksadk/sessions/in_memory.py +46 -2
- ksadk/sessions/local_service.py +148 -17
- ksadk/sessions/postgres_service.py +143 -25
- ksadk/sessions/resilient.py +36 -8
- ksadk/skills/models.py +17 -5
- ksadk/skills/package_store.py +5 -2
- ksadk/skills/runtime/agent.py +20 -5
- ksadk/skills/runtime/artifacts.py +1 -5
- ksadk/skills/runtime/backends/e2b.py +10 -4
- ksadk/skills/runtime/backends/local.py +15 -3
- ksadk/skills/runtime/base.py +1 -2
- ksadk/skills/runtime/executor.py +10 -3
- ksadk/skills/runtime/factory.py +4 -2
- ksadk/skills/runtime/loader.py +1 -2
- ksadk/skills/runtime/registry.py +15 -10
- ksadk/skills/runtime/request.py +3 -1
- ksadk/skills/service_client.py +47 -16
- ksadk/skills/tool_defs.py +15 -10
- ksadk/studio/__init__.py +5 -0
- ksadk/studio/agent_avatar_assets.py +120 -0
- ksadk/studio/agent_lifecycle.py +51 -0
- ksadk/studio/api.py +1046 -0
- ksadk/studio/api_catalog_routes.py +324 -0
- ksadk/studio/api_contracts.py +177 -0
- ksadk/studio/api_helpers.py +132 -0
- ksadk/studio/authoring.py +524 -0
- ksadk/studio/authoring_coordinator.py +285 -0
- ksadk/studio/builder.py +320 -0
- ksadk/studio/capabilities.py +351 -0
- ksadk/studio/cloud.py +278 -0
- ksadk/studio/codex_agent_service.py +583 -0
- ksadk/studio/codex_builder.py +324 -0
- ksadk/studio/codex_manifest.py +278 -0
- ksadk/studio/codex_run.py +352 -0
- ksadk/studio/compiler.py +189 -0
- ksadk/studio/contracts.py +644 -0
- ksadk/studio/errors.py +47 -0
- ksadk/studio/evaluation.py +192 -0
- ksadk/studio/event_store.py +284 -0
- ksadk/studio/framework_run.py +114 -0
- ksadk/studio/identifiers.py +33 -0
- ksadk/studio/mcp_runtime.py +229 -0
- ksadk/studio/model_client.py +543 -0
- ksadk/studio/model_profile_service.py +214 -0
- ksadk/studio/operations.py +243 -0
- ksadk/studio/otel_trace.py +754 -0
- ksadk/studio/pagination.py +182 -0
- ksadk/studio/python_tool_inspection.py +183 -0
- ksadk/studio/repository.py +306 -0
- ksadk/studio/resource_catalog.py +1217 -0
- ksadk/studio/run_service.py +707 -0
- ksadk/studio/runtime_catalog.py +74 -0
- ksadk/studio/runtime_source.py +339 -0
- ksadk/studio/service.py +1141 -0
- ksadk/studio/shared_web.py +994 -0
- ksadk/studio/skill_discovery.py +628 -0
- ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +3 -0
- ksadk/studio/static/assets/index-CaEN0eTR.css +1 -0
- ksadk/studio/static/assets/index-DI2eY_NH.js +252 -0
- ksadk/studio/static/assets/react-vendor-BNmTiJ-I.js +9 -0
- ksadk/studio/static/assets/rolldown-runtime-hePW80VL.js +1 -0
- ksadk/studio/static/index.html +15 -0
- ksadk/studio/templates.py +630 -0
- ksadk/studio/validator.py +246 -0
- ksadk/studio/workspace.py +137 -0
- ksadk/terminal_exec_policy.py +3 -4
- ksadk/tools/gateway.py +101 -15
- ksadk/tools/result_budget.py +12 -4
- ksadk/toolsets/__init__.py +161 -37
- ksadk/toolsets/a2a.py +426 -0
- ksadk/toolsets/platform.py +21 -5
- ksadk/toolsets/sandbox.py +82 -16
- ksadk/toolsets/skills.py +200 -39
- ksadk/toolsets/web.py +123 -26
- ksadk/toolsets/workspace.py +212 -101
- ksadk/tracing/__init__.py +19 -21
- ksadk/tracing/exporters/inmemory_exporter.py +62 -51
- ksadk/tracing/setup.py +135 -506
- ksadk/tracing/span_utils.py +0 -41
- ksadk/tui/loop.py +78 -30
- ksadk/tui/stream_render.py +1 -0
- ksadk/ui_config.py +5 -3
- ksadk/version.py +1 -1
- ksadk_runtime_common/memory_backend/registry.py +56 -56
- ksadk_runtime_common/schemas/runtime_event_v1.json +95 -0
- ksadk_runtime_common/workspace_files/router.py +8 -2
- agentengine_sdk_python-0.7.0.dist-info/RECORD +0 -482
- ksadk/a2a/card_builder.py +0 -64
- ksadk/a2a/client.py +0 -309
- ksadk/runners/utils/langfuse.py +0 -230
- ksadk/server/static/assets/CodeBlock-P16VOLYi.js +0 -9
- ksadk/server/static/assets/MathMessageMarkdown-CdGiQWHR.js +0 -8
- ksadk/server/static/assets/MermaidBlock-IOcal8cm.js +0 -303
- ksadk/server/static/assets/NativeTerminalPanel-DGSDWsei.js +0 -1
- ksadk/server/static/assets/architecture-7EHR7CIX-BvUlsA6l.js +0 -1
- ksadk/server/static/assets/channel-CTuydARX.js +0 -1
- ksadk/server/static/assets/chunk-QZHKN3VN-BnCydivS.js +0 -1
- ksadk/server/static/assets/classDiagram-4FO5ZUOK-BNHg45Be.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-BNHg45Be.js +0 -1
- ksadk/server/static/assets/eventmodeling-FCH6USID-DsAgWnlf.js +0 -1
- ksadk/server/static/assets/gitGraph-WXDBUCRP-BIao9Yjg.js +0 -1
- ksadk/server/static/assets/index-C00Lwg3L.js +0 -165
- ksadk/server/static/assets/index-DAURbCsP.css +0 -1
- ksadk/server/static/assets/info-J43DQDTF-CyipqGxU.js +0 -1
- ksadk/server/static/assets/packet-YPE3B663-CGkyRxlg.js +0 -1
- ksadk/server/static/assets/pie-LRSECV5Y-M0uWAf4n.js +0 -1
- ksadk/server/static/assets/radar-GUYGQ44K-Bdbm24-x.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-8xBN_gLM.js +0 -1
- ksadk/server/static/assets/treeView-BLDUP644-npMo0ak1.js +0 -1
- ksadk/server/static/assets/treemap-LRROVOQU-CHdzrrdo.js +0 -1
- ksadk/server/static/assets/wardley-L42UT6IY-BEQz7wyy.js +0 -1
- ksadk/tracing/exporters/langfuse_exporter.py +0 -445
- {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,630 @@
|
|
|
1
|
+
"""Agent templates and deterministic composition for Studio authoring."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Iterable
|
|
6
|
+
|
|
7
|
+
import yaml # type: ignore[import-untyped]
|
|
8
|
+
|
|
9
|
+
from ksadk.studio.contracts import (
|
|
10
|
+
AgentBindings,
|
|
11
|
+
AgentSpec,
|
|
12
|
+
AgentTemplateComposeRequest,
|
|
13
|
+
AgentTemplateComposition,
|
|
14
|
+
AgentTemplateRecommendation,
|
|
15
|
+
CapabilityBinding,
|
|
16
|
+
ContextSpec,
|
|
17
|
+
ExecutionSpec,
|
|
18
|
+
Instructions,
|
|
19
|
+
ModelParameters,
|
|
20
|
+
ResourceDescriptor,
|
|
21
|
+
)
|
|
22
|
+
from ksadk.studio.errors import StudioError
|
|
23
|
+
from ksadk.studio.resource_catalog import LocalResourceCatalog
|
|
24
|
+
from ksadk.studio.workspace import Workspace
|
|
25
|
+
|
|
26
|
+
RESEARCH_SKILL_NAME = "deep-research-methodology"
|
|
27
|
+
RESEARCH_SKILL_VERSION = "1.0.0"
|
|
28
|
+
|
|
29
|
+
_RESEARCH_SKILL_MANIFEST = {
|
|
30
|
+
"name": RESEARCH_SKILL_NAME,
|
|
31
|
+
"displayName": "深度调研方法",
|
|
32
|
+
"version": RESEARCH_SKILL_VERSION,
|
|
33
|
+
"description": "用于问题拆解、来源检索、交叉验证、证据归档与引用输出的标准方法。",
|
|
34
|
+
"category": "research",
|
|
35
|
+
"instructionsFile": "SKILL.md",
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
_RESEARCH_SKILL_CONTENT = """---
|
|
39
|
+
name: Deep Research Methodology
|
|
40
|
+
description: A rigorous workflow for evidence-backed research and source synthesis.
|
|
41
|
+
version: 1.0.0
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
# Deep Research Methodology
|
|
45
|
+
|
|
46
|
+
Apply this workflow to every research request:
|
|
47
|
+
|
|
48
|
+
1. Clarify the research question, decision context, scope, time range, and exclusions.
|
|
49
|
+
2. Build a question tree before collecting evidence. Separate facts, hypotheses, and unknowns.
|
|
50
|
+
3. Search broadly, then prefer primary and authoritative sources over summaries.
|
|
51
|
+
4. Record every material claim in a source ledger with title, URL, publisher, date, and access time.
|
|
52
|
+
5. Cross-check important claims with at least two independent sources when possible.
|
|
53
|
+
6. Explicitly identify conflicting evidence, stale information, and confidence limits.
|
|
54
|
+
7. Synthesize findings around the user's decision instead of returning a source dump.
|
|
55
|
+
8. Cite sources using stable labels such as [S1], [S2], and include a source table.
|
|
56
|
+
9. Never invent a source, URL, statistic, quotation, or publication date.
|
|
57
|
+
10. When external research tools are unavailable, state the limitation before answering.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
_MCP_KEYWORDS = {
|
|
61
|
+
"browser",
|
|
62
|
+
"crawl",
|
|
63
|
+
"fetch",
|
|
64
|
+
"http",
|
|
65
|
+
"research",
|
|
66
|
+
"search",
|
|
67
|
+
"url",
|
|
68
|
+
"web",
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
_DEPTH_SETTINGS = {
|
|
72
|
+
"focused": {"max_steps": 8, "timeout_seconds": 180, "max_tokens": 3072},
|
|
73
|
+
"standard": {"max_steps": 16, "timeout_seconds": 360, "max_tokens": 4096},
|
|
74
|
+
"deep": {"max_steps": 28, "timeout_seconds": 900, "max_tokens": 6144},
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
_OUTPUT_NAMES_ZH = {
|
|
78
|
+
"brief": "决策简报",
|
|
79
|
+
"report": "结构化研究报告",
|
|
80
|
+
"evidence-table": "证据矩阵与结论",
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
_OUTPUT_NAMES_EN = {
|
|
84
|
+
"brief": "decision brief",
|
|
85
|
+
"report": "structured research report",
|
|
86
|
+
"evidence-table": "evidence matrix and conclusions",
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def list_agent_templates() -> list[dict]:
|
|
91
|
+
return [
|
|
92
|
+
{
|
|
93
|
+
"id": "blank",
|
|
94
|
+
"name": "空白 Agent",
|
|
95
|
+
"description": "输入系统提示词,自主选择模型、Tool、MCP、Skill 与执行策略。",
|
|
96
|
+
"category": "general",
|
|
97
|
+
"recommended": True,
|
|
98
|
+
"steps": ["定义 Agent", "绑定能力", "配置 Prompt", "检查并创建"],
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"id": "research",
|
|
102
|
+
"name": "Research Agent",
|
|
103
|
+
"description": "围绕一个研究目标规划检索、调用 MCP、验证来源并生成带引用的报告。",
|
|
104
|
+
"category": "knowledge-work",
|
|
105
|
+
"recommended": False,
|
|
106
|
+
"steps": ["定义目标", "绑定能力", "生成 Prompt", "检查并创建"],
|
|
107
|
+
},
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def default_agent_spec(
|
|
112
|
+
template: str,
|
|
113
|
+
*,
|
|
114
|
+
description: str = "",
|
|
115
|
+
) -> AgentSpec:
|
|
116
|
+
if template == "blank":
|
|
117
|
+
return AgentSpec(
|
|
118
|
+
description=description,
|
|
119
|
+
instructions=Instructions(system="你是一个可靠的企业智能助手。", task=""),
|
|
120
|
+
)
|
|
121
|
+
if template == "research":
|
|
122
|
+
prompt = _research_instructions(
|
|
123
|
+
AgentTemplateComposeRequest(
|
|
124
|
+
goal="围绕用户输入的问题进行系统性深度调研并输出可核验结论",
|
|
125
|
+
),
|
|
126
|
+
has_research_mcp=False,
|
|
127
|
+
)
|
|
128
|
+
return AgentSpec(
|
|
129
|
+
description=description or "执行深度调研并输出带来源引用的研究报告。",
|
|
130
|
+
instructions=prompt,
|
|
131
|
+
execution=ExecutionSpec(
|
|
132
|
+
strategy="plan-act-observe",
|
|
133
|
+
max_steps=28,
|
|
134
|
+
timeout_seconds=900,
|
|
135
|
+
),
|
|
136
|
+
)
|
|
137
|
+
raise StudioError(
|
|
138
|
+
"AGENT_TEMPLATE_UNSUPPORTED",
|
|
139
|
+
"不支持的 Agent 模板",
|
|
140
|
+
status_code=422,
|
|
141
|
+
field="template",
|
|
142
|
+
details={"template": template},
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def ensure_research_skill(workspace: Workspace) -> None:
|
|
147
|
+
root = workspace.resolve(f"capabilities/skills/{RESEARCH_SKILL_NAME}")
|
|
148
|
+
manifest = root / "skill.yaml"
|
|
149
|
+
instructions = root / "SKILL.md"
|
|
150
|
+
if root.exists():
|
|
151
|
+
if manifest.is_file() and instructions.is_file():
|
|
152
|
+
return
|
|
153
|
+
raise StudioError(
|
|
154
|
+
"RESEARCH_SKILL_CONFLICT",
|
|
155
|
+
"工作区存在不完整的同名 Research Skill",
|
|
156
|
+
status_code=409,
|
|
157
|
+
details={"path": workspace.relative(root)},
|
|
158
|
+
)
|
|
159
|
+
root.mkdir(parents=True)
|
|
160
|
+
workspace.atomic_write_text(
|
|
161
|
+
manifest,
|
|
162
|
+
yaml.safe_dump(
|
|
163
|
+
_RESEARCH_SKILL_MANIFEST,
|
|
164
|
+
allow_unicode=True,
|
|
165
|
+
sort_keys=False,
|
|
166
|
+
),
|
|
167
|
+
)
|
|
168
|
+
workspace.atomic_write_text(instructions, _RESEARCH_SKILL_CONTENT)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def compose_blank_agent(
|
|
172
|
+
workspace: Workspace,
|
|
173
|
+
catalog: LocalResourceCatalog,
|
|
174
|
+
request: AgentTemplateComposeRequest,
|
|
175
|
+
) -> AgentTemplateComposition:
|
|
176
|
+
del workspace
|
|
177
|
+
resources = catalog.list(limit=200)
|
|
178
|
+
models = [item for item in resources if item.kind == "model"]
|
|
179
|
+
tools = [item for item in resources if item.kind == "tool"]
|
|
180
|
+
skills = [item for item in resources if item.kind == "skill"]
|
|
181
|
+
mcps = [item for item in resources if item.kind == "mcp"]
|
|
182
|
+
|
|
183
|
+
model = _select_model(models, request.model_profile_id)
|
|
184
|
+
selected_model_ids = _select_model_ids(
|
|
185
|
+
models, request.model_profile_id, request.model_profile_ids
|
|
186
|
+
)
|
|
187
|
+
selected_tools = _select_resources(
|
|
188
|
+
tools,
|
|
189
|
+
request.tool_resource_ids,
|
|
190
|
+
kind="tool",
|
|
191
|
+
)
|
|
192
|
+
selected_skills = _select_resources(
|
|
193
|
+
skills,
|
|
194
|
+
request.skill_resource_ids,
|
|
195
|
+
kind="skill",
|
|
196
|
+
)
|
|
197
|
+
selected_mcps = _select_resources(
|
|
198
|
+
mcps,
|
|
199
|
+
request.mcp_resource_ids,
|
|
200
|
+
kind="mcp",
|
|
201
|
+
)
|
|
202
|
+
system_prompt = request.prompt.strip() or request.goal.strip()
|
|
203
|
+
task_prompt = request.task_prompt.strip() or (
|
|
204
|
+
"理解用户目标并给出准确、可执行的回答。调用 Tool 前检查输入,"
|
|
205
|
+
"对外部操作遵守权限策略;信息不足时说明假设并请求必要补充。"
|
|
206
|
+
)
|
|
207
|
+
description = request.description.strip() or system_prompt[:160]
|
|
208
|
+
bindings = AgentBindings(
|
|
209
|
+
model_profile_id=model.resource_id,
|
|
210
|
+
model_profile_ids=selected_model_ids,
|
|
211
|
+
model_parameters=ModelParameters(
|
|
212
|
+
temperature=0.2,
|
|
213
|
+
max_tokens=4096,
|
|
214
|
+
),
|
|
215
|
+
policy_template=request.policy_template,
|
|
216
|
+
tools=[CapabilityBinding(resource_id=item.resource_id) for item in selected_tools],
|
|
217
|
+
mcp_servers=[CapabilityBinding(resource_id=item.resource_id) for item in selected_mcps],
|
|
218
|
+
skills=[CapabilityBinding(resource_id=item.resource_id) for item in selected_skills],
|
|
219
|
+
)
|
|
220
|
+
spec = AgentSpec(
|
|
221
|
+
description=description,
|
|
222
|
+
instructions=Instructions(system=system_prompt, task=task_prompt),
|
|
223
|
+
bindings=bindings,
|
|
224
|
+
execution=ExecutionSpec(
|
|
225
|
+
strategy=request.execution_strategy,
|
|
226
|
+
max_steps=request.max_steps,
|
|
227
|
+
timeout_seconds=request.timeout_seconds,
|
|
228
|
+
),
|
|
229
|
+
context=ContextSpec(
|
|
230
|
+
max_input_tokens=65536,
|
|
231
|
+
reserve_output_tokens=8192,
|
|
232
|
+
),
|
|
233
|
+
)
|
|
234
|
+
recommendations = [
|
|
235
|
+
AgentTemplateRecommendation(
|
|
236
|
+
kind="model",
|
|
237
|
+
status="bound",
|
|
238
|
+
title=model.display_name,
|
|
239
|
+
reason="负责理解用户请求、规划执行并生成回答。",
|
|
240
|
+
resource_id=model.resource_id,
|
|
241
|
+
)
|
|
242
|
+
]
|
|
243
|
+
recommendations.extend(
|
|
244
|
+
_bound_recommendations(
|
|
245
|
+
selected_tools,
|
|
246
|
+
reason="按用户选择绑定到 Agent,可用范围由权限策略控制。",
|
|
247
|
+
)
|
|
248
|
+
)
|
|
249
|
+
recommendations.extend(
|
|
250
|
+
_bound_recommendations(
|
|
251
|
+
selected_mcps,
|
|
252
|
+
reason="按用户选择连接外部 MCP Server。",
|
|
253
|
+
)
|
|
254
|
+
)
|
|
255
|
+
recommendations.extend(
|
|
256
|
+
_bound_recommendations(
|
|
257
|
+
selected_skills,
|
|
258
|
+
reason="按用户选择注入版本化 Skill 指令。",
|
|
259
|
+
)
|
|
260
|
+
)
|
|
261
|
+
return AgentTemplateComposition(
|
|
262
|
+
template_id="blank",
|
|
263
|
+
spec=spec,
|
|
264
|
+
recommendations=recommendations,
|
|
265
|
+
warnings=[],
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def compose_research_agent(
|
|
270
|
+
workspace: Workspace,
|
|
271
|
+
catalog: LocalResourceCatalog,
|
|
272
|
+
request: AgentTemplateComposeRequest,
|
|
273
|
+
) -> AgentTemplateComposition:
|
|
274
|
+
ensure_research_skill(workspace)
|
|
275
|
+
resources = catalog.list(limit=200)
|
|
276
|
+
models = [item for item in resources if item.kind == "model"]
|
|
277
|
+
tools = [item for item in resources if item.kind == "tool"]
|
|
278
|
+
skills = [item for item in resources if item.kind == "skill"]
|
|
279
|
+
mcps = [item for item in resources if item.kind == "mcp"]
|
|
280
|
+
|
|
281
|
+
model = _select_model(models, request.model_profile_id)
|
|
282
|
+
selected_model_ids = _select_model_ids(
|
|
283
|
+
models, request.model_profile_id, request.model_profile_ids
|
|
284
|
+
)
|
|
285
|
+
research_skill = next(
|
|
286
|
+
(
|
|
287
|
+
item
|
|
288
|
+
for item in skills
|
|
289
|
+
if item.name == RESEARCH_SKILL_NAME and item.version == RESEARCH_SKILL_VERSION
|
|
290
|
+
),
|
|
291
|
+
None,
|
|
292
|
+
)
|
|
293
|
+
if research_skill is None or research_skill.status != "ready":
|
|
294
|
+
raise StudioError(
|
|
295
|
+
"RESEARCH_SKILL_UNAVAILABLE",
|
|
296
|
+
"Research 模板无法解析内置调研 Skill",
|
|
297
|
+
status_code=409,
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
selected_skills = _select_resources(
|
|
301
|
+
skills,
|
|
302
|
+
[research_skill.resource_id, *request.skill_resource_ids],
|
|
303
|
+
kind="skill",
|
|
304
|
+
)
|
|
305
|
+
compatible_mcps = [item for item in mcps if _is_research_mcp(item)]
|
|
306
|
+
requested_mcp_ids = request.mcp_resource_ids or (
|
|
307
|
+
[item.resource_id for item in compatible_mcps[:1]] if request.auto_bind_mcp else []
|
|
308
|
+
)
|
|
309
|
+
selected_mcps = _select_resources(
|
|
310
|
+
mcps,
|
|
311
|
+
requested_mcp_ids,
|
|
312
|
+
kind="mcp",
|
|
313
|
+
)
|
|
314
|
+
default_tool_ids = [
|
|
315
|
+
item.resource_id
|
|
316
|
+
for item in tools
|
|
317
|
+
if item.name
|
|
318
|
+
in {
|
|
319
|
+
"list_workspace_files",
|
|
320
|
+
"search_workspace_files",
|
|
321
|
+
"read_workspace_file",
|
|
322
|
+
}
|
|
323
|
+
and item.status == "ready"
|
|
324
|
+
]
|
|
325
|
+
requested_tool_ids = request.tool_resource_ids or (
|
|
326
|
+
default_tool_ids if request.auto_bind_tools else []
|
|
327
|
+
)
|
|
328
|
+
selected_tools = _select_resources(
|
|
329
|
+
tools,
|
|
330
|
+
requested_tool_ids,
|
|
331
|
+
kind="tool",
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
settings = _DEPTH_SETTINGS[request.depth]
|
|
335
|
+
bindings = AgentBindings(
|
|
336
|
+
model_profile_id=model.resource_id,
|
|
337
|
+
model_profile_ids=selected_model_ids,
|
|
338
|
+
model_parameters=ModelParameters(
|
|
339
|
+
temperature=0.2,
|
|
340
|
+
max_tokens=settings["max_tokens"],
|
|
341
|
+
),
|
|
342
|
+
policy_template=request.policy_template,
|
|
343
|
+
tools=[CapabilityBinding(resource_id=item.resource_id) for item in selected_tools],
|
|
344
|
+
mcp_servers=[CapabilityBinding(resource_id=item.resource_id) for item in selected_mcps],
|
|
345
|
+
skills=[CapabilityBinding(resource_id=item.resource_id) for item in selected_skills],
|
|
346
|
+
)
|
|
347
|
+
has_research_mcp = bool(selected_mcps)
|
|
348
|
+
instructions = _research_instructions(
|
|
349
|
+
request,
|
|
350
|
+
has_research_mcp=has_research_mcp,
|
|
351
|
+
)
|
|
352
|
+
spec = AgentSpec(
|
|
353
|
+
description=request.description.strip()
|
|
354
|
+
or f"围绕“{_research_goal(request)[:160]}”执行深度调研并形成可核验结论。",
|
|
355
|
+
instructions=instructions,
|
|
356
|
+
bindings=bindings,
|
|
357
|
+
execution=ExecutionSpec(
|
|
358
|
+
strategy="plan-act-observe",
|
|
359
|
+
max_steps=settings["max_steps"],
|
|
360
|
+
timeout_seconds=settings["timeout_seconds"],
|
|
361
|
+
),
|
|
362
|
+
context=ContextSpec(
|
|
363
|
+
max_input_tokens=65536,
|
|
364
|
+
reserve_output_tokens=8192,
|
|
365
|
+
),
|
|
366
|
+
)
|
|
367
|
+
|
|
368
|
+
recommendations = [
|
|
369
|
+
AgentTemplateRecommendation(
|
|
370
|
+
kind="model",
|
|
371
|
+
status="bound",
|
|
372
|
+
title=model.display_name,
|
|
373
|
+
reason="负责问题拆解、证据综合与报告生成。",
|
|
374
|
+
resource_id=model.resource_id,
|
|
375
|
+
),
|
|
376
|
+
AgentTemplateRecommendation(
|
|
377
|
+
kind="skill",
|
|
378
|
+
status="bound",
|
|
379
|
+
title=research_skill.display_name,
|
|
380
|
+
reason="注入问题树、来源分级、交叉验证和引用账本方法。",
|
|
381
|
+
resource_id=research_skill.resource_id,
|
|
382
|
+
),
|
|
383
|
+
]
|
|
384
|
+
recommendations.extend(
|
|
385
|
+
AgentTemplateRecommendation(
|
|
386
|
+
kind="tool",
|
|
387
|
+
status="bound",
|
|
388
|
+
title=item.display_name,
|
|
389
|
+
reason="用于读取和检索当前工作区中的研究资料。",
|
|
390
|
+
resource_id=item.resource_id,
|
|
391
|
+
)
|
|
392
|
+
for item in selected_tools
|
|
393
|
+
)
|
|
394
|
+
warnings: list[str] = []
|
|
395
|
+
if selected_mcps:
|
|
396
|
+
recommendations.extend(
|
|
397
|
+
AgentTemplateRecommendation(
|
|
398
|
+
kind="mcp",
|
|
399
|
+
status="bound",
|
|
400
|
+
title=item.display_name,
|
|
401
|
+
reason="提供外部来源搜索、抓取或浏览能力。",
|
|
402
|
+
resource_id=item.resource_id,
|
|
403
|
+
)
|
|
404
|
+
for item in selected_mcps
|
|
405
|
+
)
|
|
406
|
+
else:
|
|
407
|
+
warning = (
|
|
408
|
+
"当前没有已探测且包含搜索或抓取 Tool 的 MCP。Agent 仍可基于用户输入和"
|
|
409
|
+
"工作区资料调研,但无法主动检索外部来源。"
|
|
410
|
+
)
|
|
411
|
+
warnings.append(warning)
|
|
412
|
+
recommendations.append(
|
|
413
|
+
AgentTemplateRecommendation(
|
|
414
|
+
kind="mcp",
|
|
415
|
+
status="missing",
|
|
416
|
+
title="Web Research MCP",
|
|
417
|
+
reason=warning,
|
|
418
|
+
)
|
|
419
|
+
)
|
|
420
|
+
return AgentTemplateComposition(
|
|
421
|
+
template_id="research",
|
|
422
|
+
spec=spec,
|
|
423
|
+
recommendations=recommendations,
|
|
424
|
+
warnings=warnings,
|
|
425
|
+
)
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
def _select_model(
|
|
429
|
+
models: list[ResourceDescriptor],
|
|
430
|
+
resource_id: str | None,
|
|
431
|
+
) -> ResourceDescriptor:
|
|
432
|
+
if resource_id:
|
|
433
|
+
selected = next(
|
|
434
|
+
(item for item in models if item.resource_id == resource_id),
|
|
435
|
+
None,
|
|
436
|
+
)
|
|
437
|
+
if selected is None:
|
|
438
|
+
raise StudioError(
|
|
439
|
+
"RESOURCE_NOT_FOUND",
|
|
440
|
+
"选择的 Model Profile 不存在",
|
|
441
|
+
status_code=404,
|
|
442
|
+
details={"resourceId": resource_id},
|
|
443
|
+
)
|
|
444
|
+
if selected.status not in {"ready", "missing-secret"}:
|
|
445
|
+
raise StudioError(
|
|
446
|
+
"RESOURCE_NOT_READY",
|
|
447
|
+
"选择的 Model Profile 当前不可用",
|
|
448
|
+
status_code=409,
|
|
449
|
+
details={"resourceId": resource_id, "status": selected.status},
|
|
450
|
+
)
|
|
451
|
+
return selected
|
|
452
|
+
selected = next(
|
|
453
|
+
(item for item in models if item.status in {"ready", "missing-secret"}),
|
|
454
|
+
None,
|
|
455
|
+
)
|
|
456
|
+
if selected is None:
|
|
457
|
+
raise StudioError(
|
|
458
|
+
"AGENT_MODEL_REQUIRED",
|
|
459
|
+
"Agent 需要一个可用的 Model Profile",
|
|
460
|
+
status_code=409,
|
|
461
|
+
)
|
|
462
|
+
return selected
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
def _select_model_ids(
|
|
466
|
+
models: list[ResourceDescriptor],
|
|
467
|
+
primary_id: str | None,
|
|
468
|
+
requested_ids: list[str] | None,
|
|
469
|
+
) -> list[str]:
|
|
470
|
+
"""Resolve the full set of bound model profile ids, deduped, primary first."""
|
|
471
|
+
valid = [item for item in models if item.status in {"ready", "missing-secret"}]
|
|
472
|
+
valid_ids = {item.resource_id for item in valid}
|
|
473
|
+
ordered: list[str] = []
|
|
474
|
+
if primary_id and primary_id in valid_ids:
|
|
475
|
+
ordered.append(primary_id)
|
|
476
|
+
for rid in requested_ids or []:
|
|
477
|
+
if rid in valid_ids and rid not in ordered:
|
|
478
|
+
ordered.append(rid)
|
|
479
|
+
return ordered
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
def _bound_recommendations(
|
|
484
|
+
resources: list[ResourceDescriptor],
|
|
485
|
+
*,
|
|
486
|
+
reason: str,
|
|
487
|
+
) -> list[AgentTemplateRecommendation]:
|
|
488
|
+
return [
|
|
489
|
+
AgentTemplateRecommendation(
|
|
490
|
+
kind=item.kind,
|
|
491
|
+
status="bound",
|
|
492
|
+
title=item.display_name,
|
|
493
|
+
reason=reason,
|
|
494
|
+
resource_id=item.resource_id,
|
|
495
|
+
)
|
|
496
|
+
for item in resources
|
|
497
|
+
]
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
def _select_resources(
|
|
501
|
+
resources: list[ResourceDescriptor],
|
|
502
|
+
resource_ids: Iterable[str],
|
|
503
|
+
*,
|
|
504
|
+
kind: str,
|
|
505
|
+
) -> list[ResourceDescriptor]:
|
|
506
|
+
selected: list[ResourceDescriptor] = []
|
|
507
|
+
seen: set[str] = set()
|
|
508
|
+
by_id = {item.resource_id: item for item in resources}
|
|
509
|
+
for resource_id in resource_ids:
|
|
510
|
+
if resource_id in seen:
|
|
511
|
+
continue
|
|
512
|
+
seen.add(resource_id)
|
|
513
|
+
descriptor = by_id.get(resource_id)
|
|
514
|
+
if descriptor is None:
|
|
515
|
+
raise StudioError(
|
|
516
|
+
"RESOURCE_NOT_FOUND",
|
|
517
|
+
"模板引用的资源不存在",
|
|
518
|
+
status_code=404,
|
|
519
|
+
details={"resourceId": resource_id},
|
|
520
|
+
)
|
|
521
|
+
if descriptor.kind != kind:
|
|
522
|
+
raise StudioError(
|
|
523
|
+
"RESOURCE_KIND_INVALID",
|
|
524
|
+
"模板资源类型不匹配",
|
|
525
|
+
status_code=422,
|
|
526
|
+
details={"resourceId": resource_id, "expectedKind": kind},
|
|
527
|
+
)
|
|
528
|
+
if descriptor.status != "ready":
|
|
529
|
+
raise StudioError(
|
|
530
|
+
"RESOURCE_NOT_READY",
|
|
531
|
+
"模板不能绑定不可用资源",
|
|
532
|
+
status_code=409,
|
|
533
|
+
details={"resourceId": resource_id, "status": descriptor.status},
|
|
534
|
+
)
|
|
535
|
+
selected.append(descriptor)
|
|
536
|
+
return selected
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
def _is_research_mcp(resource: ResourceDescriptor) -> bool:
|
|
540
|
+
if resource.status != "ready":
|
|
541
|
+
return False
|
|
542
|
+
discovered_tools = resource.contract.get("discoveredTools") or []
|
|
543
|
+
if not discovered_tools:
|
|
544
|
+
return False
|
|
545
|
+
searchable = " ".join(
|
|
546
|
+
[
|
|
547
|
+
resource.name,
|
|
548
|
+
resource.display_name,
|
|
549
|
+
resource.description,
|
|
550
|
+
*[str(tool.get("name") or "") for tool in discovered_tools],
|
|
551
|
+
*[str(tool.get("description") or "") for tool in discovered_tools],
|
|
552
|
+
]
|
|
553
|
+
).lower()
|
|
554
|
+
return any(keyword in searchable for keyword in _MCP_KEYWORDS)
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
def _research_instructions(
|
|
558
|
+
request: AgentTemplateComposeRequest,
|
|
559
|
+
*,
|
|
560
|
+
has_research_mcp: bool,
|
|
561
|
+
) -> Instructions:
|
|
562
|
+
research_goal = _research_goal(request)
|
|
563
|
+
if request.language == "en-US":
|
|
564
|
+
output_name = _OUTPUT_NAMES_EN[request.output_format]
|
|
565
|
+
role = f"You are Research Agent, a rigorous research specialist serving {request.audience}."
|
|
566
|
+
system = f"""{role}
|
|
567
|
+
|
|
568
|
+
Research objective:
|
|
569
|
+
{research_goal}
|
|
570
|
+
|
|
571
|
+
Operating principles:
|
|
572
|
+
1. Clarify scope and assumptions before collecting evidence.
|
|
573
|
+
2. Create a question tree and an explicit research plan.
|
|
574
|
+
3. Prefer primary, authoritative, and recent sources.
|
|
575
|
+
4. Cross-check material claims and distinguish facts from inference.
|
|
576
|
+
5. Keep a source ledger and cite every externally verifiable claim.
|
|
577
|
+
6. Never invent a source, URL, quotation, statistic, or publication date.
|
|
578
|
+
7. Surface conflicting evidence, uncertainty, and information gaps.
|
|
579
|
+
8. Produce a {output_name} for the user's decision context.
|
|
580
|
+
"""
|
|
581
|
+
if not has_research_mcp:
|
|
582
|
+
system += (
|
|
583
|
+
"\nExternal research MCP is not currently bound. Use only supplied or "
|
|
584
|
+
"workspace evidence and state this limitation before the answer.\n"
|
|
585
|
+
)
|
|
586
|
+
task = """For each request, execute this contract:
|
|
587
|
+
- Restate the research question, scope, and exclusions.
|
|
588
|
+
- Present the plan before long-running research.
|
|
589
|
+
- Gather and rank evidence by source quality and recency.
|
|
590
|
+
- Synthesize findings into an executive summary, key findings, evidence table,
|
|
591
|
+
disagreements or risks, recommendations, and a source list.
|
|
592
|
+
- Use stable citations such as [S1] and map each citation to a real source.
|
|
593
|
+
- End with confidence and unresolved questions.
|
|
594
|
+
"""
|
|
595
|
+
return Instructions(system=system.strip(), task=task.strip())
|
|
596
|
+
|
|
597
|
+
output_name = _OUTPUT_NAMES_ZH[request.output_format]
|
|
598
|
+
system = f"""你是 Research Agent,一名为{request.audience}服务的严谨深度调研专家。
|
|
599
|
+
|
|
600
|
+
调研目标:
|
|
601
|
+
{research_goal}
|
|
602
|
+
|
|
603
|
+
工作原则:
|
|
604
|
+
1. 收集证据前先明确范围、时间窗口、假设和排除项。
|
|
605
|
+
2. 建立问题树和可执行调研计划,再开始调用工具。
|
|
606
|
+
3. 优先使用一手、权威且时效性匹配的来源。
|
|
607
|
+
4. 对重要结论交叉验证,清楚区分事实、推断与未知。
|
|
608
|
+
5. 维护来源账本,为每个可外部核验的关键主张提供引用。
|
|
609
|
+
6. 不得虚构来源、URL、引文、统计数据或发布日期。
|
|
610
|
+
7. 主动呈现冲突证据、不确定性和信息缺口。
|
|
611
|
+
8. 围绕用户的决策场景输出{output_name}。
|
|
612
|
+
"""
|
|
613
|
+
if not has_research_mcp:
|
|
614
|
+
system += (
|
|
615
|
+
"\n当前未绑定外部调研 MCP。只能使用用户提供内容和工作区资料,"
|
|
616
|
+
"回答前必须明确说明这一限制。\n"
|
|
617
|
+
)
|
|
618
|
+
task = """每次请求都必须执行以下任务契约:
|
|
619
|
+
- 复述研究问题、范围和排除项。
|
|
620
|
+
- 在长时间调研前先展示计划。
|
|
621
|
+
- 按来源质量和时效性收集、筛选和排序证据。
|
|
622
|
+
- 输出执行摘要、关键发现、证据表、冲突或风险、建议和来源列表。
|
|
623
|
+
- 使用 [S1]、[S2] 等稳定引用,并映射到真实来源。
|
|
624
|
+
- 结尾给出置信度和仍待解决的问题。
|
|
625
|
+
"""
|
|
626
|
+
return Instructions(system=system.strip(), task=task.strip())
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
def _research_goal(request: AgentTemplateComposeRequest) -> str:
|
|
630
|
+
return request.goal.strip() or request.prompt.strip()
|