agentengine-sdk-python 0.8.1__py3-none-any.whl → 0.8.3__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.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/METADATA +25 -12
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/RECORD +421 -232
- ksadk/_build_provenance.json +1 -0
- ksadk/a2a/_space_client_events.py +381 -0
- ksadk/a2a/event_adapter.py +156 -64
- ksadk/a2a/executor.py +179 -63
- ksadk/a2a/space_client.py +6 -333
- ksadk/a2ui/core.py +222 -53
- ksadk/agui/_agent_helpers.py +247 -0
- ksadk/agui/a2ui_projection.py +12 -5
- ksadk/agui/agent.py +443 -259
- ksadk/api/client.py +528 -27
- ksadk/builders/code_builder.py +284 -8
- ksadk/builders/container_builder.py +8 -1
- ksadk/builders/managed_runtime_builder.py +42 -35
- ksadk/cli/__init__.py +23 -0
- ksadk/cli/cmd_dashboard.py +15 -1
- ksadk/cli/cmd_deploy.py +10 -2
- ksadk/cli/cmd_eval.py +66 -9
- ksadk/cli/cmd_evalset.py +284 -0
- ksadk/cli/cmd_files.py +5 -1
- ksadk/cli/cmd_hermes.py +1 -126
- ksadk/cli/cmd_invoke.py +28 -38
- ksadk/cli/cmd_managed_runtime.py +95 -0
- ksadk/cli/cmd_observe.py +85 -0
- ksadk/cli/cmd_openclaw.py +1 -435
- ksadk/cli/cmd_plugin.py +657 -0
- ksadk/cli/cmd_replay.py +28 -4
- ksadk/cli/cmd_studio.py +99 -8
- ksadk/cli/cmd_web.py +10 -2
- ksadk/cli/hermes_env.py +151 -0
- ksadk/cli/invoke_payload.py +49 -0
- ksadk/cli/openclaw_env.py +458 -0
- ksadk/codex/client.py +180 -30
- ksadk/codex/runtime.py +475 -331
- ksadk/configs/env_registry.py +94 -12
- ksadk/configs/env_registry_pcm.py +181 -0
- ksadk/configs/env_var_spec.py +18 -0
- ksadk/configs/global_config.py +5 -0
- ksadk/configs/settings.py +9 -0
- ksadk/context_engine/__init__.py +98 -0
- ksadk/context_engine/assembler.py +176 -0
- ksadk/context_engine/baseline.py +419 -0
- ksadk/context_engine/cache_observability.py +228 -0
- ksadk/context_engine/capabilities.py +443 -0
- ksadk/context_engine/contributors.py +409 -0
- ksadk/context_engine/hosted_pipeline.py +417 -0
- ksadk/context_engine/models.py +117 -0
- ksadk/context_engine/planner.py +698 -0
- ksadk/context_engine/policies.py +319 -0
- ksadk/context_engine/projection.py +31 -0
- ksadk/context_engine/shadow_plan.py +266 -0
- ksadk/context_engine/tokenizer.py +164 -0
- ksadk/conversations/__init__.py +19 -0
- ksadk/conversations/context.py +230 -30
- ksadk/conversations/contracts.py +266 -0
- ksadk/conversations/message_projection.py +308 -26
- ksadk/conversations/model_context.py +49 -3
- ksadk/conversations/projector.py +616 -0
- ksadk/conversations/reducer.py +98 -0
- ksadk/conversations/runtime_compaction.py +207 -5
- ksadk/conversations/runtime_input.py +184 -2
- ksadk/conversations/runtime_invocation.py +81 -3
- ksadk/conversations/runtime_observability.py +141 -0
- ksadk/conversations/runtime_payloads.py +42 -0
- ksadk/conversations/runtime_preparation.py +272 -2
- ksadk/conversations/runtime_resume.py +20 -1
- ksadk/conversations/runtime_stream_events.py +94 -9
- ksadk/conversations/semantic_summary.py +311 -1
- ksadk/conversations/session_lock.py +51 -0
- ksadk/deployment/env_forward.py +72 -0
- ksadk/deployment/managed_runtime.py +5 -0
- ksadk/deployment/providers/serverless.py +143 -69
- ksadk/evaluation/__init__.py +32 -0
- ksadk/evaluation/a2a_adapter.py +9 -1
- ksadk/evaluation/adapters.py +18 -5
- ksadk/evaluation/agent_eval_client.py +395 -0
- ksadk/evaluation/cloud_binding.py +80 -0
- ksadk/evaluation/cloud_converter.py +194 -0
- ksadk/evaluation/cloud_service.py +199 -0
- ksadk/evaluation/contracts.py +73 -4
- ksadk/evaluation/evaluators.py +183 -17
- ksadk/evaluation/evidence.py +258 -0
- ksadk/evaluation/executor.py +31 -6
- ksadk/evaluation/local_adapter.py +550 -0
- ksadk/evaluation/service_env.py +27 -0
- ksadk/evaluation/studio_build_adapter.py +253 -0
- ksadk/evaluation/target.py +15 -6
- ksadk/events/__init__.py +13 -13
- ksadk/events/_v1_compat/__init__.py +1 -0
- ksadk/events/_v1_compat/models.py +299 -0
- ksadk/events/_v1_compat/parser.py +247 -0
- ksadk/events/_v1_compat/projection.py +755 -0
- ksadk/events/adapters/__init__.py +34 -0
- ksadk/events/adapters/_a2a_snapshot.py +622 -0
- ksadk/events/adapters/_a2a_support.py +275 -0
- ksadk/events/adapters/_codex_interactions.py +375 -0
- ksadk/events/adapters/_codex_items.py +801 -0
- ksadk/events/adapters/_codex_validators.py +311 -0
- ksadk/events/adapters/_langgraph_support.py +785 -0
- ksadk/events/adapters/a2a.py +841 -0
- ksadk/events/adapters/adk.py +503 -0
- ksadk/events/adapters/codex.py +907 -0
- ksadk/events/adapters/langgraph.py +745 -0
- ksadk/events/canonical.py +440 -0
- ksadk/events/canonical_replay.py +497 -0
- ksadk/events/canonical_store.py +468 -0
- ksadk/events/cold_recovery.py +257 -0
- ksadk/events/content.py +89 -0
- ksadk/events/identity.py +86 -0
- ksadk/events/pipeline.py +455 -0
- ksadk/events/projections.py +66 -0
- ksadk/events/reducer.py +661 -0
- ksadk/events/replay.py +3 -36
- ksadk/events/runtime_event.py +20 -265
- ksadk/events/session_event.py +324 -0
- ksadk/events/store.py +3 -316
- ksadk/events/v1_compat.py +41 -0
- ksadk/harness/__init__.py +45 -35
- ksadk/harness/runtime.py +220 -58
- ksadk/identity/resolver.py +4 -3
- ksadk/interaction/__init__.py +28 -0
- ksadk/interaction/contracts.py +136 -0
- ksadk/interaction/ledger.py +189 -0
- ksadk/interaction/provider.py +122 -0
- ksadk/interaction/providers/__init__.py +52 -0
- ksadk/interaction/providers/adk.py +40 -0
- ksadk/interaction/providers/codex.py +94 -0
- ksadk/interaction/providers/langgraph.py +58 -0
- ksadk/kernel/__init__.py +117 -0
- ksadk/kernel/authorization.py +258 -0
- ksadk/kernel/bootstrap.py +1074 -0
- ksadk/kernel/contract_fingerprints.py +62 -0
- ksadk/kernel/contracts.py +370 -0
- ksadk/kernel/control.py +220 -0
- ksadk/kernel/errors.py +79 -0
- ksadk/kernel/ingress.py +1123 -0
- ksadk/kernel/mapping.py +111 -0
- ksadk/kernel/memory_store.py +1134 -0
- ksadk/kernel/postgres_store.py +1757 -0
- ksadk/kernel/recovery.py +452 -0
- ksadk/kernel/runtime_identity.py +103 -0
- ksadk/kernel/sql/001_agent_kernel.sql +120 -0
- ksadk/kernel/sqlite_store.py +1411 -0
- ksadk/kernel/state.py +145 -0
- ksadk/kernel/store.py +232 -0
- ksadk/kernel/worker.py +964 -0
- ksadk/knowledge_base/client.py +7 -0
- ksadk/knowledge_base/service.py +32 -5
- ksadk/memory/__init__.py +61 -0
- ksadk/memory/adk/backends/base_ltm_backend.py +96 -1
- ksadk/memory/adk/backends/http_ltm_backend.py +14 -5
- ksadk/memory/adk/backends/inmemory_ltm_backend.py +136 -3
- ksadk/memory/adk/backends/sdk_ltm_backend.py +384 -2
- ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
- ksadk/memory/coordinator.py +461 -0
- ksadk/memory/events.py +202 -0
- ksadk/memory/extraction.py +228 -0
- ksadk/memory/ltm_backend_factory.py +16 -3
- ksadk/memory/models.py +316 -0
- ksadk/memory/policy.py +215 -0
- ksadk/memory/provider.py +47 -0
- ksadk/memory/provider_adapter.py +159 -0
- ksadk/memory/provider_resolver.py +71 -0
- ksadk/memory/providers/__init__.py +5 -0
- ksadk/memory/providers/local_sqlite.py +497 -0
- ksadk/memory/resolved_policy.py +145 -0
- ksadk/memory/service.py +188 -6
- ksadk/model_proxy/bootstrap.py +16 -9
- ksadk/model_proxy/detect.py +202 -9
- ksadk/model_proxy/namespace.py +39 -15
- ksadk/model_proxy/server.py +24 -5
- ksadk/model_proxy/transform.py +60 -2
- ksadk/observability/__init__.py +25 -0
- ksadk/observability/session_log.py +420 -0
- ksadk/observability/trajectory.py +105 -0
- ksadk/plugins/__init__.py +167 -0
- ksadk/plugins/bridges/__init__.py +45 -0
- ksadk/plugins/bridges/codex.py +552 -0
- ksadk/plugins/bridges/dsh.py +1116 -0
- ksadk/plugins/builtins.py +747 -0
- ksadk/plugins/bundle.py +246 -0
- ksadk/plugins/bundle_security.py +167 -0
- ksadk/plugins/composition.py +529 -0
- ksadk/plugins/context_contributor.py +437 -0
- ksadk/plugins/contracts.py +451 -0
- ksadk/plugins/dsh_toolchain.py +935 -0
- ksadk/plugins/ecosystem_bridge.py +1105 -0
- ksadk/plugins/ecosystem_probe.py +191 -0
- ksadk/plugins/host.py +724 -0
- ksadk/plugins/providers/__init__.py +85 -0
- ksadk/plugins/providers/bundles/ksadk-codex/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +18 -0
- ksadk/plugins/providers/bundles/ksadk-codex/package.json +19 -0
- ksadk/plugins/providers/bundles/ksadk-harness/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +19 -0
- ksadk/plugins/providers/bundles/ksadk-harness/package.json +19 -0
- ksadk/plugins/providers/codex.py +722 -0
- ksadk/plugins/providers/codex_dsh.py +83 -0
- ksadk/plugins/providers/dsh.py +951 -0
- ksadk/plugins/providers/dsh_descriptor_host.py +226 -0
- ksadk/plugins/providers/harness.py +627 -0
- ksadk/plugins/providers/harness_dsh.py +91 -0
- ksadk/plugins/providers/legacy.py +215 -0
- ksadk/plugins/providers/legacy_catalog.py +100 -0
- ksadk/plugins/providers/shipped_dsh.py +370 -0
- ksadk/plugins/resolver.py +331 -0
- ksadk/plugins/subagent_providers/__init__.py +12 -0
- ksadk/plugins/subagent_providers/codex.py +443 -0
- ksadk/plugins/subagents.py +333 -0
- ksadk/prompts/__init__.py +71 -0
- ksadk/prompts/compiler.py +215 -0
- ksadk/prompts/models.py +82 -0
- ksadk/prompts/projection.py +89 -0
- ksadk/prompts/resolved.py +137 -0
- ksadk/prompts/sources.py +233 -0
- ksadk/runners/_langgraph_runner_streams.py +822 -0
- ksadk/runners/adk_runner.py +5 -5
- ksadk/runners/base_runner.py +16 -0
- ksadk/runners/factory.py +1 -2
- ksadk/runners/langgraph_runner.py +198 -437
- ksadk/runtime/_runner_adapter/__init__.py +1 -0
- ksadk/runtime/_runner_adapter/stream_mapping.py +797 -0
- ksadk/runtime/adapter.py +119 -2
- ksadk/runtime/conversation_execution.py +316 -182
- ksadk/runtime/executor.py +144 -3
- ksadk/runtime/factory.py +268 -8
- ksadk/runtime/framework_adapters.py +18 -0
- ksadk/runtime/hosted_finalizer.py +268 -0
- ksadk/runtime/launch.py +14 -1
- ksadk/runtime/preprocessing.py +25 -3
- ksadk/runtime/runner_adapter.py +293 -508
- ksadk/runtime/usage.py +33 -0
- ksadk/sandbox/__init__.py +2 -1
- ksadk/sandbox/backends/e2b.py +35 -2
- ksadk/sandbox/factory.py +72 -0
- ksadk/scheduler/__init__.py +18 -0
- ksadk/scheduler/calendar.py +102 -0
- ksadk/scheduler/contracts.py +254 -0
- ksadk/scheduler/dispatcher.py +129 -0
- ksadk/scheduler/engine.py +416 -0
- ksadk/scheduler/sqlite_store.py +563 -0
- ksadk/server/composition.py +8 -0
- ksadk/server/factory.py +69 -6
- ksadk/server/routes/kernel_ingress.py +258 -0
- ksadk/server/routes/openai_compat.py +88 -8
- ksadk/server/routes/projection.py +35 -20
- ksadk/server/routes/run.py +94 -0
- ksadk/server/routes/sessions.py +2 -0
- ksadk/server/routes/streaming.py +5 -2
- ksadk/server/static/assets/{ArtifactsPanel-CakCqxEN.js → ArtifactsPanel-10GPXIJ6.js} +1 -1
- ksadk/server/static/assets/{CodeBlock-CynLknyO.js → CodeBlock-BXk1l-G1.js} +4 -4
- ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
- ksadk/server/static/assets/{MathMessageMarkdown-3sQdOysS.js → MathMessageMarkdown-D9uB55Oh.js} +4 -4
- ksadk/server/static/assets/MermaidBlock--OEYoXIJ.js +312 -0
- ksadk/server/static/assets/NativeTerminalPanel-DrEe1syq.js +1 -0
- ksadk/server/static/assets/abnfDiagram-VCTEODGH-eeTFJLvo.js +1 -0
- ksadk/server/static/assets/arc-S3ZNbIAd.js +1 -0
- ksadk/server/static/assets/architecture-7GRP2DOG-Dk9nRQ6-.js +1 -0
- ksadk/server/static/assets/architectureDiagram-5GKGNRK7-CRjgEJDX.js +36 -0
- ksadk/server/static/assets/blockDiagram-NRAW4CY4-C7bsBoNH.js +129 -0
- ksadk/server/static/assets/c4Diagram-UCG6FXSJ-BX3c33Ob.js +38 -0
- ksadk/server/static/assets/channel-s354Yo6o.js +1 -0
- ksadk/server/static/assets/chunk-2Q5K7J3B-CDpPpKR5.js +1 -0
- ksadk/server/static/assets/{chunk-FMBD7UC4-B_fH2YuH.js → chunk-5VM5RSS4-bZ7ws-8m.js} +1 -1
- ksadk/server/static/assets/{chunk-ND2GUHAM-D6rFLaVV.js → chunk-F27PBJKO-D2r0pvhY.js} +1 -1
- ksadk/server/static/assets/chunk-G27WJ6UU-CZwF3oUP.js +231 -0
- ksadk/server/static/assets/{chunk-4BX2VUAB-B9drTgOW.js → chunk-JWPE2WC7-DigFYCML.js} +1 -1
- ksadk/server/static/assets/chunk-LCL6LL3I-CnorGV5q.js +206 -0
- ksadk/server/static/assets/chunk-POPQ4Y6H-CexntQA-.js +1 -0
- ksadk/server/static/assets/chunk-RHFEMEQ7-CHTC7UxA.js +168 -0
- ksadk/server/static/assets/chunk-SVP7TREG-BC1EWt_-.js +88 -0
- ksadk/server/static/assets/chunk-XXDRQBXY-BTG24xN0.js +1 -0
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-Dd0nucl9.js +1 -0
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Dd0nucl9.js +1 -0
- ksadk/server/static/assets/{cose-bilkent-S5V4N54A-ChNs_Mdk.js → cose-bilkent-JH36ORCC-CkonRdAS.js} +1 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-BBlT4uMf.js +1 -0
- ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-DEOCBe15.js +62 -0
- ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
- ksadk/server/static/assets/dagre-3AP2YEHR-DBThPuLa.js +4 -0
- ksadk/server/static/assets/dagre-ClTPrTht.js +1 -0
- ksadk/server/static/assets/diagram-S7CK7UJ4-DsZHrnpJ.js +30 -0
- ksadk/server/static/assets/diagram-UQ7AKVKN-BJR4nhVr.js +41 -0
- ksadk/server/static/assets/diagram-VSXAHHWV-xzcERX0a.js +3 -0
- ksadk/server/static/assets/diagram-VX7I27RA-tn2xM1xu.js +24 -0
- ksadk/server/static/assets/diagram-Z3DM3KII-BZPGBkw5.js +24 -0
- ksadk/server/static/assets/{dist-gLnrGsoU.js → dist-4zN1_tq5.js} +1 -1
- ksadk/server/static/assets/{dist-C1sz5Eo3.js → dist-8VWI-2bZ.js} +1 -1
- ksadk/server/static/assets/{dist-BjOdlDjj.js → dist-B-46q3Hk.js} +1 -1
- ksadk/server/static/assets/{dist-o2OVmKvt.js → dist-B0gdk4rl.js} +1 -1
- ksadk/server/static/assets/{dist-4N2NMVYg.js → dist-B1oWRmrH.js} +1 -1
- ksadk/server/static/assets/{dist-CmZHzlwZ.js → dist-BI1qQH4n.js} +1 -1
- ksadk/server/static/assets/{dist-X4TnqwOK.js → dist-BJLUwH6W.js} +1 -1
- ksadk/server/static/assets/{dist-B5oS1zcj.js → dist-Bbwqa8TG.js} +1 -1
- ksadk/server/static/assets/{dist-j6Dxmf_j.js → dist-Btyo4vX4.js} +1 -1
- ksadk/server/static/assets/{dist-DQU9EWw-.js → dist-C71CsujO.js} +1 -1
- ksadk/server/static/assets/{dist-BIlKoW0k.js → dist-CXpH_Rdd.js} +1 -1
- ksadk/server/static/assets/{dist-DJN_6Y39.js → dist-Cq4OL6nO.js} +1 -1
- ksadk/server/static/assets/{dist-Dli7qW-B.js → dist-D1V3f1B4.js} +1 -1
- ksadk/server/static/assets/{dist-fhOuWds5.js → dist-DJmCPRVB.js} +1 -1
- ksadk/server/static/assets/{dist-CWV4lDr1.js → dist-DQAB0qn_.js} +2 -2
- ksadk/server/static/assets/{dist-D6MpCZtz.js → dist-DUwKa_l6.js} +1 -1
- ksadk/server/static/assets/dist-DdRBIceA.js +1 -0
- ksadk/server/static/assets/{dist-DWKByxWV.js → dist-DfGFrb0v.js} +1 -1
- ksadk/server/static/assets/{dist-DsHPdk3W.js → dist-DjhwGUgZ.js} +1 -1
- ksadk/server/static/assets/{dist-B-jNR6Vn.js → dist-DyqV4fL4.js} +1 -1
- ksadk/server/static/assets/{dist-BB3-OwTQ.js → dist-M67Hwu0n.js} +1 -1
- ksadk/server/static/assets/{dist-_pHPTyZ-.js → dist-u8tVH5Ak.js} +1 -1
- ksadk/server/static/assets/ebnfDiagram-PWID7BFC-DVfMsLge.js +1 -0
- ksadk/server/static/assets/erDiagram-SSCWMZ5O-CWEZSYaw.js +99 -0
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-Dr5okd8V.js +1 -0
- ksadk/server/static/assets/flowDiagram-A5DVABFB-VEO-cVcO.js +1 -0
- ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-TWIxoyYL.js +292 -0
- ksadk/server/static/assets/gitGraph-4MIJSDKK-CKiKY9Cf.js +1 -0
- ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-DDh2hd2S.js +106 -0
- ksadk/server/static/assets/index-B2k_urY8.js +241 -0
- ksadk/server/static/assets/index-ILPt6IWF.css +2 -0
- ksadk/server/static/assets/info-A6RAGUB7-ubA4Nm_p.js +1 -0
- ksadk/server/static/assets/infoDiagram-RXCK75RN-CgoyWiDR.js +2 -0
- ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-K0OOfVna.js → ishikawaDiagram-5VMMS53U-CyRIu_om.js} +6 -6
- ksadk/server/static/assets/{journeyDiagram-JHISSGLW-8LeOJaZp.js → journeyDiagram-EYS64GPL-DN5JXHzN.js} +6 -6
- ksadk/server/static/assets/{kanban-definition-UN3LZRKU-C6uCgZrW.js → kanban-definition-3QL26DDD-CNP3ui66.js} +10 -10
- ksadk/server/static/assets/katex-DWEzQy1d.js +257 -0
- ksadk/server/static/assets/{linear-hdBcYzM8.js → linear-C-qHp7d2.js} +1 -1
- ksadk/server/static/assets/mermaid-parser.core-Cl-K943T.js +166 -0
- ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-Bjy_2v4_.js → mindmap-definition-FBJOCRG2-D5DB5mYm.js} +29 -29
- ksadk/server/static/assets/packet-AYTQ26CC-C7R3NUlK.js +1 -0
- ksadk/server/static/assets/pegDiagram-XKGWAZYB-BQVc9ia_.js +1 -0
- ksadk/server/static/assets/pie-WAS4IAKB-BIT6qjr3.js +1 -0
- ksadk/server/static/assets/pieDiagram-E7YTZNPT-B6UCAvtY.js +39 -0
- ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-BmkRbwCg.js → quadrantDiagram-AXDQQJYC-mIr2d3eb.js} +6 -6
- ksadk/server/static/assets/radar-RG4KPBEZ-l5noef9X.js +1 -0
- ksadk/server/static/assets/railroad-74A4TZTK-Baea6ZvM.js +1 -0
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-OKn8zZnU.js +1 -0
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-DdKAKC4l.js +1 -0
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-Bds8udlG.js +1 -0
- ksadk/server/static/assets/railroadDiagram-O6MQD6OU-Dt3FFDmK.js +1 -0
- ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-Cz_vQtgF.js +84 -0
- ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-l6iXmU65.js → sankeyDiagram-P5KCCOFB-wlO1TsH5.js} +7 -7
- ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-Cq6UBeQB.js → sequenceDiagram-WJ2MYXX4-CHRbElYq.js} +10 -10
- ksadk/server/static/assets/sizeCapture-X5ZJPWSS-DXX54iyO.js +1 -0
- ksadk/server/static/assets/stateDiagram-HBIQ2CUA-Dp_lw9II.js +1 -0
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-5b-8o2iS.js +1 -0
- ksadk/server/static/assets/swimlanes-XN3QIQJK-D8O5UlLG.js +1 -0
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uf6WPRA4.js +8 -0
- ksadk/server/static/assets/{timeline-definition-PNZ67QCA-DEz24vV0.js → timeline-definition-24CTP7MA-8mfKcxvG.js} +7 -7
- ksadk/server/static/assets/treeView-Q6P3EWNA-CK5CSrSO.js +1 -0
- ksadk/server/static/assets/treemap-WGGIJYW6-Ch2BKgAM.js +1 -0
- ksadk/server/static/assets/vennDiagram-4TSXK5OY-EnNl0DE7.js +34 -0
- ksadk/server/static/assets/wardley-WFR3VGLG-YW3Q0ml_.js +1 -0
- ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DBu5fbYr.js +78 -0
- ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-BSVXs4IY.js +7 -0
- ksadk/server/static/index.html +2 -2
- ksadk/sessions/__init__.py +26 -9
- ksadk/sessions/_local_service_sync.py +688 -0
- ksadk/sessions/_local_tables.py +21 -0
- ksadk/sessions/_postgres_schema.py +305 -0
- ksadk/sessions/_postgres_tables.py +15 -0
- ksadk/sessions/base.py +80 -1
- ksadk/sessions/in_memory.py +53 -2
- ksadk/sessions/local_service.py +63 -604
- ksadk/sessions/postgres_service.py +58 -148
- ksadk/sessions/resilient.py +35 -1
- ksadk/skills/service_client.py +48 -0
- ksadk/studio/agent_lifecycle.py +26 -20
- ksadk/studio/api.py +1063 -69
- ksadk/studio/api_catalog_routes.py +5 -0
- ksadk/studio/api_contracts.py +148 -6
- ksadk/studio/api_memory_routes.py +82 -0
- ksadk/studio/api_plugin_routes.py +480 -0
- ksadk/studio/attachment_store.py +187 -0
- ksadk/studio/authoring.py +259 -28
- ksadk/studio/authoring_coordinator.py +809 -67
- ksadk/studio/builder.py +197 -40
- ksadk/studio/capabilities.py +17 -0
- ksadk/studio/cloud.py +1920 -95
- ksadk/studio/codex_agent_service.py +137 -15
- ksadk/studio/codex_authoring.py +469 -0
- ksadk/studio/codex_builder.py +177 -25
- ksadk/studio/codex_manifest.py +71 -22
- ksadk/studio/codex_run.py +59 -4
- ksadk/studio/compatibility_report.py +445 -0
- ksadk/studio/compiler.py +7 -1
- ksadk/studio/contracts.py +234 -4
- ksadk/studio/dsh_provider_registration.py +768 -0
- ksadk/studio/event_store.py +79 -101
- ksadk/studio/framework_run.py +264 -3
- ksadk/studio/hosted_kernel.py +317 -0
- ksadk/studio/manifest_resolver.py +131 -0
- ksadk/studio/model_client.py +95 -9
- ksadk/studio/model_profile_service.py +1 -1
- ksadk/studio/operations.py +47 -5
- ksadk/studio/otel_trace.py +348 -42
- ksadk/studio/pcm_memory.py +85 -0
- ksadk/studio/plugin_composition.py +301 -0
- ksadk/studio/plugin_kernel_adapter.py +128 -0
- ksadk/studio/plugin_runtime.py +652 -0
- ksadk/studio/repository.py +23 -2
- ksadk/studio/resource_catalog.py +49 -1
- ksadk/studio/run_service.py +1266 -202
- ksadk/studio/runtime_source.py +51 -17
- ksadk/studio/scheduler_runtime.py +374 -0
- ksadk/studio/scheduler_service.py +211 -0
- ksadk/studio/service.py +1815 -117
- ksadk/studio/shared_web.py +199 -50
- ksadk/studio/soul.py +52 -0
- ksadk/studio/static/assets/index-DXs1Eq4M.css +1 -0
- ksadk/studio/static/assets/index-DeDqwTsD.js +283 -0
- ksadk/studio/static/index.html +2 -2
- ksadk/studio/templates.py +100 -8
- ksadk/studio/validator.py +20 -1
- ksadk/studio/workspace.py +31 -32
- ksadk/tracing/setup.py +304 -3
- ksadk/version.py +1 -1
- ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
- ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
- ksadk_runtime_common/workspace_files/path_utils.py +41 -0
- ksadk/events/parser.py +0 -191
- ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
- ksadk/server/static/assets/MermaidBlock-NERD_ef7.js +0 -303
- ksadk/server/static/assets/NativeTerminalPanel-CiHWf82q.js +0 -1
- ksadk/server/static/assets/arc-DrgjcKhl.js +0 -1
- ksadk/server/static/assets/architecture-7EHR7CIX-CpZLRCcY.js +0 -1
- ksadk/server/static/assets/architectureDiagram-3BPJPVTR-BXoVRbQ6.js +0 -36
- ksadk/server/static/assets/blockDiagram-GPEHLZMM-BnaB3Ywv.js +0 -132
- ksadk/server/static/assets/c4Diagram-AAUBKEIU-Dw4weZcp.js +0 -10
- ksadk/server/static/assets/channel-Dt3rQTFI.js +0 -1
- ksadk/server/static/assets/chunk-2J33WTMH-ChjpLK7j.js +0 -1
- ksadk/server/static/assets/chunk-55IACEB6-CK4ROATy.js +0 -1
- ksadk/server/static/assets/chunk-727SXJPM-B9KtTTgw.js +0 -206
- ksadk/server/static/assets/chunk-AQP2D5EJ-1O1mki3m.js +0 -231
- ksadk/server/static/assets/chunk-QZHKN3VN-iXEZtKQc.js +0 -1
- ksadk/server/static/assets/classDiagram-4FO5ZUOK-DIveV17Q.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-DIveV17Q.js +0 -1
- ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
- ksadk/server/static/assets/dagre-BM42HDAG-D0QXg_MQ.js +0 -4
- ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
- ksadk/server/static/assets/diagram-2AECGRRQ-DBDDKwBQ.js +0 -43
- ksadk/server/static/assets/diagram-5GNKFQAL-BkwDOxmO.js +0 -10
- ksadk/server/static/assets/diagram-KO2AKTUF-Bv8waYvY.js +0 -3
- ksadk/server/static/assets/diagram-LMA3HP47-e1VECDdu.js +0 -24
- ksadk/server/static/assets/diagram-OG6HWLK6-Ds9adfRl.js +0 -24
- ksadk/server/static/assets/dist-B5J2uhNk.js +0 -1
- ksadk/server/static/assets/erDiagram-TEJ5UH35-BPItFKH6.js +0 -85
- ksadk/server/static/assets/eventmodeling-FCH6USID-DYFSxbqr.js +0 -1
- ksadk/server/static/assets/flowDiagram-I6XJVG4X-BbYB9w5Y.js +0 -162
- ksadk/server/static/assets/ganttDiagram-6RSMTGT7-TQXa0KXv.js +0 -292
- ksadk/server/static/assets/gitGraph-WXDBUCRP-DyNYp6BN.js +0 -1
- ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-bKblCnpa.js +0 -106
- ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
- ksadk/server/static/assets/index-R52pJJvg.js +0 -177
- ksadk/server/static/assets/index-jJr3_955.css +0 -2
- ksadk/server/static/assets/info-J43DQDTF-WUx7qTde.js +0 -1
- ksadk/server/static/assets/infoDiagram-5YYISTIA-BGVT7J_i.js +0 -2
- ksadk/server/static/assets/katex-CYWseY5E.js +0 -265
- ksadk/server/static/assets/mermaid-parser.core-BWrDjSZM.js +0 -161
- ksadk/server/static/assets/packet-YPE3B663-BN13y_xl.js +0 -1
- ksadk/server/static/assets/pie-LRSECV5Y-ftSLXhhc.js +0 -1
- ksadk/server/static/assets/pieDiagram-4H26LBE5-GmmqNiVH.js +0 -30
- ksadk/server/static/assets/radar-GUYGQ44K-jaICkIeO.js +0 -1
- ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DSWFqL7c.js +0 -84
- ksadk/server/static/assets/stateDiagram-AJRCARHV-qzTQpg3Y.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-BYCoYGAN.js +0 -1
- ksadk/server/static/assets/treeView-BLDUP644-Cpib_vlz.js +0 -1
- ksadk/server/static/assets/treemap-LRROVOQU-DQxfmVHK.js +0 -1
- ksadk/server/static/assets/vennDiagram-CIIHVFJN-CMCixki2.js +0 -34
- ksadk/server/static/assets/wardley-L42UT6IY-BQYHnnkU.js +0 -1
- ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-CVzB8F9K.js +0 -78
- ksadk/server/static/assets/xychartDiagram-2RQKCTM6-BFBqBLc1.js +0 -7
- ksadk/studio/evaluation.py +0 -192
- ksadk/studio/static/assets/index-CaEN0eTR.css +0 -1
- ksadk/studio/static/assets/index-DI2eY_NH.js +0 -252
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/WHEEL +0 -0
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/top_level.txt +0 -0
ksadk/runtime/runner_adapter.py
CHANGED
|
@@ -13,22 +13,32 @@ from __future__ import annotations
|
|
|
13
13
|
import asyncio
|
|
14
14
|
import copy
|
|
15
15
|
import inspect
|
|
16
|
-
import json
|
|
17
16
|
import logging
|
|
17
|
+
import time
|
|
18
18
|
from collections.abc import Mapping
|
|
19
|
-
from contextlib import nullcontext
|
|
20
19
|
from dataclasses import dataclass, field
|
|
21
20
|
from typing import Any, AsyncIterator, Dict, Optional, cast
|
|
22
21
|
|
|
23
|
-
from
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
from pydantic import JsonValue
|
|
23
|
+
|
|
24
|
+
from ksadk.events.canonical import (
|
|
25
|
+
ApprovalRequest,
|
|
26
|
+
InteractionRequested,
|
|
27
|
+
OutputRef,
|
|
28
|
+
RunCanceled,
|
|
29
|
+
RunCompleted,
|
|
30
|
+
RunInterrupted,
|
|
31
|
+
RunStarted,
|
|
32
|
+
RuntimeEvent,
|
|
33
|
+
SourceRef,
|
|
34
|
+
)
|
|
35
|
+
from ksadk.events.identity import (
|
|
36
|
+
stable_event_id,
|
|
37
|
+
stable_item_id,
|
|
38
|
+
stable_scope_id,
|
|
30
39
|
)
|
|
31
|
-
from ksadk.
|
|
40
|
+
from ksadk.kernel.contracts import RuntimeCapability, RuntimeCapabilityMatrix
|
|
41
|
+
from ksadk.kernel.errors import UnsupportedControlError
|
|
32
42
|
from ksadk.runners.base_runner import BaseRunner
|
|
33
43
|
from ksadk.runtime.adapter import (
|
|
34
44
|
RESUME_START_REQUEST_NATIVE_KEY,
|
|
@@ -44,79 +54,21 @@ from ksadk.runtime.adapter import (
|
|
|
44
54
|
)
|
|
45
55
|
from ksadk.runtime.preprocessing import PreparedRuntimeStart, prepare_runtime_start
|
|
46
56
|
from ksadk.runtime.runner_loading import ensure_runner_loaded
|
|
47
|
-
from ksadk.runtime_context import platform_invocation_scope
|
|
48
|
-
from ksadk.tools.gateway import approval_interrupt_info_from_result
|
|
49
57
|
|
|
50
58
|
logger = logging.getLogger(__name__)
|
|
51
59
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
async def _anext_or_stop(gen: AsyncIterator[Any]) -> Any:
|
|
57
|
-
"""取下一个 chunk;流结束返回 _STREAM_STOP sentinel(便于竞速)。"""
|
|
58
|
-
try:
|
|
59
|
-
return await gen.__anext__()
|
|
60
|
-
except StopAsyncIteration:
|
|
61
|
-
return _STREAM_STOP
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def _a2ui_surface_event(chunk: Any) -> tuple[str, dict[str, Any]] | None:
|
|
65
|
-
"""Recognize a validated A2UI tool envelope and make it a first-class event.
|
|
60
|
+
# 保留既有 monkeypatch patch 点:stream_mapping 在调用时经本模块属性解析。
|
|
61
|
+
from ksadk.conversations.runtime_observability import ( # noqa: E402,F401
|
|
62
|
+
_conversation_span_scope,
|
|
63
|
+
)
|
|
66
64
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
"""
|
|
65
|
+
# dict-chunk 退化路径的流竞速/事件映射实现拆至 _runner_adapter 子包(纯移动,行为不变)。
|
|
66
|
+
from ksadk.runtime._runner_adapter.stream_mapping import ( # noqa: E402
|
|
67
|
+
_STREAM_STOP,
|
|
68
|
+
_RunnerStreamMappingMixin,
|
|
69
|
+
)
|
|
73
70
|
|
|
74
|
-
|
|
75
|
-
return None
|
|
76
|
-
value = chunk.get("tool_output", chunk.get("output"))
|
|
77
|
-
if value is not None and hasattr(value, "content"):
|
|
78
|
-
value = value.content
|
|
79
|
-
if isinstance(value, str):
|
|
80
|
-
try:
|
|
81
|
-
value = json.loads(value)
|
|
82
|
-
except (TypeError, ValueError):
|
|
83
|
-
return None
|
|
84
|
-
if not isinstance(value, Mapping):
|
|
85
|
-
return None
|
|
86
|
-
operations_raw = value.get("a2ui_operations")
|
|
87
|
-
if not isinstance(operations_raw, list) or not operations_raw:
|
|
88
|
-
return None
|
|
89
|
-
operations = [dict(operation) for operation in operations_raw if isinstance(operation, Mapping)]
|
|
90
|
-
if not operations:
|
|
91
|
-
return None
|
|
92
|
-
|
|
93
|
-
known: list[tuple[str, str]] = []
|
|
94
|
-
for operation in operations:
|
|
95
|
-
for key, event_type in (
|
|
96
|
-
("createSurface", EventType.A2UI_SURFACE_BEGIN),
|
|
97
|
-
("updateComponents", EventType.A2UI_SURFACE_UPDATE),
|
|
98
|
-
("updateDataModel", EventType.A2UI_SURFACE_UPDATE),
|
|
99
|
-
("deleteSurface", EventType.A2UI_SURFACE_END),
|
|
100
|
-
):
|
|
101
|
-
detail = operation.get(key)
|
|
102
|
-
if isinstance(detail, Mapping) and isinstance(detail.get("surfaceId"), str):
|
|
103
|
-
surface_id = detail["surfaceId"].strip()
|
|
104
|
-
if surface_id:
|
|
105
|
-
known.append((surface_id, event_type))
|
|
106
|
-
break
|
|
107
|
-
if not known:
|
|
108
|
-
return None
|
|
109
|
-
surface_ids = {surface_id for surface_id, _event_type in known}
|
|
110
|
-
if len(surface_ids) != 1:
|
|
111
|
-
logger.warning("ignoring A2UI tool result with multiple surfaces")
|
|
112
|
-
return None
|
|
113
|
-
surface_id = known[0][0]
|
|
114
|
-
event_type = (
|
|
115
|
-
EventType.A2UI_SURFACE_BEGIN
|
|
116
|
-
if any(kind == EventType.A2UI_SURFACE_BEGIN for _surface_id, kind in known)
|
|
117
|
-
else known[0][1]
|
|
118
|
-
)
|
|
119
|
-
return event_type, {"surface_id": surface_id, "operations": operations}
|
|
71
|
+
_ResumeKey = tuple[str, str, str, str, str]
|
|
120
72
|
|
|
121
73
|
|
|
122
74
|
def _coerce_literal(value: Any, allowed: tuple[str, ...], default: str) -> Any:
|
|
@@ -161,9 +113,13 @@ class _ActiveRun:
|
|
|
161
113
|
skip_runner: bool = False
|
|
162
114
|
done: bool = False
|
|
163
115
|
completion_metrics: dict[str, Any] = field(default_factory=dict)
|
|
116
|
+
# dict-chunk 退化路径:追踪已 ItemStarted 的 item key,避免重复发 Started。
|
|
117
|
+
started_items: set[tuple[str, str]] = field(default_factory=set)
|
|
118
|
+
# dict-chunk 退化路径:final_answer message 的 item_id,供 RunCompleted.output_refs 引用。
|
|
119
|
+
final_answer_item_id: Optional[str] = None
|
|
164
120
|
|
|
165
121
|
|
|
166
|
-
class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
122
|
+
class RunnerRuntimeAdapter(_RunnerStreamMappingMixin, RuntimeAdapter):
|
|
167
123
|
"""把 ``BaseRunner`` 映射为平台六动词的通用 adapter。"""
|
|
168
124
|
|
|
169
125
|
def __init__(self, runner: BaseRunner, *, runtime_type: str) -> None:
|
|
@@ -182,6 +138,68 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
182
138
|
|
|
183
139
|
# ---- 框架钩子(子类按需 override) ----
|
|
184
140
|
|
|
141
|
+
def capabilities(self) -> RuntimeCapabilityMatrix:
|
|
142
|
+
"""诚实矩阵:cancel 经 asyncio 任务打断(emulated,过 conformance);
|
|
143
|
+
resume/checkpoint 依赖 runner 声明的原生 checkpoint;attach/durable_restore
|
|
144
|
+
依赖 ``attach_runtime_handle`` seam 与跨进程持久化,内存表不算数。
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
def _unavailable(reason: str) -> RuntimeCapability:
|
|
148
|
+
return RuntimeCapability(supported=False, mode="unavailable", reason=reason)
|
|
149
|
+
|
|
150
|
+
checkpoint_capability = self._checkpoint_capability()
|
|
151
|
+
attach_seam = callable(getattr(self._runner, "attach_runtime_handle", None))
|
|
152
|
+
checkpoint_supported = bool(checkpoint_capability.supported)
|
|
153
|
+
durable_supported = bool(
|
|
154
|
+
checkpoint_capability.durable
|
|
155
|
+
and checkpoint_capability.shared_across_pods
|
|
156
|
+
and attach_seam
|
|
157
|
+
)
|
|
158
|
+
return RuntimeCapabilityMatrix(
|
|
159
|
+
cancel=RuntimeCapability(
|
|
160
|
+
supported=True,
|
|
161
|
+
mode="emulated",
|
|
162
|
+
reason="runner_stream_task_interrupt",
|
|
163
|
+
),
|
|
164
|
+
pause=_unavailable("runtime_no_native_pause"),
|
|
165
|
+
resume=(
|
|
166
|
+
RuntimeCapability(supported=True, mode="native")
|
|
167
|
+
if checkpoint_supported
|
|
168
|
+
else _unavailable("runtime_no_native_checkpoint")
|
|
169
|
+
),
|
|
170
|
+
submit_interaction=_unavailable("runtime_no_live_interaction_channel"),
|
|
171
|
+
attach=(
|
|
172
|
+
RuntimeCapability(supported=True, mode="native")
|
|
173
|
+
if attach_seam
|
|
174
|
+
else _unavailable("runner_no_durable_attach_seam")
|
|
175
|
+
),
|
|
176
|
+
steer=_unavailable("runtime_no_native_steer"),
|
|
177
|
+
inject=_unavailable("runtime_no_native_inject"),
|
|
178
|
+
checkpoint=(
|
|
179
|
+
RuntimeCapability(supported=True, mode="native")
|
|
180
|
+
if checkpoint_supported
|
|
181
|
+
else _unavailable("runtime_no_native_checkpoint")
|
|
182
|
+
),
|
|
183
|
+
durable_restore=(
|
|
184
|
+
RuntimeCapability(supported=True, mode="native")
|
|
185
|
+
if durable_supported
|
|
186
|
+
else _unavailable("durable_restore_requires_cross_process_checkpoint")
|
|
187
|
+
),
|
|
188
|
+
# A generic Runner cannot claim interaction delivery merely from a
|
|
189
|
+
# checkpoint capability. ADK is forward-only and only the
|
|
190
|
+
# LangGraph specialization below binds a checkpoint to the
|
|
191
|
+
# original interrupt identity.
|
|
192
|
+
interaction_mode="unavailable",
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
async def durable_restore(self, handle: RunHandle) -> RunHandle:
|
|
196
|
+
if not self.capabilities().durable_restore.supported:
|
|
197
|
+
raise UnsupportedControlError(
|
|
198
|
+
f"{self._runtime_type} has no cross-process checkpoint backend for run "
|
|
199
|
+
f"{handle.run_id!r}"
|
|
200
|
+
)
|
|
201
|
+
return await self.attach(handle)
|
|
202
|
+
|
|
185
203
|
def _checkpoint_capability(self) -> CheckpointCapability:
|
|
186
204
|
"""诚实暴露 checkpoint 粒度。默认读 runner.describe_checkpoint_capability。"""
|
|
187
205
|
raw = {}
|
|
@@ -285,7 +303,7 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
285
303
|
)
|
|
286
304
|
attach = getattr(self._runner, "attach_runtime_handle", None)
|
|
287
305
|
if not callable(attach):
|
|
288
|
-
raise
|
|
306
|
+
raise UnsupportedControlError(
|
|
289
307
|
f"runner for {self._runtime_type!r} has no durable "
|
|
290
308
|
"attach_runtime_handle capability"
|
|
291
309
|
)
|
|
@@ -408,7 +426,7 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
408
426
|
capability = self._require_native_checkpoint_capability()
|
|
409
427
|
checkpoint_id = str(handle.native_ref.get("checkpoint_id") or "").strip()
|
|
410
428
|
if not checkpoint_id:
|
|
411
|
-
raise
|
|
429
|
+
raise UnsupportedControlError(
|
|
412
430
|
f"{self._runtime_type} runner has no native checkpoint for run "
|
|
413
431
|
f"{handle.run_id!r}"
|
|
414
432
|
)
|
|
@@ -425,7 +443,7 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
425
443
|
if capability.supported:
|
|
426
444
|
return capability
|
|
427
445
|
detail = capability.reason or "runner does not expose framework checkpoints"
|
|
428
|
-
raise
|
|
446
|
+
raise UnsupportedControlError(
|
|
429
447
|
f"{self._runtime_type} native checkpoint capability is unavailable: {detail}"
|
|
430
448
|
)
|
|
431
449
|
|
|
@@ -495,30 +513,19 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
495
513
|
# 消费 pending cancel:start 时若已记 pending,立即中断该 turn。
|
|
496
514
|
if handle.run_id in self._pending_cancels:
|
|
497
515
|
self._pending_cancels.discard(handle.run_id)
|
|
498
|
-
yield self.
|
|
499
|
-
handle,
|
|
500
|
-
EventType.RUN_CANCELED,
|
|
501
|
-
{
|
|
502
|
-
"status": "cancelled",
|
|
503
|
-
"cancel_result": CancelResult.PENDING_CANCEL_RECORDED.value,
|
|
504
|
-
},
|
|
505
|
-
)
|
|
516
|
+
yield self._make_run_canceled(handle, reason=CancelResult.PENDING_CANCEL_RECORDED.value)
|
|
506
517
|
return
|
|
507
518
|
|
|
508
519
|
if run.skip_runner:
|
|
509
520
|
run.done = True
|
|
510
521
|
self._active_runs.pop(handle.run_id, None)
|
|
511
|
-
yield self.
|
|
512
|
-
handle,
|
|
513
|
-
EventType.RUN_COMPLETED,
|
|
514
|
-
self._completion_payload(handle, status="already_resumed"),
|
|
515
|
-
)
|
|
522
|
+
yield self._make_run_completed(handle)
|
|
516
523
|
return
|
|
517
524
|
|
|
518
525
|
if run.resume_key is not None:
|
|
519
526
|
self._consumed_resumes.add(run.resume_key)
|
|
520
527
|
|
|
521
|
-
yield self.
|
|
528
|
+
yield self._make_run_started(handle)
|
|
522
529
|
|
|
523
530
|
request = run.__dict__.get("_start_request")
|
|
524
531
|
runner_input = self._build_runner_input(handle, request)
|
|
@@ -530,43 +537,35 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
530
537
|
run.stream = gen
|
|
531
538
|
async for event in gen:
|
|
532
539
|
yield event
|
|
533
|
-
if event.event_type ==
|
|
540
|
+
if event.event_type == "interaction.requested":
|
|
534
541
|
approval_interrupted = True
|
|
542
|
+
# Track pending approval for canonical streams that bypass
|
|
543
|
+
# _chunk_to_event (e.g. stream_canonical_events).
|
|
544
|
+
if isinstance(event, InteractionRequested):
|
|
545
|
+
call_id = str(event.interaction_id or "")
|
|
546
|
+
if call_id:
|
|
547
|
+
run.pending_approvals.add(call_id)
|
|
548
|
+
pending_ids = handle.native_ref.setdefault("pending_approval_ids", [])
|
|
549
|
+
if call_id not in pending_ids:
|
|
550
|
+
pending_ids.append(call_id)
|
|
535
551
|
if event.event_type in {
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
552
|
+
"run.completed",
|
|
553
|
+
"run.failed",
|
|
554
|
+
"run.canceled",
|
|
555
|
+
"run.interrupted",
|
|
540
556
|
}:
|
|
541
557
|
terminal_event_seen = True
|
|
542
|
-
if event.event_type in {
|
|
558
|
+
if event.event_type in {"run.failed", "run.canceled"}:
|
|
543
559
|
return
|
|
544
560
|
|
|
545
561
|
if run.interrupt_event.is_set() and not terminal_event_seen:
|
|
546
|
-
yield self.
|
|
547
|
-
handle,
|
|
548
|
-
EventType.RUN_CANCELED,
|
|
549
|
-
{
|
|
550
|
-
"status": "cancelled",
|
|
551
|
-
"cancel_result": CancelResult.INTERRUPTED_ACTIVE_TURN.value,
|
|
552
|
-
},
|
|
562
|
+
yield self._make_run_canceled(
|
|
563
|
+
handle, reason=CancelResult.INTERRUPTED_ACTIVE_TURN.value
|
|
553
564
|
)
|
|
554
565
|
elif approval_interrupted and not terminal_event_seen:
|
|
555
|
-
yield self.
|
|
556
|
-
handle,
|
|
557
|
-
EventType.RUN_INTERRUPTED,
|
|
558
|
-
{"status": "input_required"},
|
|
559
|
-
)
|
|
566
|
+
yield self._make_run_interrupted(handle, reason="input_required")
|
|
560
567
|
elif not terminal_event_seen:
|
|
561
|
-
yield self.
|
|
562
|
-
handle,
|
|
563
|
-
EventType.RUN_COMPLETED,
|
|
564
|
-
self._completion_payload(
|
|
565
|
-
handle,
|
|
566
|
-
status="completed",
|
|
567
|
-
metrics=run.completion_metrics,
|
|
568
|
-
),
|
|
569
|
-
)
|
|
568
|
+
yield self._make_run_completed(handle, run=run, metrics=run.completion_metrics)
|
|
570
569
|
finally:
|
|
571
570
|
run.stream = None
|
|
572
571
|
run.done = True
|
|
@@ -585,15 +584,17 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
585
584
|
else {}
|
|
586
585
|
)
|
|
587
586
|
base_metadata = merged.get("metadata")
|
|
588
|
-
merged.update(
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
587
|
+
merged.update(
|
|
588
|
+
{
|
|
589
|
+
"input": override.get("input"),
|
|
590
|
+
"session_id": handle.session_id,
|
|
591
|
+
"invocation_id": handle.run_id,
|
|
592
|
+
"metadata": {
|
|
593
|
+
**(dict(base_metadata) if isinstance(base_metadata, Mapping) else {}),
|
|
594
|
+
**dict(override.get("metadata") or {}),
|
|
595
|
+
},
|
|
596
|
+
}
|
|
597
|
+
)
|
|
597
598
|
for key, value in override.items():
|
|
598
599
|
if key not in ("input", "metadata"):
|
|
599
600
|
merged[key] = value
|
|
@@ -617,355 +618,19 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
617
618
|
"metadata": metadata,
|
|
618
619
|
}
|
|
619
620
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
run = self._active_runs.get(handle.run_id)
|
|
624
|
-
interrupt = run.interrupt_event if run is not None else None
|
|
625
|
-
prepared_start = run.__dict__.get("_prepared_start") if run is not None else None
|
|
626
|
-
invocation_context = (
|
|
627
|
-
prepared_start.context if isinstance(prepared_start, PreparedRuntimeStart) else None
|
|
628
|
-
)
|
|
629
|
-
scope = (
|
|
630
|
-
platform_invocation_scope(invocation_context)
|
|
631
|
-
if invocation_context is not None
|
|
632
|
-
else nullcontext()
|
|
633
|
-
)
|
|
634
|
-
runner_name = _runner_name(self._runner)
|
|
635
|
-
accumulated_output = ""
|
|
636
|
-
usage: dict[str, Any] = {}
|
|
637
|
-
runner_gen: Optional[AsyncIterator[Any]] = None
|
|
638
|
-
async with _conversation_span_scope(runner_name) as span:
|
|
639
|
-
if isinstance(prepared_start, PreparedRuntimeStart):
|
|
640
|
-
_set_conversation_span_attributes(
|
|
641
|
-
span,
|
|
642
|
-
agent_id=str(handle.native_ref.get("agent_id") or "agent"),
|
|
643
|
-
user_id=str(handle.native_ref.get("user_id") or "user"),
|
|
644
|
-
session_id=handle.session_id,
|
|
645
|
-
invocation_id=handle.run_id,
|
|
646
|
-
runner_name=runner_name,
|
|
647
|
-
model=prepared_start.context.model,
|
|
648
|
-
response_id=prepared_start.response_id,
|
|
649
|
-
)
|
|
650
|
-
_set_conversation_input_attributes(span, prepared_start.input_text)
|
|
651
|
-
try:
|
|
652
|
-
with scope:
|
|
653
|
-
canonical_stream = getattr(self._runner, "stream_runtime_events", None)
|
|
654
|
-
stream_result = (
|
|
655
|
-
canonical_stream(runner_input)
|
|
656
|
-
if callable(canonical_stream)
|
|
657
|
-
else self._runner.stream(runner_input)
|
|
658
|
-
)
|
|
659
|
-
if inspect.iscoroutine(stream_result):
|
|
660
|
-
# runner.stream 若声明为 async def -> AsyncIterator(非 async generator),
|
|
661
|
-
# 调用返回 coroutine,需 await 得到迭代器。
|
|
662
|
-
stream_result = await stream_result
|
|
663
|
-
runner_gen = cast(AsyncIterator[Any], stream_result)
|
|
664
|
-
while True:
|
|
665
|
-
# 竞速:下一个 runner chunk vs cancel 中断事件。
|
|
666
|
-
chunk_task = asyncio.ensure_future(_anext_or_stop(runner_gen))
|
|
667
|
-
if run is not None:
|
|
668
|
-
run.chunk_task = chunk_task
|
|
669
|
-
wait_set = {chunk_task}
|
|
670
|
-
interrupt_task = (
|
|
671
|
-
asyncio.ensure_future(interrupt.wait())
|
|
672
|
-
if interrupt is not None
|
|
673
|
-
else None
|
|
674
|
-
)
|
|
675
|
-
if interrupt_task is not None:
|
|
676
|
-
wait_set.add(interrupt_task)
|
|
677
|
-
done, pending = await asyncio.wait(
|
|
678
|
-
wait_set, return_when=asyncio.FIRST_COMPLETED
|
|
679
|
-
)
|
|
680
|
-
for task in pending:
|
|
681
|
-
task.cancel()
|
|
682
|
-
if pending:
|
|
683
|
-
await asyncio.gather(*pending, return_exceptions=True)
|
|
684
|
-
if interrupt_task is not None and interrupt_task in done:
|
|
685
|
-
# cancel 中断:安全关闭 runner 流(同一 task)并停止。
|
|
686
|
-
chunk_task.cancel()
|
|
687
|
-
await asyncio.gather(chunk_task, return_exceptions=True)
|
|
688
|
-
return
|
|
689
|
-
try:
|
|
690
|
-
chunk = chunk_task.result()
|
|
691
|
-
except asyncio.CancelledError:
|
|
692
|
-
if interrupt is not None and interrupt.is_set():
|
|
693
|
-
return
|
|
694
|
-
raise
|
|
695
|
-
finally:
|
|
696
|
-
if run is not None:
|
|
697
|
-
run.chunk_task = None
|
|
698
|
-
if chunk is _STREAM_STOP:
|
|
699
|
-
return
|
|
700
|
-
if isinstance(chunk, RuntimeEvent):
|
|
701
|
-
if chunk.event_type in {
|
|
702
|
-
EventType.TEXT_DELTA,
|
|
703
|
-
EventType.TEXT_COMPLETED,
|
|
704
|
-
} and chunk.phase == "final_answer":
|
|
705
|
-
text = self._coerce(chunk.payload.get("text"))
|
|
706
|
-
if chunk.event_type == EventType.TEXT_COMPLETED:
|
|
707
|
-
accumulated_output = text
|
|
708
|
-
else:
|
|
709
|
-
accumulated_output += text
|
|
710
|
-
elif chunk.event_type == EventType.USAGE_REPORTED:
|
|
711
|
-
usage.update(chunk.payload)
|
|
712
|
-
if isinstance(chunk, dict):
|
|
713
|
-
chunk_type = str(chunk.get("type") or "")
|
|
714
|
-
if chunk_type == "final" and run is not None:
|
|
715
|
-
for source_key, target_key in (
|
|
716
|
-
("duration_ms", "duration_ms"),
|
|
717
|
-
("started_at", "started_at"),
|
|
718
|
-
("completed_at", "completed_at"),
|
|
719
|
-
("metrics_source", "source"),
|
|
720
|
-
):
|
|
721
|
-
if chunk.get(source_key) is not None:
|
|
722
|
-
run.completion_metrics[target_key] = chunk[source_key]
|
|
723
|
-
if chunk_type in {"final", "text", "text_delta"}:
|
|
724
|
-
text = self._coerce(
|
|
725
|
-
chunk.get("delta") or chunk.get("output") or chunk.get("data")
|
|
726
|
-
)
|
|
727
|
-
if text:
|
|
728
|
-
if chunk_type == "final" or chunk.get("replace"):
|
|
729
|
-
accumulated_output = text
|
|
730
|
-
else:
|
|
731
|
-
accumulated_output += text
|
|
732
|
-
raw_usage = chunk.get("usage")
|
|
733
|
-
if isinstance(raw_usage, dict):
|
|
734
|
-
usage.update(raw_usage)
|
|
735
|
-
event = self._chunk_to_event(handle, run, chunk)
|
|
736
|
-
if event is not None:
|
|
737
|
-
yield event
|
|
738
|
-
a2ui_surface = _a2ui_surface_event(chunk)
|
|
739
|
-
if a2ui_surface is not None:
|
|
740
|
-
event_type, payload = a2ui_surface
|
|
741
|
-
yield self._event(handle, event_type, payload)
|
|
742
|
-
finally:
|
|
743
|
-
if accumulated_output:
|
|
744
|
-
_set_conversation_output_attributes(span, accumulated_output)
|
|
745
|
-
_set_conversation_usage_attributes(span, usage)
|
|
746
|
-
if runner_gen is not None:
|
|
747
|
-
aclose = getattr(runner_gen, "aclose", None)
|
|
748
|
-
if callable(aclose):
|
|
749
|
-
try:
|
|
750
|
-
await aclose()
|
|
751
|
-
except Exception: # noqa: BLE001
|
|
752
|
-
pass
|
|
753
|
-
if run is not None:
|
|
754
|
-
run.cancellation_ack.set()
|
|
755
|
-
|
|
756
|
-
def _chunk_to_event(
|
|
757
|
-
self, handle: RunHandle, run: Optional[_ActiveRun], chunk: Any
|
|
758
|
-
) -> Optional[RuntimeEvent]:
|
|
759
|
-
if isinstance(chunk, RuntimeEvent):
|
|
760
|
-
# Outer adapter owns the public lifecycle envelope. A native
|
|
761
|
-
# Runtime may emit its own RUN_STARTED with private identifiers;
|
|
762
|
-
# suppress that duplicate and rebind all other canonical events
|
|
763
|
-
# to the public handle without flattening their payloads.
|
|
764
|
-
if chunk.event_type == EventType.RUN_STARTED:
|
|
765
|
-
return None
|
|
766
|
-
return RuntimeEvent.create(
|
|
767
|
-
chunk.event_type,
|
|
768
|
-
agent_id=str(handle.native_ref.get("agent_id") or "agent"),
|
|
769
|
-
user_id=str(handle.native_ref.get("user_id") or "user"),
|
|
770
|
-
session_id=handle.session_id,
|
|
771
|
-
invocation_id=handle.run_id,
|
|
772
|
-
seq_id=self._next_seq(),
|
|
773
|
-
phase=chunk.phase,
|
|
774
|
-
payload=dict(chunk.payload),
|
|
775
|
-
event_id=chunk.event_id,
|
|
776
|
-
timestamp=chunk.timestamp,
|
|
777
|
-
)
|
|
778
|
-
if not isinstance(chunk, dict):
|
|
779
|
-
return self._event(
|
|
780
|
-
handle, EventType.TEXT_DELTA, {"text": str(chunk)}, phase="commentary"
|
|
781
|
-
)
|
|
782
|
-
chunk_type = chunk.get("type")
|
|
783
|
-
if chunk_type in ("reasoning", "reasoning_delta", "thinking"):
|
|
784
|
-
text = self._coerce(
|
|
785
|
-
chunk.get("delta")
|
|
786
|
-
or chunk.get("content")
|
|
787
|
-
or chunk.get("output")
|
|
788
|
-
or chunk.get("data")
|
|
789
|
-
)
|
|
790
|
-
if not text:
|
|
791
|
-
return None
|
|
792
|
-
event_type = (
|
|
793
|
-
EventType.REASONING_COMPLETED
|
|
794
|
-
if chunk.get("status") in ("completed", "done")
|
|
795
|
-
else EventType.REASONING_DELTA
|
|
796
|
-
)
|
|
797
|
-
return self._event(
|
|
798
|
-
handle,
|
|
799
|
-
event_type,
|
|
800
|
-
{"text": text},
|
|
801
|
-
phase="commentary",
|
|
802
|
-
)
|
|
803
|
-
if chunk_type in ("tool_call", "tool_start"):
|
|
804
|
-
call_id = str(
|
|
805
|
-
chunk.get("tool_call_id")
|
|
806
|
-
or chunk.get("call_id")
|
|
807
|
-
or chunk.get("run_id")
|
|
808
|
-
or chunk.get("id")
|
|
809
|
-
or ""
|
|
810
|
-
)
|
|
811
|
-
name = str(chunk.get("tool_name") or chunk.get("name") or "tool")
|
|
812
|
-
return self._event(
|
|
813
|
-
handle,
|
|
814
|
-
EventType.TOOL_CALL_BEGIN,
|
|
815
|
-
{
|
|
816
|
-
"call_id": call_id or name,
|
|
817
|
-
"name": name,
|
|
818
|
-
"args": chunk.get("tool_args", chunk.get("args")),
|
|
819
|
-
},
|
|
820
|
-
)
|
|
821
|
-
if chunk_type in ("tool_result", "tool_end"):
|
|
822
|
-
call_id = str(
|
|
823
|
-
chunk.get("tool_call_id")
|
|
824
|
-
or chunk.get("call_id")
|
|
825
|
-
or chunk.get("run_id")
|
|
826
|
-
or chunk.get("id")
|
|
827
|
-
or ""
|
|
828
|
-
)
|
|
829
|
-
name = str(chunk.get("tool_name") or chunk.get("name") or "tool")
|
|
830
|
-
tool_args = chunk.get("tool_args", chunk.get("args"))
|
|
831
|
-
result = chunk.get("tool_output", chunk.get("output"))
|
|
832
|
-
approval_detail = approval_interrupt_info_from_result(
|
|
833
|
-
result,
|
|
834
|
-
fallback_tool_name=name,
|
|
835
|
-
tool_args=tool_args,
|
|
836
|
-
run_id=call_id or None,
|
|
837
|
-
)
|
|
838
|
-
if approval_detail is not None:
|
|
839
|
-
return self._approval_requested_event(
|
|
840
|
-
handle,
|
|
841
|
-
run,
|
|
842
|
-
detail=approval_detail,
|
|
843
|
-
call_id=call_id,
|
|
844
|
-
)
|
|
845
|
-
return self._event(
|
|
846
|
-
handle,
|
|
847
|
-
EventType.TOOL_CALL_END,
|
|
848
|
-
{
|
|
849
|
-
"call_id": call_id or name,
|
|
850
|
-
"name": name,
|
|
851
|
-
"result": result,
|
|
852
|
-
"error": chunk.get("error"),
|
|
853
|
-
},
|
|
854
|
-
)
|
|
855
|
-
if chunk_type in ("interrupt", "approval", "approval_required"):
|
|
856
|
-
raw_detail = chunk.get("interrupt_info") or chunk.get("detail") or {}
|
|
857
|
-
detail = dict(raw_detail) if isinstance(raw_detail, Mapping) else {}
|
|
858
|
-
call_id = str(
|
|
859
|
-
chunk.get("call_id")
|
|
860
|
-
or chunk.get("approval_id")
|
|
861
|
-
or chunk.get("id")
|
|
862
|
-
or ""
|
|
863
|
-
)
|
|
864
|
-
return self._approval_requested_event(
|
|
865
|
-
handle,
|
|
866
|
-
run,
|
|
867
|
-
detail=detail,
|
|
868
|
-
call_id=call_id,
|
|
869
|
-
)
|
|
870
|
-
if chunk_type == "checkpoint":
|
|
871
|
-
raw_metadata = chunk.get("metadata")
|
|
872
|
-
metadata: dict[str, Any] = raw_metadata if isinstance(raw_metadata, dict) else {}
|
|
873
|
-
raw_agentengine = metadata.get("agentengine")
|
|
874
|
-
agentengine: dict[str, Any] = (
|
|
875
|
-
raw_agentengine if isinstance(raw_agentengine, dict) else {}
|
|
876
|
-
)
|
|
877
|
-
framework = str(agentengine.get("framework") or self._runtime_type)
|
|
878
|
-
framework_ref = agentengine.get("framework_ref") or {}
|
|
879
|
-
runtime_ref = (
|
|
880
|
-
framework_ref.get(framework) if isinstance(framework_ref, dict) else {}
|
|
881
|
-
) or {}
|
|
882
|
-
checkpoint_id = str(
|
|
883
|
-
runtime_ref.get("checkpoint_id") if isinstance(runtime_ref, dict) else ""
|
|
884
|
-
)
|
|
885
|
-
if not checkpoint_id:
|
|
886
|
-
return None
|
|
887
|
-
handle.native_ref["checkpoint_id"] = checkpoint_id
|
|
888
|
-
known_checkpoint_ids = handle.native_ref.setdefault("known_checkpoint_ids", [])
|
|
889
|
-
if checkpoint_id not in known_checkpoint_ids:
|
|
890
|
-
known_checkpoint_ids.append(checkpoint_id)
|
|
891
|
-
handle.native_ref["framework_ref"] = framework_ref
|
|
892
|
-
if isinstance(runtime_ref, dict):
|
|
893
|
-
handle.native_ref.update(runtime_ref)
|
|
894
|
-
return self._event(
|
|
895
|
-
handle,
|
|
896
|
-
EventType.CHECKPOINT_CREATED,
|
|
897
|
-
{
|
|
898
|
-
"checkpoint_id": checkpoint_id,
|
|
899
|
-
"granularity": self._checkpoint_capability().granularity,
|
|
900
|
-
"run_id": str(agentengine.get("run_id") or handle.run_id),
|
|
901
|
-
"framework": framework,
|
|
902
|
-
"framework_ref": framework_ref,
|
|
903
|
-
"resume_target": framework_ref,
|
|
904
|
-
},
|
|
905
|
-
)
|
|
906
|
-
if chunk_type == "graph_update":
|
|
907
|
-
return self._event(
|
|
908
|
-
handle,
|
|
909
|
-
EventType.RUN_PROGRESS,
|
|
910
|
-
{
|
|
911
|
-
"status": "in_progress",
|
|
912
|
-
"node": str(chunk.get("node") or ""),
|
|
913
|
-
"state_update": self._coerce(chunk.get("output")),
|
|
914
|
-
},
|
|
915
|
-
)
|
|
916
|
-
if chunk_type == "usage":
|
|
917
|
-
raw_usage = chunk.get("usage")
|
|
918
|
-
usage: dict[str, Any] = raw_usage if isinstance(raw_usage, dict) else {}
|
|
919
|
-
return self._event(
|
|
920
|
-
handle,
|
|
921
|
-
EventType.USAGE_REPORTED,
|
|
922
|
-
{
|
|
923
|
-
"input_tokens": int(usage.get("input_tokens") or 0),
|
|
924
|
-
"output_tokens": int(usage.get("output_tokens") or 0),
|
|
925
|
-
"total_tokens": int(usage.get("total_tokens") or 0),
|
|
926
|
-
"cached_tokens": int(usage.get("cached_tokens") or 0),
|
|
927
|
-
"reasoning_tokens": int(usage.get("reasoning_tokens") or 0),
|
|
928
|
-
"source": str(usage.get("source") or self._runtime_type),
|
|
929
|
-
},
|
|
930
|
-
)
|
|
931
|
-
if chunk_type == "error":
|
|
932
|
-
error = self._coerce(chunk.get("message") or chunk.get("error"))
|
|
933
|
-
return self._event(
|
|
934
|
-
handle,
|
|
935
|
-
EventType.RUN_FAILED,
|
|
936
|
-
{
|
|
937
|
-
"status": "failed",
|
|
938
|
-
"error": error or "runner failed",
|
|
939
|
-
},
|
|
940
|
-
)
|
|
941
|
-
if chunk_type == "final":
|
|
942
|
-
return self._event(
|
|
943
|
-
handle,
|
|
944
|
-
EventType.TEXT_COMPLETED,
|
|
945
|
-
{"text": self._coerce(chunk.get("output"))},
|
|
946
|
-
phase="final_answer",
|
|
947
|
-
)
|
|
948
|
-
text = self._coerce(chunk.get("delta") or chunk.get("output") or chunk.get("data"))
|
|
949
|
-
if not text:
|
|
950
|
-
return None
|
|
951
|
-
payload: dict[str, Any] = {"text": text}
|
|
952
|
-
if chunk.get("replace"):
|
|
953
|
-
payload["replace"] = True
|
|
954
|
-
return self._event(handle, EventType.TEXT_DELTA, payload, phase="commentary")
|
|
955
|
-
|
|
956
|
-
def _approval_requested_event(
|
|
621
|
+
# ---- canonical event construction helpers ----
|
|
622
|
+
|
|
623
|
+
def _interaction_requested_from_approval(
|
|
957
624
|
self,
|
|
958
625
|
handle: RunHandle,
|
|
959
626
|
run: Optional[_ActiveRun],
|
|
960
627
|
*,
|
|
961
628
|
detail: Mapping[str, Any],
|
|
962
629
|
call_id: str,
|
|
963
|
-
) -> RuntimeEvent:
|
|
964
|
-
"""
|
|
630
|
+
) -> list[RuntimeEvent]:
|
|
631
|
+
"""把 ToolGateway 结果中携带的审批请求转为 canonical InteractionRequested。"""
|
|
965
632
|
|
|
966
|
-
approval_id = str(
|
|
967
|
-
detail.get("approval_request_id") or detail.get("id") or call_id or ""
|
|
968
|
-
)
|
|
633
|
+
approval_id = str(detail.get("approval_request_id") or detail.get("id") or call_id or "")
|
|
969
634
|
resolved_call_id = str(call_id or approval_id)
|
|
970
635
|
if run is not None and approval_id:
|
|
971
636
|
run.pending_approvals.add(approval_id)
|
|
@@ -973,52 +638,172 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
973
638
|
pending_approval_ids = handle.native_ref.setdefault("pending_approval_ids", [])
|
|
974
639
|
if approval_id not in pending_approval_ids:
|
|
975
640
|
pending_approval_ids.append(approval_id)
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
641
|
+
framework = self._runtime_type
|
|
642
|
+
run_id = handle.run_id
|
|
643
|
+
scope_id = stable_scope_id(framework, run_id)
|
|
644
|
+
interaction_id = resolved_call_id or stable_item_id(framework, run_id, "interaction")
|
|
645
|
+
item_id = stable_item_id(framework, run_id, "interaction")
|
|
646
|
+
detail_value: JsonValue = (
|
|
647
|
+
cast(JsonValue, dict(detail)) if isinstance(detail, Mapping) else None
|
|
648
|
+
)
|
|
649
|
+
return [
|
|
650
|
+
InteractionRequested(
|
|
651
|
+
**self._canonical_kwargs(
|
|
652
|
+
handle,
|
|
653
|
+
scope_id=scope_id,
|
|
654
|
+
item_id=item_id,
|
|
655
|
+
event_type="interaction.requested",
|
|
656
|
+
part_id="interaction",
|
|
657
|
+
),
|
|
658
|
+
interaction_id=interaction_id,
|
|
659
|
+
interaction_kind="approval",
|
|
660
|
+
request=ApprovalRequest(
|
|
661
|
+
call_id=resolved_call_id or None,
|
|
662
|
+
kind="tool",
|
|
663
|
+
detail=detail_value,
|
|
664
|
+
),
|
|
665
|
+
)
|
|
666
|
+
]
|
|
667
|
+
|
|
668
|
+
def _make_source(self, handle: RunHandle, *, protocol: str | None = None) -> SourceRef:
|
|
669
|
+
# SourceRef.framework 是封闭枚举;测试 fixture 或自定义 runtime_type 落到
|
|
670
|
+
# 通用 "ksadk",原生框架名原样保留。
|
|
671
|
+
framework = self._runtime_type
|
|
672
|
+
if framework not in {"adk", "langgraph", "codex", "a2a", "ksadk"}:
|
|
673
|
+
framework = "ksadk"
|
|
674
|
+
return SourceRef(
|
|
675
|
+
framework=framework,
|
|
676
|
+
protocol=protocol,
|
|
677
|
+
native_run_id=handle.run_id,
|
|
678
|
+
metadata={
|
|
679
|
+
"agent_id": str(handle.native_ref.get("agent_id") or "agent"),
|
|
680
|
+
"user_id": str(handle.native_ref.get("user_id") or "user"),
|
|
681
|
+
"session_id": handle.session_id,
|
|
682
|
+
"invocation_id": handle.run_id,
|
|
984
683
|
},
|
|
985
684
|
)
|
|
986
685
|
|
|
987
|
-
def
|
|
686
|
+
def _canonical_kwargs(
|
|
988
687
|
self,
|
|
989
688
|
handle: RunHandle,
|
|
990
|
-
event_type: str,
|
|
991
|
-
payload: dict,
|
|
992
689
|
*,
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
690
|
+
scope_id: str,
|
|
691
|
+
item_id: str,
|
|
692
|
+
event_type: str,
|
|
693
|
+
part_id: str,
|
|
694
|
+
) -> dict[str, Any]:
|
|
695
|
+
"""Build common EventEnvelope kwargs for the dict-chunk degraded path."""
|
|
696
|
+
framework = self._runtime_type
|
|
697
|
+
run_id = handle.run_id
|
|
698
|
+
# TODO(runtime-event-v2): dict chunk 退化路径,chunk_ordinal 用 seq counter;
|
|
699
|
+
# LangGraph/Codex 切 stream_canonical_events 后清理
|
|
700
|
+
n = self._next_seq()
|
|
701
|
+
return {
|
|
702
|
+
"schema_version": 2,
|
|
703
|
+
"event_id": stable_event_id(
|
|
704
|
+
framework, scope_id, item_id, event_type, part_id, run_id, n
|
|
705
|
+
),
|
|
706
|
+
"seq": n,
|
|
707
|
+
"timestamp": time.time(),
|
|
708
|
+
"run_id": run_id,
|
|
709
|
+
"scope_id": scope_id,
|
|
710
|
+
"source": self._make_source(handle),
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
def _make_run_started(self, handle: RunHandle) -> RunStarted:
|
|
714
|
+
framework = self._runtime_type
|
|
715
|
+
run_id = handle.run_id
|
|
716
|
+
scope_id = stable_scope_id(framework, run_id)
|
|
717
|
+
item_id = stable_item_id(framework, run_id, "$run")
|
|
718
|
+
return RunStarted(
|
|
719
|
+
schema_version=2,
|
|
720
|
+
event_id=stable_event_id(framework, scope_id, item_id, "run.started", "run", run_id, 0),
|
|
721
|
+
seq=self._next_seq(),
|
|
722
|
+
timestamp=time.time(),
|
|
723
|
+
run_id=run_id,
|
|
724
|
+
scope_id=scope_id,
|
|
725
|
+
source=self._make_source(handle),
|
|
726
|
+
status="running",
|
|
1004
727
|
)
|
|
1005
728
|
|
|
1006
|
-
def
|
|
729
|
+
def _make_run_completed(
|
|
1007
730
|
self,
|
|
1008
731
|
handle: RunHandle,
|
|
1009
732
|
*,
|
|
1010
|
-
|
|
733
|
+
run: Optional[_ActiveRun] = None,
|
|
1011
734
|
metrics: Mapping[str, Any] | None = None,
|
|
1012
|
-
) ->
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
735
|
+
) -> RunCompleted:
|
|
736
|
+
framework = self._runtime_type
|
|
737
|
+
run_id = handle.run_id
|
|
738
|
+
scope_id = stable_scope_id(framework, run_id)
|
|
739
|
+
item_id = stable_item_id(framework, run_id, "$run")
|
|
740
|
+
output_refs: tuple[OutputRef, ...] = ()
|
|
741
|
+
if run is not None and run.final_answer_item_id:
|
|
742
|
+
output_refs = (
|
|
743
|
+
OutputRef(
|
|
744
|
+
scope_id=scope_id,
|
|
745
|
+
item_id=run.final_answer_item_id,
|
|
746
|
+
part_id="text-0",
|
|
747
|
+
),
|
|
748
|
+
)
|
|
749
|
+
source = self._make_source(handle)
|
|
750
|
+
if metrics:
|
|
751
|
+
source = source.model_copy(
|
|
752
|
+
update={"metadata": {**source.metadata, "metrics": dict(metrics)}}
|
|
753
|
+
)
|
|
754
|
+
return RunCompleted(
|
|
755
|
+
schema_version=2,
|
|
756
|
+
event_id=stable_event_id(
|
|
757
|
+
framework, scope_id, item_id, "run.completed", "run", run_id, 0
|
|
758
|
+
),
|
|
759
|
+
seq=self._next_seq(),
|
|
760
|
+
timestamp=time.time(),
|
|
761
|
+
run_id=run_id,
|
|
762
|
+
scope_id=scope_id,
|
|
763
|
+
source=source,
|
|
764
|
+
status="completed",
|
|
765
|
+
output_refs=output_refs,
|
|
766
|
+
)
|
|
767
|
+
|
|
768
|
+
def _make_run_canceled(self, handle: RunHandle, *, reason: str | None = None) -> RunCanceled:
|
|
769
|
+
framework = self._runtime_type
|
|
770
|
+
run_id = handle.run_id
|
|
771
|
+
scope_id = stable_scope_id(framework, run_id)
|
|
772
|
+
item_id = stable_item_id(framework, run_id, "$run")
|
|
773
|
+
return RunCanceled(
|
|
774
|
+
schema_version=2,
|
|
775
|
+
event_id=stable_event_id(
|
|
776
|
+
framework, scope_id, item_id, "run.canceled", "run", run_id, 0
|
|
777
|
+
),
|
|
778
|
+
seq=self._next_seq(),
|
|
779
|
+
timestamp=time.time(),
|
|
780
|
+
run_id=run_id,
|
|
781
|
+
scope_id=scope_id,
|
|
782
|
+
source=self._make_source(handle),
|
|
783
|
+
status="canceled",
|
|
784
|
+
reason=reason,
|
|
785
|
+
)
|
|
786
|
+
|
|
787
|
+
def _make_run_interrupted(
|
|
788
|
+
self, handle: RunHandle, *, reason: str | None = None
|
|
789
|
+
) -> RunInterrupted:
|
|
790
|
+
framework = self._runtime_type
|
|
791
|
+
run_id = handle.run_id
|
|
792
|
+
scope_id = stable_scope_id(framework, run_id)
|
|
793
|
+
item_id = stable_item_id(framework, run_id, "$run")
|
|
794
|
+
return RunInterrupted(
|
|
795
|
+
schema_version=2,
|
|
796
|
+
event_id=stable_event_id(
|
|
797
|
+
framework, scope_id, item_id, "run.interrupted", "run", run_id, 0
|
|
798
|
+
),
|
|
799
|
+
seq=self._next_seq(),
|
|
800
|
+
timestamp=time.time(),
|
|
801
|
+
run_id=run_id,
|
|
802
|
+
scope_id=scope_id,
|
|
803
|
+
source=self._make_source(handle),
|
|
804
|
+
status="interrupted",
|
|
805
|
+
reason=reason,
|
|
806
|
+
)
|
|
1022
807
|
|
|
1023
808
|
@staticmethod
|
|
1024
809
|
def _coerce(value: Any) -> str:
|