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
ksadk/a2a/executor.py
CHANGED
|
@@ -1,190 +1,411 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""A2ARuntimeExecutor — 把 RuntimeAdapter 桥接进 A2A 请求生命周期。
|
|
2
|
+
|
|
3
|
+
契约 §7.2:A2A ``context_id`` ↔ Runtime ``session_id``;``canceled`` ↔
|
|
4
|
+
``RuntimeAdapter.cancel(invocation_id)``。executor 不在此自造 cancel,而是委托
|
|
5
|
+
:class:`~ksadk.a2a.task_adapter.A2ARuntimeTaskAdapter`(其内部走 RuntimeAdapter.cancel,
|
|
6
|
+
G0.3 已冻结)。
|
|
7
|
+
|
|
8
|
+
wire 对象在 a2a-sdk 1.1.0 是 protobuf(``a2a_pb2``);文本用 ``Part(text=...)``,
|
|
9
|
+
消息用 ``Message(role=Role.ROLE_AGENT, parts=[...])``。
|
|
10
|
+
"""
|
|
2
11
|
|
|
3
12
|
from __future__ import annotations
|
|
4
13
|
|
|
14
|
+
import inspect
|
|
5
15
|
import json
|
|
6
16
|
import logging
|
|
7
|
-
from
|
|
8
|
-
from typing import Any
|
|
17
|
+
from typing import Any, Literal
|
|
9
18
|
|
|
10
19
|
from a2a.server.agent_execution import AgentExecutor, RequestContext
|
|
11
20
|
from a2a.server.events import EventQueue
|
|
12
21
|
from a2a.server.tasks import TaskUpdater
|
|
13
|
-
from a2a.types import Part,
|
|
22
|
+
from a2a.types import Part, Task, TaskState, TaskStatus
|
|
23
|
+
from a2a.utils.errors import TaskNotCancelableError
|
|
24
|
+
|
|
25
|
+
from ksadk.a2a.resume_store import A2AResumePayloadKind
|
|
26
|
+
from ksadk.events import EventType, RuntimeEvent
|
|
27
|
+
from ksadk.runtime import CancelResult, RunHandle
|
|
14
28
|
|
|
15
29
|
logger = logging.getLogger(__name__)
|
|
16
30
|
|
|
31
|
+
#: ADK v2 A2A 集成扩展标记 URI(adk.dev/a2a/a2a-extension)。
|
|
32
|
+
#: 在 Task/status metadata 里塞入该 key 且值非空时,ADK ``RemoteA2aAgent`` 走
|
|
33
|
+
#: ``_handle_a2a_response_v2``——处理每个 ``artifact_update``(含 append=True 增量),
|
|
34
|
+
#: 不再像 v1 那样只放行首块+末块、丢弃中间增量(remote_a2a_agent.py:546/762)。
|
|
35
|
+
#: ksadk 自研 executor 必须带这个标记,否则编排侧 sub-agent 流式被压成"一次性"。
|
|
36
|
+
ADK_V2_INTEGRATION_EXTENSION_URI = "https://google.github.io/adk-docs/a2a/a2a-extension/"
|
|
37
|
+
|
|
38
|
+
#: 扩展标记值(与 google.adk ``A2aAgentExecutor._get_invocation_metadata`` 对齐)。
|
|
39
|
+
ADK_V2_INTEGRATION_METADATA: dict[str, Any] = {
|
|
40
|
+
ADK_V2_INTEGRATION_EXTENSION_URI: {"adk_agent_executor_v2": True}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
_OUTPUT_SNAPSHOT_METADATA = {"ksadk_output_snapshot": True}
|
|
44
|
+
_ArtifactKind = Literal["text", "thinking"]
|
|
17
45
|
|
|
18
|
-
class KsAgentExecutor(AgentExecutor):
|
|
19
|
-
"""Execute a KsADK runner inside the A2A request lifecycle."""
|
|
20
46
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
47
|
+
def _thought_part(text: str) -> Part:
|
|
48
|
+
"""构造可被 ADK RemoteA2aAgent 识别为 thought 的 A2A Part。"""
|
|
49
|
+
return Part(text=text, metadata={"adk_thought": True})
|
|
24
50
|
|
|
25
|
-
|
|
51
|
+
|
|
52
|
+
class _ArtifactStreamEmitter:
|
|
53
|
+
"""按连续类型分段输出 A2A artifact,并正确终止每个 artifact stream。"""
|
|
54
|
+
|
|
55
|
+
def __init__(self, updater: TaskUpdater, task_id: str) -> None:
|
|
56
|
+
self._updater = updater
|
|
57
|
+
self._task_id = task_id
|
|
58
|
+
self._active_kind: _ArtifactKind | None = None
|
|
59
|
+
self._segments: dict[_ArtifactKind, int] = {"text": 0, "thinking": 0}
|
|
60
|
+
self._emitted: dict[tuple[_ArtifactKind, int], int] = {}
|
|
61
|
+
self._pending: tuple[_ArtifactKind, str, bool, int] | None = None
|
|
62
|
+
|
|
63
|
+
async def push(
|
|
26
64
|
self,
|
|
27
|
-
|
|
28
|
-
|
|
65
|
+
kind: _ArtifactKind,
|
|
66
|
+
text: str,
|
|
67
|
+
*,
|
|
68
|
+
replace_snapshot: bool = False,
|
|
69
|
+
) -> None:
|
|
70
|
+
if self._pending is not None:
|
|
71
|
+
switched = self._pending[0] != kind
|
|
72
|
+
await self._emit(self._pending, last_chunk=switched)
|
|
73
|
+
if self._active_kind != kind:
|
|
74
|
+
self._segments[kind] += 1
|
|
75
|
+
self._active_kind = kind
|
|
76
|
+
self._pending = (kind, text, replace_snapshot, self._segments[kind])
|
|
77
|
+
|
|
78
|
+
async def close(self) -> None:
|
|
79
|
+
if self._pending is None:
|
|
80
|
+
return
|
|
81
|
+
await self._emit(self._pending, last_chunk=True)
|
|
82
|
+
self._pending = None
|
|
83
|
+
|
|
84
|
+
async def _emit(
|
|
85
|
+
self,
|
|
86
|
+
pending: tuple[_ArtifactKind, str, bool, int],
|
|
87
|
+
*,
|
|
88
|
+
last_chunk: bool,
|
|
29
89
|
) -> None:
|
|
90
|
+
kind, text, replace_snapshot, segment = pending
|
|
91
|
+
key = (kind, segment)
|
|
92
|
+
self._emitted[key] = self._emitted.get(key, 0) + 1
|
|
93
|
+
is_reasoning = kind == "thinking"
|
|
94
|
+
base_id = (
|
|
95
|
+
f"{self._task_id}-reasoning"
|
|
96
|
+
if is_reasoning
|
|
97
|
+
else f"{self._task_id}-response"
|
|
98
|
+
)
|
|
99
|
+
artifact_id = base_id if segment == 1 else f"{base_id}-{segment}"
|
|
100
|
+
part = (
|
|
101
|
+
_thought_part(text)
|
|
102
|
+
if is_reasoning
|
|
103
|
+
else Part(
|
|
104
|
+
text=text,
|
|
105
|
+
metadata=(
|
|
106
|
+
dict(_OUTPUT_SNAPSHOT_METADATA)
|
|
107
|
+
if replace_snapshot
|
|
108
|
+
else None
|
|
109
|
+
),
|
|
110
|
+
)
|
|
111
|
+
)
|
|
112
|
+
await self._updater.add_artifact(
|
|
113
|
+
parts=[part],
|
|
114
|
+
artifact_id=artifact_id,
|
|
115
|
+
name="reasoning" if is_reasoning else "response",
|
|
116
|
+
append=False if replace_snapshot else self._emitted[key] > 1,
|
|
117
|
+
last_chunk=last_chunk,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
async def _enqueue_initial_task(context: RequestContext, event_queue: EventQueue) -> None:
|
|
122
|
+
"""先入队初始 ``Task`` 对象,再发状态更新(a2a-sdk 1.1.0 生命周期要求:
|
|
123
|
+
TaskStatusUpdateEvent 之前必须已有 Task)。``current_task`` 为续跑任务时直接用,
|
|
124
|
+
否则新建 submitted 任务。Task metadata 带 ADK v2 扩展标记,让 RemoteA2aAgent
|
|
125
|
+
走 v2 handler 保留全部流式增量。
|
|
126
|
+
"""
|
|
127
|
+
task = getattr(context, "current_task", None)
|
|
128
|
+
if task is None:
|
|
129
|
+
task = Task(
|
|
130
|
+
id=context.task_id,
|
|
131
|
+
context_id=context.context_id,
|
|
132
|
+
status=TaskStatus(state=TaskState.TASK_STATE_SUBMITTED),
|
|
133
|
+
metadata=dict(ADK_V2_INTEGRATION_METADATA),
|
|
134
|
+
)
|
|
135
|
+
await event_queue.enqueue_event(task)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class _InputRequired(Exception):
|
|
139
|
+
"""Runtime 请求用户输入的信号(内部用于跳出 execute,task 停 input-required)。"""
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class _RunCanceled(Exception):
|
|
143
|
+
"""Runtime 已取消本次执行,executor 不得再发 completed。"""
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
class A2ARuntimeExecutor(AgentExecutor):
|
|
147
|
+
"""在 A2A 请求生命周期内执行 RuntimeAdapter。
|
|
148
|
+
|
|
149
|
+
start/stream/resume/cancel 全部委托 ``A2ARuntimeTaskAdapter``;协议层不再
|
|
150
|
+
保留 Runner fallback,因此所有入口共享同一 RuntimeEvent 合同。
|
|
151
|
+
"""
|
|
152
|
+
|
|
153
|
+
def __init__(
|
|
154
|
+
self,
|
|
155
|
+
task_adapter: Any,
|
|
156
|
+
include_reasoning: bool = False,
|
|
157
|
+
) -> None:
|
|
158
|
+
if task_adapter is None:
|
|
159
|
+
raise TypeError("task_adapter is required")
|
|
160
|
+
self.task_adapter = task_adapter
|
|
161
|
+
self.include_reasoning = include_reasoning
|
|
162
|
+
|
|
163
|
+
async def execute(self, context: RequestContext, event_queue: EventQueue) -> None:
|
|
164
|
+
current_task = getattr(context, "current_task", None)
|
|
165
|
+
durable_context_id = str(
|
|
166
|
+
getattr(current_task, "context_id", "") or context.context_id or "unknown-context"
|
|
167
|
+
)
|
|
30
168
|
updater = TaskUpdater(
|
|
31
169
|
event_queue=event_queue,
|
|
32
170
|
task_id=context.task_id or "unknown-task",
|
|
33
|
-
context_id=
|
|
171
|
+
context_id=durable_context_id,
|
|
34
172
|
)
|
|
173
|
+
is_resume = (
|
|
174
|
+
current_task is not None
|
|
175
|
+
and getattr(getattr(current_task, "status", None), "state", None)
|
|
176
|
+
== TaskState.TASK_STATE_INPUT_REQUIRED
|
|
177
|
+
)
|
|
178
|
+
interaction_response: Any = None
|
|
179
|
+
# Third-party/local adapters written before durable context mapping do not
|
|
180
|
+
# necessarily provide this optional lifecycle hook.
|
|
181
|
+
prepare_context = getattr(self.task_adapter, "prepare_context", None)
|
|
182
|
+
if callable(prepare_context):
|
|
183
|
+
await prepare_context(context)
|
|
184
|
+
if is_resume:
|
|
185
|
+
interaction_response = self.task_adapter.answer_from_context(context)
|
|
186
|
+
# Invalid resume tokens/decisions are request errors. Validate before emitting
|
|
187
|
+
# working so the durable Task remains input-required and retryable.
|
|
188
|
+
await self.task_adapter.validate_resume_task(
|
|
189
|
+
context.task_id or "",
|
|
190
|
+
context,
|
|
191
|
+
answer=interaction_response,
|
|
192
|
+
)
|
|
35
193
|
|
|
194
|
+
handle: RunHandle | None = None
|
|
36
195
|
try:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
196
|
+
# §7.2:当前任务处于 input-required 时,本条消息是续跑回包(checkpoint/resume)。
|
|
197
|
+
if not is_resume:
|
|
198
|
+
await _enqueue_initial_task(context, event_queue)
|
|
199
|
+
# start_work 不透传 metadata;直接 update_status 以带 ADK v2 扩展标记
|
|
200
|
+
# (RemoteA2aAgent 读 task/status metadata 决定走 v2 全增量 handler)。
|
|
201
|
+
await updater.update_status(
|
|
202
|
+
TaskState.TASK_STATE_WORKING,
|
|
203
|
+
metadata=dict(ADK_V2_INTEGRATION_METADATA),
|
|
204
|
+
)
|
|
205
|
+
if is_resume:
|
|
206
|
+
handle = await self.task_adapter.resume_task(
|
|
207
|
+
context.task_id or "",
|
|
208
|
+
context,
|
|
209
|
+
answer=interaction_response,
|
|
210
|
+
)
|
|
211
|
+
output = await self._run_runtime(context, updater, handle)
|
|
212
|
+
else:
|
|
213
|
+
handle = await self.task_adapter.start_task(
|
|
214
|
+
task_id=str(context.task_id or ""),
|
|
215
|
+
context=context,
|
|
216
|
+
input_data=context.get_user_input(),
|
|
217
|
+
)
|
|
218
|
+
output = await self._run_runtime(context, updater, handle)
|
|
219
|
+
# completed 携带全文消息:非流式消费端与 text.completed 投影(§ event_adapter
|
|
220
|
+
# message_to_event final)依赖它拿最终结果;流式消费端的重复由 adk_runner
|
|
221
|
+
# 在 handoff 分支对"增量累积"去重解决(不在此处删消息)。
|
|
40
222
|
completion_message = (
|
|
41
|
-
updater.new_agent_message(parts=[Part(
|
|
42
|
-
if output
|
|
43
|
-
else None
|
|
223
|
+
updater.new_agent_message(parts=[Part(text=output)]) if output else None
|
|
44
224
|
)
|
|
45
225
|
await updater.complete(message=completion_message)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
226
|
+
await self._forget_task(context, handle)
|
|
227
|
+
except _InputRequired:
|
|
228
|
+
# runner 请求输入:task 已停在 input-required(附 resume token),不 complete。
|
|
229
|
+
logger.info("A2A task %s 进入 input-required", context.task_id)
|
|
230
|
+
except _RunCanceled:
|
|
231
|
+
logger.info("A2A task %s 已由 runtime 取消", context.task_id)
|
|
232
|
+
await self._forget_task(context, handle)
|
|
233
|
+
except Exception as exc: # noqa: BLE001
|
|
234
|
+
logger.error("A2A task execution failed (%s)", type(exc).__name__)
|
|
49
235
|
await updater.failed(
|
|
50
|
-
message=updater.new_agent_message(
|
|
51
|
-
parts=[Part(root=TextPart(text=error_text))]
|
|
52
|
-
)
|
|
236
|
+
message=updater.new_agent_message(parts=[Part(text="A2A task execution failed")])
|
|
53
237
|
)
|
|
238
|
+
await self._forget_task(context, handle)
|
|
54
239
|
|
|
55
|
-
async def cancel(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
240
|
+
async def cancel(self, context: RequestContext, event_queue: EventQueue) -> None:
|
|
241
|
+
# §7.4:cancel 统一由 adapter 提供。有 RuntimeAdapter → 尊重其 CancelResult,
|
|
242
|
+
# 只有底层真取消(CANCELLED)才把协议 Task 置 canceled;其余状态如实抛
|
|
243
|
+
# TaskNotCancelableError 拒绝,不伪造终态。无 adapter 时底层状态未知,
|
|
244
|
+
# 同样拒绝取消。
|
|
245
|
+
current_task = getattr(context, "current_task", None)
|
|
60
246
|
updater = TaskUpdater(
|
|
61
247
|
event_queue=event_queue,
|
|
62
248
|
task_id=context.task_id or "unknown-task",
|
|
63
|
-
context_id=
|
|
249
|
+
context_id=str(
|
|
250
|
+
getattr(current_task, "context_id", "") or context.context_id or "unknown-context"
|
|
251
|
+
),
|
|
64
252
|
)
|
|
65
|
-
await
|
|
66
|
-
|
|
67
|
-
|
|
253
|
+
result = await self.task_adapter.cancel_task(context.task_id or "", context)
|
|
254
|
+
# 只有底层真的接受了取消(已中断活跃 turn,或已登记 pending cancel)才把
|
|
255
|
+
# 协议 Task 置 canceled;其他结果如实拒绝,包括未来新增的 UNSUPPORTED。
|
|
256
|
+
if result not in (
|
|
257
|
+
CancelResult.INTERRUPTED_ACTIVE_TURN,
|
|
258
|
+
CancelResult.PENDING_CANCEL_RECORDED,
|
|
259
|
+
):
|
|
260
|
+
result_value = getattr(result, "value", result)
|
|
261
|
+
raise TaskNotCancelableError(
|
|
262
|
+
message=f"underlying runtime cancel did not apply: {result_value}"
|
|
68
263
|
)
|
|
264
|
+
await updater.cancel(
|
|
265
|
+
message=updater.new_agent_message(parts=[Part(text="Request canceled")])
|
|
69
266
|
)
|
|
267
|
+
clear_resume_state = getattr(self.task_adapter, "clear_resume_state", None)
|
|
268
|
+
if callable(clear_resume_state):
|
|
269
|
+
result = clear_resume_state(context.task_id or "", context)
|
|
270
|
+
if inspect.isawaitable(result):
|
|
271
|
+
await result
|
|
70
272
|
|
|
71
|
-
async def
|
|
273
|
+
async def _run_runtime(
|
|
72
274
|
self,
|
|
73
275
|
context: RequestContext,
|
|
74
276
|
updater: TaskUpdater,
|
|
75
|
-
|
|
76
|
-
) -> str:
|
|
77
|
-
stream = getattr(self.runner, "stream", None)
|
|
78
|
-
if self.prefer_stream and callable(stream):
|
|
79
|
-
return await self._run_streaming(context, updater, stream, runner_input)
|
|
80
|
-
|
|
81
|
-
result = await self.runner.invoke(runner_input)
|
|
82
|
-
text = self._coerce_text(result)
|
|
83
|
-
if text:
|
|
84
|
-
await updater.add_artifact(
|
|
85
|
-
parts=[Part(root=TextPart(text=text))],
|
|
86
|
-
artifact_id=f"{context.task_id}-response",
|
|
87
|
-
name="response",
|
|
88
|
-
last_chunk=True,
|
|
89
|
-
)
|
|
90
|
-
return text
|
|
91
|
-
|
|
92
|
-
async def _run_streaming(
|
|
93
|
-
self,
|
|
94
|
-
context: RequestContext,
|
|
95
|
-
updater: TaskUpdater,
|
|
96
|
-
stream: Any,
|
|
97
|
-
runner_input: dict[str, Any],
|
|
277
|
+
handle: RunHandle,
|
|
98
278
|
) -> str:
|
|
99
279
|
output_text = ""
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
280
|
+
artifacts = _ArtifactStreamEmitter(updater, str(context.task_id))
|
|
281
|
+
reasoning_text = ""
|
|
282
|
+
input_required = False
|
|
283
|
+
input_prompt = "Input required"
|
|
284
|
+
checkpoint_id: str | None = None
|
|
285
|
+
call_id: str | None = None
|
|
286
|
+
payload_kind: A2AResumePayloadKind = "hitl_answer"
|
|
287
|
+
|
|
288
|
+
async for event in self.task_adapter.stream_task(handle):
|
|
289
|
+
if not isinstance(event, RuntimeEvent):
|
|
290
|
+
raise TypeError("RuntimeAdapter.stream must yield RuntimeEvent")
|
|
291
|
+
if event.event_type == EventType.RUN_FAILED:
|
|
292
|
+
raise RuntimeError(self._coerce_text(event.payload.get("error")))
|
|
293
|
+
if event.event_type == EventType.RUN_CANCELED:
|
|
294
|
+
await artifacts.close()
|
|
295
|
+
if not self._cancel_was_accepted(context, handle):
|
|
296
|
+
await updater.cancel(
|
|
297
|
+
message=updater.new_agent_message(parts=[Part(text="Request canceled")])
|
|
298
|
+
)
|
|
299
|
+
raise _RunCanceled()
|
|
300
|
+
if event.event_type == EventType.APPROVAL_REQUESTED:
|
|
301
|
+
input_required = True
|
|
302
|
+
payload_kind = "approval_decision"
|
|
303
|
+
call_id = (
|
|
304
|
+
str(event.payload.get("call_id") or event.payload.get("approval_id") or "")
|
|
305
|
+
or None
|
|
110
306
|
)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
elif final_text.startswith(output_text):
|
|
116
|
-
suffix = final_text[len(output_text) :]
|
|
117
|
-
output_text = final_text
|
|
118
|
-
if suffix:
|
|
119
|
-
emitted_chunks += 1
|
|
120
|
-
await updater.add_artifact(
|
|
121
|
-
parts=[Part(root=TextPart(text=suffix))],
|
|
122
|
-
artifact_id=artifact_id,
|
|
123
|
-
name="response",
|
|
124
|
-
append=bool(emitted_chunks > 1),
|
|
125
|
-
last_chunk=last_chunk,
|
|
126
|
-
)
|
|
127
|
-
continue
|
|
128
|
-
else:
|
|
129
|
-
output_text = final_text
|
|
130
|
-
await updater.add_artifact(
|
|
131
|
-
parts=[Part(root=TextPart(text=final_text))],
|
|
132
|
-
artifact_id=artifact_id,
|
|
133
|
-
name="response",
|
|
134
|
-
append=False,
|
|
135
|
-
last_chunk=last_chunk,
|
|
307
|
+
detail = event.payload.get("detail")
|
|
308
|
+
if isinstance(detail, dict):
|
|
309
|
+
input_prompt = self._coerce_text(
|
|
310
|
+
detail.get("prompt") or detail.get("message") or input_prompt
|
|
136
311
|
)
|
|
137
312
|
continue
|
|
138
|
-
|
|
139
|
-
|
|
313
|
+
if event.event_type == EventType.CHECKPOINT_CREATED:
|
|
314
|
+
checkpoint_id = str(event.payload.get("checkpoint_id") or "") or None
|
|
315
|
+
continue
|
|
316
|
+
if event.event_type == EventType.RUN_INTERRUPTED:
|
|
317
|
+
input_required = True
|
|
318
|
+
input_prompt = self._coerce_text(
|
|
319
|
+
event.payload.get("prompt") or event.payload.get("message") or input_prompt
|
|
320
|
+
)
|
|
321
|
+
continue
|
|
322
|
+
if event.event_type not in {
|
|
323
|
+
EventType.TEXT_DELTA,
|
|
324
|
+
EventType.TEXT_COMPLETED,
|
|
325
|
+
EventType.REASONING_DELTA,
|
|
326
|
+
EventType.REASONING_COMPLETED,
|
|
327
|
+
}:
|
|
328
|
+
continue
|
|
329
|
+
text = self._coerce_text(event.payload.get("text"))
|
|
140
330
|
if not text:
|
|
141
331
|
continue
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
332
|
+
if event.event_type == EventType.REASONING_COMPLETED:
|
|
333
|
+
if not self.include_reasoning:
|
|
334
|
+
continue
|
|
335
|
+
if not reasoning_text:
|
|
336
|
+
delta = text
|
|
337
|
+
reasoning_text = text
|
|
338
|
+
elif text.startswith(reasoning_text):
|
|
339
|
+
delta = text[len(reasoning_text) :]
|
|
340
|
+
reasoning_text = text
|
|
341
|
+
else:
|
|
342
|
+
delta = text
|
|
343
|
+
reasoning_text += text
|
|
344
|
+
if delta:
|
|
345
|
+
await artifacts.push("thinking", delta)
|
|
346
|
+
continue
|
|
347
|
+
if event.event_type == EventType.REASONING_DELTA:
|
|
348
|
+
if not self.include_reasoning:
|
|
349
|
+
continue
|
|
350
|
+
reasoning_text += text
|
|
351
|
+
await artifacts.push("thinking", text)
|
|
352
|
+
continue
|
|
353
|
+
# TEXT_COMPLETED 是累计全文,去重只发新增 suffix;TEXT_DELTA 默认是增量,
|
|
354
|
+
# 但 runner 显式标记 replace 时是权威快照。
|
|
355
|
+
if event.event_type == EventType.TEXT_COMPLETED:
|
|
356
|
+
if not output_text:
|
|
357
|
+
delta = text
|
|
358
|
+
output_text = text
|
|
359
|
+
replace_snapshot = False
|
|
360
|
+
elif text.startswith(output_text):
|
|
361
|
+
delta = text[len(output_text) :]
|
|
362
|
+
output_text = text
|
|
363
|
+
replace_snapshot = False
|
|
364
|
+
else:
|
|
365
|
+
delta = text
|
|
366
|
+
output_text = text
|
|
367
|
+
replace_snapshot = True
|
|
368
|
+
else:
|
|
369
|
+
delta = text
|
|
370
|
+
replace_snapshot = bool(event.payload.get("replace"))
|
|
371
|
+
output_text = text if replace_snapshot else output_text + text
|
|
372
|
+
if not delta:
|
|
373
|
+
continue
|
|
374
|
+
await artifacts.push("text", delta, replace_snapshot=replace_snapshot)
|
|
375
|
+
if self._cancel_was_accepted(context, handle):
|
|
376
|
+
await artifacts.close()
|
|
377
|
+
raise _RunCanceled()
|
|
378
|
+
await artifacts.close()
|
|
379
|
+
if input_required:
|
|
380
|
+
await self.task_adapter.persist_resume_state(
|
|
381
|
+
task_id=str(context.task_id or ""),
|
|
382
|
+
context=context,
|
|
383
|
+
handle=handle,
|
|
384
|
+
checkpoint_id=checkpoint_id,
|
|
385
|
+
call_id=call_id,
|
|
386
|
+
payload_kind=payload_kind,
|
|
150
387
|
)
|
|
151
|
-
|
|
388
|
+
await updater.update_status(
|
|
389
|
+
TaskState.TASK_STATE_INPUT_REQUIRED,
|
|
390
|
+
message=updater.new_agent_message(parts=[Part(text=input_prompt)]),
|
|
391
|
+
metadata=dict(ADK_V2_INTEGRATION_METADATA),
|
|
392
|
+
)
|
|
393
|
+
raise _InputRequired()
|
|
152
394
|
return output_text
|
|
153
395
|
|
|
154
|
-
|
|
155
|
-
self,
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
except StopAsyncIteration:
|
|
161
|
-
return
|
|
396
|
+
def _cancel_was_accepted(self, context: RequestContext, handle: RunHandle) -> bool:
|
|
397
|
+
was_cancel_accepted = getattr(self.task_adapter, "was_cancel_accepted", None)
|
|
398
|
+
return bool(
|
|
399
|
+
callable(was_cancel_accepted)
|
|
400
|
+
and was_cancel_accepted(str(context.task_id or ""), context, handle)
|
|
401
|
+
)
|
|
162
402
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
yield previous, False
|
|
170
|
-
previous = current
|
|
171
|
-
|
|
172
|
-
@staticmethod
|
|
173
|
-
def _build_runner_input(context: RequestContext) -> dict[str, Any]:
|
|
174
|
-
metadata = dict(context.metadata)
|
|
175
|
-
state = metadata.get("state", {})
|
|
176
|
-
if not isinstance(state, dict):
|
|
177
|
-
state = {}
|
|
178
|
-
|
|
179
|
-
return {
|
|
180
|
-
"input": context.get_user_input(),
|
|
181
|
-
"task_id": context.task_id,
|
|
182
|
-
"context_id": context.context_id,
|
|
183
|
-
"session_id": context.context_id,
|
|
184
|
-
"state": dict(state),
|
|
185
|
-
"branch": metadata.get("branch", ""),
|
|
186
|
-
"metadata": metadata,
|
|
187
|
-
}
|
|
403
|
+
async def _forget_task(self, context: RequestContext, handle: RunHandle | None) -> None:
|
|
404
|
+
forget_task = getattr(self.task_adapter, "forget_task", None)
|
|
405
|
+
if handle is not None and callable(forget_task):
|
|
406
|
+
result = forget_task(str(context.task_id or ""), context, handle)
|
|
407
|
+
if inspect.isawaitable(result):
|
|
408
|
+
await result
|
|
188
409
|
|
|
189
410
|
@classmethod
|
|
190
411
|
def _coerce_text(cls, payload: Any) -> str:
|
|
@@ -199,3 +420,6 @@ class KsAgentExecutor(AgentExecutor):
|
|
|
199
420
|
return cls._coerce_text(value)
|
|
200
421
|
return json.dumps(payload, ensure_ascii=False, default=str)
|
|
201
422
|
return str(payload)
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
__all__ = ["A2ARuntimeExecutor"]
|