agentengine-sdk-python 0.8.0__py3-none-any.whl → 0.8.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/METADATA +43 -7
- agentengine_sdk_python-0.8.2.dist-info/RECORD +778 -0
- {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/WHEEL +1 -1
- ksadk/a2a/__init__.py +2 -0
- ksadk/a2a/_space_client_events.py +381 -0
- ksadk/a2a/bootstrap.py +0 -2
- ksadk/a2a/card.py +6 -111
- ksadk/a2a/control_plane.py +239 -1
- ksadk/a2a/event_adapter.py +156 -64
- ksadk/a2a/executor.py +195 -172
- ksadk/a2a/routes.py +12 -5
- ksadk/a2a/server.py +1 -8
- ksadk/a2a/service_env.py +33 -0
- ksadk/a2a/space_client.py +43 -349
- ksadk/a2a_card.py +101 -0
- ksadk/a2ui/core.py +222 -53
- ksadk/agui/_agent_helpers.py +243 -0
- ksadk/agui/a2ui_projection.py +12 -5
- ksadk/agui/agent.py +474 -275
- ksadk/agui/config.py +11 -5
- ksadk/agui/routes.py +7 -15
- ksadk/api/client.py +530 -40
- ksadk/api/environment.py +27 -0
- ksadk/builders/code_builder.py +352 -53
- ksadk/builders/container_builder.py +71 -44
- ksadk/builders/framework_requirements.py +2 -1
- ksadk/builders/ks3_uploader.py +2 -2
- ksadk/builders/managed_runtime_builder.py +60 -28
- ksadk/cli/__init__.py +25 -0
- ksadk/cli/cmd_a2a.py +18 -31
- ksadk/cli/cmd_create.py +13 -26
- ksadk/cli/cmd_dashboard.py +15 -1
- ksadk/cli/cmd_deploy.py +28 -3
- ksadk/cli/cmd_eval.py +443 -0
- ksadk/cli/cmd_evalset.py +284 -0
- ksadk/cli/cmd_files.py +5 -1
- ksadk/cli/cmd_hermes.py +137 -163
- ksadk/cli/cmd_invoke.py +28 -38
- ksadk/cli/cmd_launch.py +12 -0
- ksadk/cli/cmd_managed_runtime.py +95 -0
- ksadk/cli/cmd_observe.py +85 -0
- ksadk/cli/cmd_openclaw.py +85 -479
- ksadk/cli/cmd_replay.py +28 -4
- ksadk/cli/cmd_run.py +29 -67
- ksadk/cli/cmd_studio.py +201 -0
- ksadk/cli/cmd_web.py +15 -6
- ksadk/cli/dry_run.py +2 -1
- ksadk/cli/env_options.py +83 -0
- ksadk/cli/global_options.py +3 -1
- ksadk/cli/hermes_env.py +151 -0
- ksadk/cli/invoke_payload.py +49 -0
- ksadk/cli/network_options.py +7 -5
- ksadk/cli/openclaw_env.py +458 -0
- ksadk/cli/runtime_bootstrap.py +51 -0
- ksadk/cli/ui.py +6 -0
- ksadk/cli/workflow_common.py +5 -5
- ksadk/codex/__init__.py +3 -3
- ksadk/codex/client.py +833 -49
- ksadk/codex/phase.py +1 -1
- ksadk/codex/runtime.py +720 -127
- ksadk/common/kop_client.py +232 -0
- ksadk/configs/__init__.py +1 -3
- ksadk/configs/env_registry.py +244 -45
- ksadk/configs/env_registry_pcm.py +181 -0
- ksadk/configs/env_var_spec.py +18 -0
- ksadk/configs/global_config.py +6 -1
- ksadk/configs/settings.py +5 -108
- 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 +344 -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 +85 -94
- ksadk/conversations/context.py +126 -6
- ksadk/conversations/message_projection.py +292 -28
- ksadk/conversations/model_context.py +49 -3
- ksadk/conversations/runtime_compaction.py +207 -5
- ksadk/conversations/runtime_input.py +193 -3
- ksadk/conversations/runtime_invocation.py +81 -3
- ksadk/conversations/runtime_observability.py +157 -4
- ksadk/conversations/runtime_payloads.py +42 -0
- ksadk/conversations/runtime_preparation.py +280 -2
- ksadk/conversations/runtime_resume.py +71 -32
- ksadk/conversations/runtime_stream_events.py +94 -9
- ksadk/conversations/runtime_streaming.py +175 -22
- 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 +38 -0
- ksadk/deployment/manager.py +24 -8
- ksadk/deployment/providers/serverless.py +228 -92
- ksadk/evaluation/__init__.py +116 -0
- ksadk/evaluation/a2a_adapter.py +452 -0
- ksadk/evaluation/adapters.py +67 -0
- 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 +478 -0
- ksadk/evaluation/evalset.py +351 -0
- ksadk/evaluation/evaluators.py +627 -0
- ksadk/evaluation/evidence.py +258 -0
- ksadk/evaluation/executor.py +143 -0
- ksadk/evaluation/local_adapter.py +550 -0
- ksadk/evaluation/service_env.py +27 -0
- ksadk/evaluation/storage.py +68 -0
- ksadk/evaluation/studio_build_adapter.py +253 -0
- ksadk/evaluation/target.py +82 -0
- 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 +753 -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 +717 -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 -256
- ksadk/events/session_event.py +324 -0
- ksadk/events/store.py +3 -316
- ksadk/events/v1_compat.py +41 -0
- ksadk/harness/__init__.py +3 -2
- ksadk/harness/app.py +114 -123
- ksadk/harness/config.py +1 -1
- ksadk/harness/runtime.py +467 -0
- ksadk/hermes_terminal.py +5 -0
- 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 +61 -0
- ksadk/kernel/contracts.py +362 -0
- ksadk/kernel/control.py +219 -0
- ksadk/kernel/errors.py +79 -0
- ksadk/kernel/ingress.py +1102 -0
- ksadk/kernel/mapping.py +111 -0
- ksadk/kernel/memory_store.py +1133 -0
- ksadk/kernel/postgres_store.py +1756 -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 +1410 -0
- ksadk/kernel/state.py +145 -0
- ksadk/kernel/store.py +232 -0
- ksadk/kernel/worker.py +953 -0
- ksadk/knowledge_base/client.py +22 -4
- ksadk/knowledge_base/service.py +32 -5
- ksadk/managed_a2a_card.py +160 -0
- ksadk/managed_runtime.py +16 -9
- 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 +394 -5
- ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
- ksadk/memory/adk/long_term_memory.py +3 -2
- 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 +490 -0
- ksadk/memory/resolved_policy.py +145 -0
- ksadk/memory/service.py +198 -8
- ksadk/memory/tool.py +4 -0
- ksadk/model_proxy/bootstrap.py +16 -9
- ksadk/model_proxy/config.py +22 -1
- ksadk/model_proxy/detect.py +202 -9
- ksadk/model_proxy/namespace.py +67 -15
- ksadk/model_proxy/server.py +168 -6
- ksadk/model_proxy/transform.py +105 -3
- ksadk/observability/__init__.py +25 -0
- ksadk/observability/session_log.py +420 -0
- ksadk/observability/trajectory.py +105 -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 +14 -31
- ksadk/runners/base_runner.py +44 -3
- ksadk/runners/factory.py +3 -3
- ksadk/runners/langgraph_runner.py +252 -433
- ksadk/runners/utils/__init__.py +0 -10
- ksadk/runners/utils/loader.py +16 -0
- ksadk/runtime/__init__.py +67 -41
- ksadk/runtime/_runner_adapter/__init__.py +1 -0
- ksadk/runtime/_runner_adapter/stream_mapping.py +788 -0
- ksadk/runtime/adapter.py +199 -16
- ksadk/runtime/conversation_execution.py +687 -0
- ksadk/runtime/executor.py +392 -0
- ksadk/runtime/factory.py +342 -0
- ksadk/runtime/framework_adapters.py +6 -12
- ksadk/runtime/hosted_finalizer.py +268 -0
- ksadk/runtime/launch.py +61 -0
- ksadk/runtime/preprocessing.py +49 -14
- ksadk/runtime/runner_adapter.py +330 -391
- ksadk/runtime/runner_loading.py +36 -0
- ksadk/runtime/usage.py +33 -0
- ksadk/sandbox/backends/e2b.py +36 -3
- ksadk/server/__init__.py +39 -4
- ksadk/server/app.py +18 -492
- ksadk/server/composition.py +36 -2
- ksadk/server/factory.py +210 -149
- ksadk/server/routes/common.py +15 -46
- ksadk/server/routes/control.py +13 -9
- ksadk/server/routes/kernel_ingress.py +258 -0
- ksadk/server/routes/misc.py +10 -33
- ksadk/server/routes/models.py +14 -6
- ksadk/server/routes/openai_compat.py +129 -27
- ksadk/server/routes/projection.py +84 -16
- ksadk/server/routes/run.py +347 -460
- ksadk/server/routes/sessions.py +37 -40
- ksadk/server/routes/streaming.py +52 -7
- ksadk/server/routes/workspace.py +54 -21
- ksadk/server/static/assets/{ArtifactsPanel-Cjnqt-8W.js → ArtifactsPanel-DSU1sWD_.js} +1 -1
- ksadk/server/static/assets/{CodeBlock-BqyqZfuB.js → CodeBlock-DOH6MVcn.js} +4 -4
- ksadk/server/static/assets/{MathMessageMarkdown-BpH7jiFM.js → MathMessageMarkdown-BL8my1R2.js} +4 -4
- ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
- ksadk/server/static/assets/MermaidBlock-Dz4IP-Tx.js +312 -0
- ksadk/server/static/assets/NativeTerminalPanel-DUrK0JpZ.js +1 -0
- ksadk/server/static/assets/abnfDiagram-VCTEODGH-g20pFzNV.js +1 -0
- ksadk/server/static/assets/arc-C4FzinUA.js +1 -0
- ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +1 -0
- ksadk/server/static/assets/architectureDiagram-5GKGNRK7-DpIqL5h4.js +36 -0
- ksadk/server/static/assets/blockDiagram-NRAW4CY4-BjkljTNz.js +129 -0
- ksadk/server/static/assets/c4Diagram-UCG6FXSJ-Dk_ieq2X.js +38 -0
- ksadk/server/static/assets/channel-4cQHKtx1.js +1 -0
- ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +1 -0
- ksadk/server/static/assets/{chunk-FMBD7UC4-BGhvzDYt.js → chunk-5VM5RSS4-BVHAchFb.js} +1 -1
- ksadk/server/static/assets/{chunk-ND2GUHAM-D98vPd-E.js → chunk-F27PBJKO-C-ipQzuS.js} +1 -1
- ksadk/server/static/assets/chunk-G27WJ6UU-C2EyJbIK.js +231 -0
- ksadk/server/static/assets/{chunk-4BX2VUAB-CsWIQRhc.js → chunk-JWPE2WC7-vYvVJb_M.js} +1 -1
- ksadk/server/static/assets/chunk-LCL6LL3I-BcI6ysPT.js +206 -0
- ksadk/server/static/assets/chunk-POPQ4Y6H-C030x_Z1.js +1 -0
- ksadk/server/static/assets/chunk-RHFEMEQ7-yyGpsz4n.js +168 -0
- ksadk/server/static/assets/chunk-SVP7TREG-BLTlmMU7.js +88 -0
- ksadk/server/static/assets/chunk-XXDRQBXY-C_32ArgP.js +1 -0
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +1 -0
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +1 -0
- ksadk/server/static/assets/{cose-bilkent-S5V4N54A-CX3yotHq.js → cose-bilkent-JH36ORCC-9YQYwdl0.js} +1 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +1 -0
- ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-ErLF5N13.js +62 -0
- ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
- ksadk/server/static/assets/dagre-3AP2YEHR-DFiQF-6f.js +4 -0
- ksadk/server/static/assets/dagre-BuhGnRI1.js +1 -0
- ksadk/server/static/assets/diagram-S7CK7UJ4-Bt1v8-GC.js +30 -0
- ksadk/server/static/assets/diagram-UQ7AKVKN-DSCxJdBK.js +41 -0
- ksadk/server/static/assets/diagram-VSXAHHWV-DHfYwp_9.js +3 -0
- ksadk/server/static/assets/diagram-VX7I27RA-DdzD-4Le.js +24 -0
- ksadk/server/static/assets/diagram-Z3DM3KII-Du-nAJ9F.js +24 -0
- ksadk/server/static/assets/{dist-D82mtD2s.js → dist-8hqcx0sU.js} +1 -1
- ksadk/server/static/assets/dist-B7seoj3d.js +1 -0
- ksadk/server/static/assets/{dist-DHn6nBzr.js → dist-BE7bu-DL.js} +1 -1
- ksadk/server/static/assets/{dist-eoW6tZXA.js → dist-BVDffZ0U.js} +1 -1
- ksadk/server/static/assets/{dist-C2xjE7cO.js → dist-BX8z72IC.js} +1 -1
- ksadk/server/static/assets/{dist-CgF3fj15.js → dist-Bf2M8m3N.js} +1 -1
- ksadk/server/static/assets/{dist-Bs-jQcRX.js → dist-BjU6y-A2.js} +1 -1
- ksadk/server/static/assets/{dist-Djgl2wVZ.js → dist-BytlxIDT.js} +1 -1
- ksadk/server/static/assets/{dist-CVQRZjPu.js → dist-CSh_DE14.js} +1 -1
- ksadk/server/static/assets/{dist-6CVKuTAe.js → dist-CXYYBw3_.js} +1 -1
- ksadk/server/static/assets/{dist-DlzCRy0S.js → dist-C_wsv-Qd.js} +1 -1
- ksadk/server/static/assets/{dist-DF06ORQo.js → dist-ClxGviKw.js} +1 -1
- ksadk/server/static/assets/{dist-Cf23NY4L.js → dist-CttYUqzS.js} +1 -1
- ksadk/server/static/assets/{dist-ivOya1LD.js → dist-DNp6rLRA.js} +1 -1
- ksadk/server/static/assets/{dist-BibcG1V9.js → dist-DUX-id_F.js} +1 -1
- ksadk/server/static/assets/{dist-BUHRxvDG.js → dist-DmldrHd_.js} +1 -1
- ksadk/server/static/assets/{dist-BZ9n9AjO.js → dist-DnfXs8Vn.js} +2 -2
- ksadk/server/static/assets/{dist-DqNnNFrw.js → dist-Dq9gLD7L.js} +1 -1
- ksadk/server/static/assets/{dist-CGcp2ex8.js → dist-W-TIVntx.js} +1 -1
- ksadk/server/static/assets/{dist-Cwt7koer.js → dist-dDdADKFA.js} +1 -1
- ksadk/server/static/assets/{dist-C7-3jInC.js → dist-dydu68Fl.js} +1 -1
- ksadk/server/static/assets/{dist-C99THtIA.js → dist-ngtN0DJB.js} +1 -1
- ksadk/server/static/assets/ebnfDiagram-PWID7BFC-Da9C9NO1.js +1 -0
- ksadk/server/static/assets/erDiagram-SSCWMZ5O-EAGqqR79.js +99 -0
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +1 -0
- ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +1 -0
- ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-DqJsKb59.js +292 -0
- ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +1 -0
- ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-B6g4dtDi.js +106 -0
- ksadk/server/static/assets/index-8ipRcQ-M.js +240 -0
- ksadk/server/static/assets/index-ByFCqjlh.css +2 -0
- ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +1 -0
- ksadk/server/static/assets/infoDiagram-RXCK75RN-Djm_nbd5.js +2 -0
- ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-DLOHGvWw.js → ishikawaDiagram-5VMMS53U-DWya9SG2.js} +6 -6
- ksadk/server/static/assets/{journeyDiagram-JHISSGLW-BIzKeejT.js → journeyDiagram-EYS64GPL-DutxhSNI.js} +6 -6
- ksadk/server/static/assets/{kanban-definition-UN3LZRKU-BWHoFSw2.js → kanban-definition-3QL26DDD-DJdOF8Fm.js} +10 -10
- ksadk/server/static/assets/katex-vFWytM5c.js +257 -0
- ksadk/server/static/assets/{linear-CvMBw9cA.js → linear-BHjG8b-J.js} +1 -1
- ksadk/server/static/assets/mermaid-parser.core-KGSy4jWT.js +166 -0
- ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-CSAQxEAe.js → mindmap-definition-FBJOCRG2-9-HC88D4.js} +29 -29
- ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +1 -0
- ksadk/server/static/assets/pegDiagram-XKGWAZYB-DrEZd4fD.js +1 -0
- ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +1 -0
- ksadk/server/static/assets/pieDiagram-E7YTZNPT-DpjqOFFp.js +39 -0
- ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-CxIR4JXI.js → quadrantDiagram-AXDQQJYC-BiNhgOXX.js} +6 -6
- ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +1 -0
- ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +1 -0
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +1 -0
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +1 -0
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +1 -0
- ksadk/server/static/assets/railroadDiagram-O6MQD6OU-_Y3Ojg6G.js +1 -0
- ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-DeCFdg9K.js +84 -0
- ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-DpGa6EAV.js → sankeyDiagram-P5KCCOFB-CPH75rhw.js} +7 -7
- ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-NTKNGGe5.js → sequenceDiagram-WJ2MYXX4-OEpQQdr4.js} +10 -10
- ksadk/server/static/assets/sizeCapture-X5ZJPWSS-heUErzhI.js +1 -0
- ksadk/server/static/assets/stateDiagram-HBIQ2CUA-DvA3jSMB.js +1 -0
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +1 -0
- ksadk/server/static/assets/swimlanes-XN3QIQJK-CR-dfN_t.js +1 -0
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +8 -0
- ksadk/server/static/assets/{timeline-definition-PNZ67QCA-jqoYs3jQ.js → timeline-definition-24CTP7MA-DAVJf1TX.js} +7 -7
- ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +1 -0
- ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +1 -0
- ksadk/server/static/assets/vennDiagram-4TSXK5OY-DwM8eDkh.js +34 -0
- ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +1 -0
- ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DZL-Zz2t.js +78 -0
- ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-Dy6Yh_hu.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/runtime/backends/e2b.py +1 -1
- ksadk/skills/service_client.py +13 -3
- 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 +1598 -0
- ksadk/studio/api_catalog_routes.py +324 -0
- ksadk/studio/api_contracts.py +286 -0
- ksadk/studio/api_helpers.py +132 -0
- ksadk/studio/api_memory_routes.py +82 -0
- ksadk/studio/authoring.py +749 -0
- ksadk/studio/authoring_coordinator.py +1017 -0
- ksadk/studio/builder.py +397 -0
- ksadk/studio/capabilities.py +368 -0
- ksadk/studio/cloud.py +2099 -0
- ksadk/studio/codex_agent_service.py +694 -0
- ksadk/studio/codex_authoring.py +469 -0
- ksadk/studio/codex_builder.py +437 -0
- ksadk/studio/codex_manifest.py +307 -0
- ksadk/studio/codex_run.py +395 -0
- ksadk/studio/compiler.py +190 -0
- ksadk/studio/contracts.py +755 -0
- ksadk/studio/errors.py +47 -0
- ksadk/studio/event_store.py +214 -0
- ksadk/studio/framework_run.py +342 -0
- ksadk/studio/hosted_kernel.py +317 -0
- ksadk/studio/identifiers.py +33 -0
- ksadk/studio/manifest_resolver.py +131 -0
- ksadk/studio/mcp_runtime.py +229 -0
- ksadk/studio/model_client.py +629 -0
- ksadk/studio/model_profile_service.py +214 -0
- ksadk/studio/operations.py +275 -0
- ksadk/studio/otel_trace.py +1060 -0
- ksadk/studio/pagination.py +182 -0
- ksadk/studio/pcm_memory.py +85 -0
- ksadk/studio/python_tool_inspection.py +183 -0
- ksadk/studio/repository.py +327 -0
- ksadk/studio/resource_catalog.py +1260 -0
- ksadk/studio/run_service.py +1133 -0
- ksadk/studio/runtime_catalog.py +74 -0
- ksadk/studio/runtime_source.py +365 -0
- ksadk/studio/service.py +2249 -0
- ksadk/studio/shared_web.py +1004 -0
- ksadk/studio/skill_discovery.py +628 -0
- ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +3 -0
- ksadk/studio/static/assets/index-BLpcdrgW.css +1 -0
- ksadk/studio/static/assets/index-CYekR2Xv.js +260 -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 +722 -0
- ksadk/studio/validator.py +265 -0
- ksadk/studio/workspace.py +135 -0
- ksadk/tools/gateway.py +9 -0
- ksadk/toolsets/__init__.py +27 -1
- ksadk/toolsets/a2a.py +426 -0
- ksadk/tracing/__init__.py +19 -21
- ksadk/tracing/setup.py +317 -403
- ksadk/tracing/span_utils.py +0 -44
- ksadk/version.py +1 -1
- ksadk_runtime_common/memory_backend/registry.py +56 -56
- 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/router.py +8 -2
- agentengine_sdk_python-0.8.0.dist-info/RECORD +0 -578
- ksadk/a2a/card_builder.py +0 -64
- ksadk/a2a/client.py +0 -309
- ksadk/events/parser.py +0 -191
- ksadk/harness/runner.py +0 -211
- ksadk/runners/codex_runner.py +0 -132
- ksadk/runners/utils/langfuse.py +0 -230
- ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
- ksadk/server/static/assets/MermaidBlock-DWuxETaJ.js +0 -303
- ksadk/server/static/assets/NativeTerminalPanel-MDTopWMO.js +0 -1
- ksadk/server/static/assets/arc-CFKwSk_B.js +0 -1
- ksadk/server/static/assets/architecture-7EHR7CIX-CynqOWjZ.js +0 -1
- ksadk/server/static/assets/architectureDiagram-3BPJPVTR-Dej8jX8c.js +0 -36
- ksadk/server/static/assets/blockDiagram-GPEHLZMM-1F64jqvy.js +0 -132
- ksadk/server/static/assets/c4Diagram-AAUBKEIU-9q7AUAKb.js +0 -10
- ksadk/server/static/assets/channel-iUGv2N24.js +0 -1
- ksadk/server/static/assets/chunk-2J33WTMH-6qgwJm7Q.js +0 -1
- ksadk/server/static/assets/chunk-55IACEB6-BK8paA20.js +0 -1
- ksadk/server/static/assets/chunk-727SXJPM-B-JEhy7h.js +0 -206
- ksadk/server/static/assets/chunk-AQP2D5EJ-DYBvMHAa.js +0 -231
- ksadk/server/static/assets/chunk-QZHKN3VN-YQIEXeF6.js +0 -1
- ksadk/server/static/assets/classDiagram-4FO5ZUOK-CDAUuoXK.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-CDAUuoXK.js +0 -1
- ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
- ksadk/server/static/assets/dagre-BM42HDAG-C7TguAWo.js +0 -4
- ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
- ksadk/server/static/assets/diagram-2AECGRRQ-Dd17_kws.js +0 -43
- ksadk/server/static/assets/diagram-5GNKFQAL-DVIClIil.js +0 -10
- ksadk/server/static/assets/diagram-KO2AKTUF-Df_3gYQa.js +0 -3
- ksadk/server/static/assets/diagram-LMA3HP47-BhLk6ZtA.js +0 -24
- ksadk/server/static/assets/diagram-OG6HWLK6-D4GNGvuu.js +0 -24
- ksadk/server/static/assets/dist-DyvYLMW9.js +0 -1
- ksadk/server/static/assets/erDiagram-TEJ5UH35-CnfRcY2M.js +0 -85
- ksadk/server/static/assets/eventmodeling-FCH6USID-ChYO-ijM.js +0 -1
- ksadk/server/static/assets/flowDiagram-I6XJVG4X-DGaJjGNJ.js +0 -162
- ksadk/server/static/assets/ganttDiagram-6RSMTGT7-DpCoB2g9.js +0 -292
- ksadk/server/static/assets/gitGraph-WXDBUCRP-BN_0Fk-j.js +0 -1
- ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-9IKVFBVT.js +0 -106
- ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
- ksadk/server/static/assets/index-QSwCHuB8.js +0 -177
- ksadk/server/static/assets/index-jOPmTOZH.css +0 -2
- ksadk/server/static/assets/info-J43DQDTF-Cp6o3vId.js +0 -1
- ksadk/server/static/assets/infoDiagram-5YYISTIA-CYIIsb8y.js +0 -2
- ksadk/server/static/assets/katex-DATssjp1.js +0 -265
- ksadk/server/static/assets/mermaid-parser.core-mGAcEwcq.js +0 -161
- ksadk/server/static/assets/packet-YPE3B663-wQzct3cT.js +0 -1
- ksadk/server/static/assets/pie-LRSECV5Y-BgTQiv-9.js +0 -1
- ksadk/server/static/assets/pieDiagram-4H26LBE5-By-ra07M.js +0 -30
- ksadk/server/static/assets/radar-GUYGQ44K-BIq5fXsn.js +0 -1
- ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DpW90iu3.js +0 -84
- ksadk/server/static/assets/stateDiagram-AJRCARHV-DGpd9yFG.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-B3o579IQ.js +0 -1
- ksadk/server/static/assets/treeView-BLDUP644-Dqi-E0EM.js +0 -1
- ksadk/server/static/assets/treemap-LRROVOQU-ClQP9CJ9.js +0 -1
- ksadk/server/static/assets/vennDiagram-CIIHVFJN-l3Z7-wbP.js +0 -34
- ksadk/server/static/assets/wardley-L42UT6IY-8XLvnNIs.js +0 -1
- ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-BR54GPmr.js +0 -78
- ksadk/server/static/assets/xychartDiagram-2RQKCTM6-SkiH8GsK.js +0 -7
- ksadk/tracing/exporters/langfuse_exporter.py +0 -460
- {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/top_level.txt +0 -0
ksadk/runtime/runner_adapter.py
CHANGED
|
@@ -13,24 +13,35 @@ 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 (
|
|
44
|
+
RESUME_START_REQUEST_NATIVE_KEY,
|
|
34
45
|
BaseRuntime,
|
|
35
46
|
CancelResult,
|
|
36
47
|
CheckpointCapability,
|
|
@@ -42,78 +53,22 @@ from ksadk.runtime.adapter import (
|
|
|
42
53
|
StartRequest,
|
|
43
54
|
)
|
|
44
55
|
from ksadk.runtime.preprocessing import PreparedRuntimeStart, prepare_runtime_start
|
|
45
|
-
from ksadk.
|
|
56
|
+
from ksadk.runtime.runner_loading import ensure_runner_loaded
|
|
46
57
|
|
|
47
58
|
logger = logging.getLogger(__name__)
|
|
48
59
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
async def _anext_or_stop(gen: AsyncIterator[Any]) -> Any:
|
|
54
|
-
"""取下一个 chunk;流结束返回 _STREAM_STOP sentinel(便于竞速)。"""
|
|
55
|
-
try:
|
|
56
|
-
return await gen.__anext__()
|
|
57
|
-
except StopAsyncIteration:
|
|
58
|
-
return _STREAM_STOP
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def _a2ui_surface_event(chunk: Any) -> tuple[str, dict[str, Any]] | None:
|
|
62
|
-
"""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
|
+
)
|
|
63
64
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
"""
|
|
65
|
+
# dict-chunk 退化路径的流竞速/事件映射实现拆至 _runner_adapter 子包(纯移动,行为不变)。
|
|
66
|
+
from ksadk.runtime._runner_adapter.stream_mapping import ( # noqa: E402
|
|
67
|
+
_STREAM_STOP,
|
|
68
|
+
_RunnerStreamMappingMixin,
|
|
69
|
+
)
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
return None
|
|
73
|
-
value = chunk.get("tool_output", chunk.get("output"))
|
|
74
|
-
if value is not None and hasattr(value, "content"):
|
|
75
|
-
value = value.content
|
|
76
|
-
if isinstance(value, str):
|
|
77
|
-
try:
|
|
78
|
-
value = json.loads(value)
|
|
79
|
-
except (TypeError, ValueError):
|
|
80
|
-
return None
|
|
81
|
-
if not isinstance(value, Mapping):
|
|
82
|
-
return None
|
|
83
|
-
operations_raw = value.get("a2ui_operations")
|
|
84
|
-
if not isinstance(operations_raw, list) or not operations_raw:
|
|
85
|
-
return None
|
|
86
|
-
operations = [dict(operation) for operation in operations_raw if isinstance(operation, Mapping)]
|
|
87
|
-
if not operations:
|
|
88
|
-
return None
|
|
89
|
-
|
|
90
|
-
known: list[tuple[str, str]] = []
|
|
91
|
-
for operation in operations:
|
|
92
|
-
for key, event_type in (
|
|
93
|
-
("createSurface", EventType.A2UI_SURFACE_BEGIN),
|
|
94
|
-
("updateComponents", EventType.A2UI_SURFACE_UPDATE),
|
|
95
|
-
("updateDataModel", EventType.A2UI_SURFACE_UPDATE),
|
|
96
|
-
("deleteSurface", EventType.A2UI_SURFACE_END),
|
|
97
|
-
):
|
|
98
|
-
detail = operation.get(key)
|
|
99
|
-
if isinstance(detail, Mapping) and isinstance(detail.get("surfaceId"), str):
|
|
100
|
-
surface_id = detail["surfaceId"].strip()
|
|
101
|
-
if surface_id:
|
|
102
|
-
known.append((surface_id, event_type))
|
|
103
|
-
break
|
|
104
|
-
if not known:
|
|
105
|
-
return None
|
|
106
|
-
surface_ids = {surface_id for surface_id, _event_type in known}
|
|
107
|
-
if len(surface_ids) != 1:
|
|
108
|
-
logger.warning("ignoring A2UI tool result with multiple surfaces")
|
|
109
|
-
return None
|
|
110
|
-
surface_id = known[0][0]
|
|
111
|
-
event_type = (
|
|
112
|
-
EventType.A2UI_SURFACE_BEGIN
|
|
113
|
-
if any(kind == EventType.A2UI_SURFACE_BEGIN for _surface_id, kind in known)
|
|
114
|
-
else known[0][1]
|
|
115
|
-
)
|
|
116
|
-
return event_type, {"surface_id": surface_id, "operations": operations}
|
|
71
|
+
_ResumeKey = tuple[str, str, str, str, str]
|
|
117
72
|
|
|
118
73
|
|
|
119
74
|
def _coerce_literal(value: Any, allowed: tuple[str, ...], default: str) -> Any:
|
|
@@ -157,9 +112,14 @@ class _ActiveRun:
|
|
|
157
112
|
resume_fingerprint: Any = None
|
|
158
113
|
skip_runner: bool = False
|
|
159
114
|
done: bool = False
|
|
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
|
|
160
120
|
|
|
161
121
|
|
|
162
|
-
class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
122
|
+
class RunnerRuntimeAdapter(_RunnerStreamMappingMixin, RuntimeAdapter):
|
|
163
123
|
"""把 ``BaseRunner`` 映射为平台六动词的通用 adapter。"""
|
|
164
124
|
|
|
165
125
|
def __init__(self, runner: BaseRunner, *, runtime_type: str) -> None:
|
|
@@ -178,6 +138,63 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
178
138
|
|
|
179
139
|
# ---- 框架钩子(子类按需 override) ----
|
|
180
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
|
+
)
|
|
189
|
+
|
|
190
|
+
async def durable_restore(self, handle: RunHandle) -> RunHandle:
|
|
191
|
+
if not self.capabilities().durable_restore.supported:
|
|
192
|
+
raise UnsupportedControlError(
|
|
193
|
+
f"{self._runtime_type} has no cross-process checkpoint backend for run "
|
|
194
|
+
f"{handle.run_id!r}"
|
|
195
|
+
)
|
|
196
|
+
return await self.attach(handle)
|
|
197
|
+
|
|
181
198
|
def _checkpoint_capability(self) -> CheckpointCapability:
|
|
182
199
|
"""诚实暴露 checkpoint 粒度。默认读 runner.describe_checkpoint_capability。"""
|
|
183
200
|
raw = {}
|
|
@@ -230,7 +247,13 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
230
247
|
|
|
231
248
|
# ---- 六动词 ----
|
|
232
249
|
|
|
250
|
+
async def preflight(self) -> None:
|
|
251
|
+
"""Load the framework agent before a streaming HTTP response commits."""
|
|
252
|
+
|
|
253
|
+
ensure_runner_loaded(self._runner, runtime_type=self._runtime_type)
|
|
254
|
+
|
|
233
255
|
async def start(self, request: StartRequest) -> RunHandle:
|
|
256
|
+
ensure_runner_loaded(self._runner, runtime_type=self._runtime_type)
|
|
234
257
|
run_id = str(request.metadata.get("invocation_id") or self._next_invocation_id())
|
|
235
258
|
prepared_start = await prepare_runtime_start(request, self._runner)
|
|
236
259
|
handle = RunHandle(
|
|
@@ -275,7 +298,7 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
275
298
|
)
|
|
276
299
|
attach = getattr(self._runner, "attach_runtime_handle", None)
|
|
277
300
|
if not callable(attach):
|
|
278
|
-
raise
|
|
301
|
+
raise UnsupportedControlError(
|
|
279
302
|
f"runner for {self._runtime_type!r} has no durable "
|
|
280
303
|
"attach_runtime_handle capability"
|
|
281
304
|
)
|
|
@@ -336,6 +359,12 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
336
359
|
return handle
|
|
337
360
|
self._require_native_checkpoint_capability()
|
|
338
361
|
self._known_runs.add(handle.run_id)
|
|
362
|
+
prepared_start: PreparedRuntimeStart | None = None
|
|
363
|
+
raw_start_request = handle.native_ref.pop(RESUME_START_REQUEST_NATIVE_KEY, None)
|
|
364
|
+
if isinstance(raw_start_request, Mapping):
|
|
365
|
+
prepared_start = await prepare_runtime_start(
|
|
366
|
+
StartRequest.model_validate(raw_start_request), self._runner
|
|
367
|
+
)
|
|
339
368
|
# _resume_native 返回的 runner_input 覆盖存到 run 上,下一次 stream() 经
|
|
340
369
|
# _build_runner_input 消费,以框架原生方式真驱动恢复。
|
|
341
370
|
override = await self._resume_native(handle, target, payload)
|
|
@@ -380,6 +409,8 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
380
409
|
resume_key=resume_key,
|
|
381
410
|
resume_fingerprint=resume_fingerprint,
|
|
382
411
|
)
|
|
412
|
+
if prepared_start is not None:
|
|
413
|
+
run.__dict__["_prepared_start"] = prepared_start
|
|
383
414
|
if override:
|
|
384
415
|
run.__dict__["_resume_input_override"] = override
|
|
385
416
|
self._resume_decisions[resume_key] = resume_fingerprint
|
|
@@ -390,7 +421,7 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
390
421
|
capability = self._require_native_checkpoint_capability()
|
|
391
422
|
checkpoint_id = str(handle.native_ref.get("checkpoint_id") or "").strip()
|
|
392
423
|
if not checkpoint_id:
|
|
393
|
-
raise
|
|
424
|
+
raise UnsupportedControlError(
|
|
394
425
|
f"{self._runtime_type} runner has no native checkpoint for run "
|
|
395
426
|
f"{handle.run_id!r}"
|
|
396
427
|
)
|
|
@@ -407,7 +438,7 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
407
438
|
if capability.supported:
|
|
408
439
|
return capability
|
|
409
440
|
detail = capability.reason or "runner does not expose framework checkpoints"
|
|
410
|
-
raise
|
|
441
|
+
raise UnsupportedControlError(
|
|
411
442
|
f"{self._runtime_type} native checkpoint capability is unavailable: {detail}"
|
|
412
443
|
)
|
|
413
444
|
|
|
@@ -477,30 +508,19 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
477
508
|
# 消费 pending cancel:start 时若已记 pending,立即中断该 turn。
|
|
478
509
|
if handle.run_id in self._pending_cancels:
|
|
479
510
|
self._pending_cancels.discard(handle.run_id)
|
|
480
|
-
yield self.
|
|
481
|
-
handle,
|
|
482
|
-
EventType.RUN_CANCELED,
|
|
483
|
-
{
|
|
484
|
-
"status": "cancelled",
|
|
485
|
-
"cancel_result": CancelResult.PENDING_CANCEL_RECORDED.value,
|
|
486
|
-
},
|
|
487
|
-
)
|
|
511
|
+
yield self._make_run_canceled(handle, reason=CancelResult.PENDING_CANCEL_RECORDED.value)
|
|
488
512
|
return
|
|
489
513
|
|
|
490
514
|
if run.skip_runner:
|
|
491
515
|
run.done = True
|
|
492
516
|
self._active_runs.pop(handle.run_id, None)
|
|
493
|
-
yield self.
|
|
494
|
-
handle,
|
|
495
|
-
EventType.RUN_COMPLETED,
|
|
496
|
-
{"status": "already_resumed"},
|
|
497
|
-
)
|
|
517
|
+
yield self._make_run_completed(handle)
|
|
498
518
|
return
|
|
499
519
|
|
|
500
520
|
if run.resume_key is not None:
|
|
501
521
|
self._consumed_resumes.add(run.resume_key)
|
|
502
522
|
|
|
503
|
-
yield self.
|
|
523
|
+
yield self._make_run_started(handle)
|
|
504
524
|
|
|
505
525
|
request = run.__dict__.get("_start_request")
|
|
506
526
|
runner_input = self._build_runner_input(handle, request)
|
|
@@ -512,35 +532,35 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
512
532
|
run.stream = gen
|
|
513
533
|
async for event in gen:
|
|
514
534
|
yield event
|
|
515
|
-
if event.event_type ==
|
|
535
|
+
if event.event_type == "interaction.requested":
|
|
516
536
|
approval_interrupted = True
|
|
537
|
+
# Track pending approval for canonical streams that bypass
|
|
538
|
+
# _chunk_to_event (e.g. stream_canonical_events).
|
|
539
|
+
if isinstance(event, InteractionRequested):
|
|
540
|
+
call_id = str(event.interaction_id or "")
|
|
541
|
+
if call_id:
|
|
542
|
+
run.pending_approvals.add(call_id)
|
|
543
|
+
pending_ids = handle.native_ref.setdefault("pending_approval_ids", [])
|
|
544
|
+
if call_id not in pending_ids:
|
|
545
|
+
pending_ids.append(call_id)
|
|
517
546
|
if event.event_type in {
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
547
|
+
"run.completed",
|
|
548
|
+
"run.failed",
|
|
549
|
+
"run.canceled",
|
|
550
|
+
"run.interrupted",
|
|
522
551
|
}:
|
|
523
552
|
terminal_event_seen = True
|
|
524
|
-
if event.event_type in {
|
|
553
|
+
if event.event_type in {"run.failed", "run.canceled"}:
|
|
525
554
|
return
|
|
526
555
|
|
|
527
556
|
if run.interrupt_event.is_set() and not terminal_event_seen:
|
|
528
|
-
yield self.
|
|
529
|
-
handle,
|
|
530
|
-
EventType.RUN_CANCELED,
|
|
531
|
-
{
|
|
532
|
-
"status": "cancelled",
|
|
533
|
-
"cancel_result": CancelResult.INTERRUPTED_ACTIVE_TURN.value,
|
|
534
|
-
},
|
|
557
|
+
yield self._make_run_canceled(
|
|
558
|
+
handle, reason=CancelResult.INTERRUPTED_ACTIVE_TURN.value
|
|
535
559
|
)
|
|
536
560
|
elif approval_interrupted and not terminal_event_seen:
|
|
537
|
-
yield self.
|
|
538
|
-
handle,
|
|
539
|
-
EventType.RUN_INTERRUPTED,
|
|
540
|
-
{"status": "input_required"},
|
|
541
|
-
)
|
|
561
|
+
yield self._make_run_interrupted(handle, reason="input_required")
|
|
542
562
|
elif not terminal_event_seen:
|
|
543
|
-
yield self.
|
|
563
|
+
yield self._make_run_completed(handle, run=run, metrics=run.completion_metrics)
|
|
544
564
|
finally:
|
|
545
565
|
run.stream = None
|
|
546
566
|
run.done = True
|
|
@@ -551,19 +571,30 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
551
571
|
# 直接作为 runner 输入,驱动框架原生恢复。
|
|
552
572
|
run = self._active_runs.get(handle.run_id)
|
|
553
573
|
override = run.__dict__.get("_resume_input_override") if run is not None else None
|
|
574
|
+
prepared_start = run.__dict__.get("_prepared_start") if run is not None else None
|
|
554
575
|
if override is not None:
|
|
555
|
-
merged =
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
576
|
+
merged = (
|
|
577
|
+
dict(prepared_start.runner_input)
|
|
578
|
+
if isinstance(prepared_start, PreparedRuntimeStart)
|
|
579
|
+
else {}
|
|
580
|
+
)
|
|
581
|
+
base_metadata = merged.get("metadata")
|
|
582
|
+
merged.update(
|
|
583
|
+
{
|
|
584
|
+
"input": override.get("input"),
|
|
585
|
+
"session_id": handle.session_id,
|
|
586
|
+
"invocation_id": handle.run_id,
|
|
587
|
+
"metadata": {
|
|
588
|
+
**(dict(base_metadata) if isinstance(base_metadata, Mapping) else {}),
|
|
589
|
+
**dict(override.get("metadata") or {}),
|
|
590
|
+
},
|
|
591
|
+
}
|
|
592
|
+
)
|
|
561
593
|
for key, value in override.items():
|
|
562
594
|
if key not in ("input", "metadata"):
|
|
563
595
|
merged[key] = value
|
|
564
596
|
return merged
|
|
565
597
|
|
|
566
|
-
prepared_start = run.__dict__.get("_prepared_start") if run is not None else None
|
|
567
598
|
if isinstance(prepared_start, PreparedRuntimeStart):
|
|
568
599
|
return dict(prepared_start.runner_input)
|
|
569
600
|
|
|
@@ -582,283 +613,191 @@ class RunnerRuntimeAdapter(RuntimeAdapter):
|
|
|
582
613
|
"metadata": metadata,
|
|
583
614
|
}
|
|
584
615
|
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
616
|
+
# ---- canonical event construction helpers ----
|
|
617
|
+
|
|
618
|
+
def _interaction_requested_from_approval(
|
|
619
|
+
self,
|
|
620
|
+
handle: RunHandle,
|
|
621
|
+
run: Optional[_ActiveRun],
|
|
622
|
+
*,
|
|
623
|
+
detail: Mapping[str, Any],
|
|
624
|
+
call_id: str,
|
|
625
|
+
) -> list[RuntimeEvent]:
|
|
626
|
+
"""把 ToolGateway 结果中携带的审批请求转为 canonical InteractionRequested。"""
|
|
627
|
+
|
|
628
|
+
approval_id = str(detail.get("approval_request_id") or detail.get("id") or call_id or "")
|
|
629
|
+
resolved_call_id = str(call_id or approval_id)
|
|
630
|
+
if run is not None and approval_id:
|
|
631
|
+
run.pending_approvals.add(approval_id)
|
|
632
|
+
if approval_id:
|
|
633
|
+
pending_approval_ids = handle.native_ref.setdefault("pending_approval_ids", [])
|
|
634
|
+
if approval_id not in pending_approval_ids:
|
|
635
|
+
pending_approval_ids.append(approval_id)
|
|
636
|
+
framework = self._runtime_type
|
|
637
|
+
run_id = handle.run_id
|
|
638
|
+
scope_id = stable_scope_id(framework, run_id)
|
|
639
|
+
interaction_id = resolved_call_id or stable_item_id(framework, run_id, "interaction")
|
|
640
|
+
item_id = stable_item_id(framework, run_id, "interaction")
|
|
641
|
+
detail_value: JsonValue = (
|
|
642
|
+
cast(JsonValue, dict(detail)) if isinstance(detail, Mapping) else None
|
|
598
643
|
)
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
)
|
|
615
|
-
_set_conversation_input_attributes(span, prepared_start.input_text)
|
|
616
|
-
try:
|
|
617
|
-
with scope:
|
|
618
|
-
stream_result = self._runner.stream(runner_input)
|
|
619
|
-
if inspect.iscoroutine(stream_result):
|
|
620
|
-
# runner.stream 若声明为 async def -> AsyncIterator(非 async generator),
|
|
621
|
-
# 调用返回 coroutine,需 await 得到迭代器。
|
|
622
|
-
stream_result = await stream_result
|
|
623
|
-
runner_gen = cast(AsyncIterator[Any], stream_result)
|
|
624
|
-
while True:
|
|
625
|
-
# 竞速:下一个 runner chunk vs cancel 中断事件。
|
|
626
|
-
chunk_task = asyncio.ensure_future(_anext_or_stop(runner_gen))
|
|
627
|
-
if run is not None:
|
|
628
|
-
run.chunk_task = chunk_task
|
|
629
|
-
wait_set = {chunk_task}
|
|
630
|
-
interrupt_task = (
|
|
631
|
-
asyncio.ensure_future(interrupt.wait())
|
|
632
|
-
if interrupt is not None
|
|
633
|
-
else None
|
|
634
|
-
)
|
|
635
|
-
if interrupt_task is not None:
|
|
636
|
-
wait_set.add(interrupt_task)
|
|
637
|
-
done, pending = await asyncio.wait(
|
|
638
|
-
wait_set, return_when=asyncio.FIRST_COMPLETED
|
|
639
|
-
)
|
|
640
|
-
for task in pending:
|
|
641
|
-
task.cancel()
|
|
642
|
-
if pending:
|
|
643
|
-
await asyncio.gather(*pending, return_exceptions=True)
|
|
644
|
-
if interrupt_task is not None and interrupt_task in done:
|
|
645
|
-
# cancel 中断:安全关闭 runner 流(同一 task)并停止。
|
|
646
|
-
chunk_task.cancel()
|
|
647
|
-
await asyncio.gather(chunk_task, return_exceptions=True)
|
|
648
|
-
return
|
|
649
|
-
try:
|
|
650
|
-
chunk = chunk_task.result()
|
|
651
|
-
except asyncio.CancelledError:
|
|
652
|
-
if interrupt is not None and interrupt.is_set():
|
|
653
|
-
return
|
|
654
|
-
raise
|
|
655
|
-
finally:
|
|
656
|
-
if run is not None:
|
|
657
|
-
run.chunk_task = None
|
|
658
|
-
if chunk is _STREAM_STOP:
|
|
659
|
-
return
|
|
660
|
-
if isinstance(chunk, dict):
|
|
661
|
-
chunk_type = str(chunk.get("type") or "")
|
|
662
|
-
if chunk_type in {"final", "text", "text_delta"}:
|
|
663
|
-
text = self._coerce(
|
|
664
|
-
chunk.get("delta") or chunk.get("output") or chunk.get("data")
|
|
665
|
-
)
|
|
666
|
-
if text:
|
|
667
|
-
accumulated_output.append(text)
|
|
668
|
-
raw_usage = chunk.get("usage")
|
|
669
|
-
if isinstance(raw_usage, dict):
|
|
670
|
-
usage.update(raw_usage)
|
|
671
|
-
event = self._chunk_to_event(handle, run, chunk)
|
|
672
|
-
if event is not None:
|
|
673
|
-
yield event
|
|
674
|
-
a2ui_surface = _a2ui_surface_event(chunk)
|
|
675
|
-
if a2ui_surface is not None:
|
|
676
|
-
event_type, payload = a2ui_surface
|
|
677
|
-
yield self._event(handle, event_type, payload)
|
|
678
|
-
finally:
|
|
679
|
-
if accumulated_output:
|
|
680
|
-
_set_conversation_output_attributes(span, "".join(accumulated_output))
|
|
681
|
-
_set_conversation_usage_attributes(span, usage)
|
|
682
|
-
if runner_gen is not None:
|
|
683
|
-
aclose = getattr(runner_gen, "aclose", None)
|
|
684
|
-
if callable(aclose):
|
|
685
|
-
try:
|
|
686
|
-
await aclose()
|
|
687
|
-
except Exception: # noqa: BLE001
|
|
688
|
-
pass
|
|
689
|
-
if run is not None:
|
|
690
|
-
run.cancellation_ack.set()
|
|
691
|
-
|
|
692
|
-
def _chunk_to_event(
|
|
693
|
-
self, handle: RunHandle, run: Optional[_ActiveRun], chunk: Any
|
|
694
|
-
) -> Optional[RuntimeEvent]:
|
|
695
|
-
if not isinstance(chunk, dict):
|
|
696
|
-
return self._event(
|
|
697
|
-
handle, EventType.TEXT_DELTA, {"text": str(chunk)}, phase="commentary"
|
|
698
|
-
)
|
|
699
|
-
chunk_type = chunk.get("type")
|
|
700
|
-
if chunk_type in ("reasoning", "reasoning_delta", "thinking"):
|
|
701
|
-
text = self._coerce(
|
|
702
|
-
chunk.get("delta")
|
|
703
|
-
or chunk.get("content")
|
|
704
|
-
or chunk.get("output")
|
|
705
|
-
or chunk.get("data")
|
|
706
|
-
)
|
|
707
|
-
if not text:
|
|
708
|
-
return None
|
|
709
|
-
event_type = (
|
|
710
|
-
EventType.REASONING_COMPLETED
|
|
711
|
-
if chunk.get("status") in ("completed", "done")
|
|
712
|
-
else EventType.REASONING_DELTA
|
|
713
|
-
)
|
|
714
|
-
return self._event(
|
|
715
|
-
handle,
|
|
716
|
-
event_type,
|
|
717
|
-
{"text": text},
|
|
718
|
-
phase="commentary",
|
|
719
|
-
)
|
|
720
|
-
if chunk_type in ("tool_call", "tool_start"):
|
|
721
|
-
call_id = str(
|
|
722
|
-
chunk.get("tool_call_id")
|
|
723
|
-
or chunk.get("call_id")
|
|
724
|
-
or chunk.get("run_id")
|
|
725
|
-
or chunk.get("id")
|
|
726
|
-
or ""
|
|
727
|
-
)
|
|
728
|
-
name = str(chunk.get("tool_name") or chunk.get("name") or "tool")
|
|
729
|
-
return self._event(
|
|
730
|
-
handle,
|
|
731
|
-
EventType.TOOL_CALL_BEGIN,
|
|
732
|
-
{
|
|
733
|
-
"call_id": call_id or name,
|
|
734
|
-
"name": name,
|
|
735
|
-
"args": chunk.get("tool_args", chunk.get("args")),
|
|
736
|
-
},
|
|
737
|
-
)
|
|
738
|
-
if chunk_type in ("tool_result", "tool_end"):
|
|
739
|
-
call_id = str(
|
|
740
|
-
chunk.get("tool_call_id")
|
|
741
|
-
or chunk.get("call_id")
|
|
742
|
-
or chunk.get("run_id")
|
|
743
|
-
or chunk.get("id")
|
|
744
|
-
or ""
|
|
745
|
-
)
|
|
746
|
-
name = str(chunk.get("tool_name") or chunk.get("name") or "tool")
|
|
747
|
-
return self._event(
|
|
748
|
-
handle,
|
|
749
|
-
EventType.TOOL_CALL_END,
|
|
750
|
-
{
|
|
751
|
-
"call_id": call_id or name,
|
|
752
|
-
"name": name,
|
|
753
|
-
"result": chunk.get("tool_output", chunk.get("output")),
|
|
754
|
-
"error": chunk.get("error"),
|
|
755
|
-
},
|
|
756
|
-
)
|
|
757
|
-
if chunk_type in ("interrupt", "approval", "approval_required"):
|
|
758
|
-
detail = chunk.get("interrupt_info") or chunk.get("detail") or {}
|
|
759
|
-
detail_id = detail.get("approval_request_id") if isinstance(detail, dict) else None
|
|
760
|
-
call_id = str(
|
|
761
|
-
chunk.get("call_id")
|
|
762
|
-
or chunk.get("approval_id")
|
|
763
|
-
or chunk.get("id")
|
|
764
|
-
or detail_id
|
|
765
|
-
or ""
|
|
766
|
-
)
|
|
767
|
-
if run is not None and call_id:
|
|
768
|
-
run.pending_approvals.add(call_id)
|
|
769
|
-
if call_id:
|
|
770
|
-
pending_approval_ids = handle.native_ref.setdefault("pending_approval_ids", [])
|
|
771
|
-
if call_id not in pending_approval_ids:
|
|
772
|
-
pending_approval_ids.append(call_id)
|
|
773
|
-
return self._event(
|
|
774
|
-
handle,
|
|
775
|
-
EventType.APPROVAL_REQUESTED,
|
|
776
|
-
{
|
|
777
|
-
"approval_id": call_id,
|
|
778
|
-
"call_id": call_id,
|
|
779
|
-
"kind": "tool",
|
|
780
|
-
"detail": detail,
|
|
781
|
-
},
|
|
782
|
-
)
|
|
783
|
-
if chunk_type == "checkpoint":
|
|
784
|
-
metadata = chunk.get("metadata") or {}
|
|
785
|
-
agentengine = metadata.get("agentengine") if isinstance(metadata, dict) else {}
|
|
786
|
-
framework_ref = (
|
|
787
|
-
agentengine.get("framework_ref") if isinstance(agentengine, dict) else {}
|
|
788
|
-
) or {}
|
|
789
|
-
runtime_ref = (
|
|
790
|
-
framework_ref.get(self._runtime_type) if isinstance(framework_ref, dict) else {}
|
|
791
|
-
) or {}
|
|
792
|
-
checkpoint_id = str(
|
|
793
|
-
runtime_ref.get("checkpoint_id") if isinstance(runtime_ref, dict) else ""
|
|
794
|
-
)
|
|
795
|
-
if not checkpoint_id:
|
|
796
|
-
return None
|
|
797
|
-
handle.native_ref["checkpoint_id"] = checkpoint_id
|
|
798
|
-
known_checkpoint_ids = handle.native_ref.setdefault("known_checkpoint_ids", [])
|
|
799
|
-
if checkpoint_id not in known_checkpoint_ids:
|
|
800
|
-
known_checkpoint_ids.append(checkpoint_id)
|
|
801
|
-
handle.native_ref["framework_ref"] = framework_ref
|
|
802
|
-
if isinstance(runtime_ref, dict):
|
|
803
|
-
handle.native_ref.update(runtime_ref)
|
|
804
|
-
return self._event(
|
|
805
|
-
handle,
|
|
806
|
-
EventType.CHECKPOINT_CREATED,
|
|
807
|
-
{
|
|
808
|
-
"checkpoint_id": checkpoint_id,
|
|
809
|
-
"granularity": self._checkpoint_capability().granularity,
|
|
810
|
-
"resume_target": framework_ref,
|
|
811
|
-
},
|
|
812
|
-
)
|
|
813
|
-
if chunk_type == "graph_update":
|
|
814
|
-
return self._event(
|
|
815
|
-
handle,
|
|
816
|
-
EventType.RUN_PROGRESS,
|
|
817
|
-
{
|
|
818
|
-
"status": "in_progress",
|
|
819
|
-
"node": str(chunk.get("node") or ""),
|
|
820
|
-
"state_update": self._coerce(chunk.get("output")),
|
|
821
|
-
},
|
|
822
|
-
)
|
|
823
|
-
if chunk_type == "error":
|
|
824
|
-
error = self._coerce(chunk.get("message") or chunk.get("error"))
|
|
825
|
-
return self._event(
|
|
826
|
-
handle,
|
|
827
|
-
EventType.RUN_FAILED,
|
|
828
|
-
{
|
|
829
|
-
"status": "failed",
|
|
830
|
-
"error": error or "runner failed",
|
|
831
|
-
},
|
|
832
|
-
)
|
|
833
|
-
if chunk_type == "final":
|
|
834
|
-
return self._event(
|
|
835
|
-
handle,
|
|
836
|
-
EventType.TEXT_COMPLETED,
|
|
837
|
-
{"text": self._coerce(chunk.get("output"))},
|
|
838
|
-
phase="final_answer",
|
|
644
|
+
return [
|
|
645
|
+
InteractionRequested(
|
|
646
|
+
**self._canonical_kwargs(
|
|
647
|
+
handle,
|
|
648
|
+
scope_id=scope_id,
|
|
649
|
+
item_id=item_id,
|
|
650
|
+
event_type="interaction.requested",
|
|
651
|
+
part_id="interaction",
|
|
652
|
+
),
|
|
653
|
+
interaction_id=interaction_id,
|
|
654
|
+
interaction_kind="approval",
|
|
655
|
+
request=ApprovalRequest(
|
|
656
|
+
call_id=resolved_call_id or None,
|
|
657
|
+
kind="tool",
|
|
658
|
+
detail=detail_value,
|
|
659
|
+
),
|
|
839
660
|
)
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
661
|
+
]
|
|
662
|
+
|
|
663
|
+
def _make_source(self, handle: RunHandle, *, protocol: str | None = None) -> SourceRef:
|
|
664
|
+
# SourceRef.framework 是封闭枚举;测试 fixture 或自定义 runtime_type 落到
|
|
665
|
+
# 通用 "ksadk",原生框架名原样保留。
|
|
666
|
+
framework = self._runtime_type
|
|
667
|
+
if framework not in {"adk", "langgraph", "codex", "a2a", "ksadk"}:
|
|
668
|
+
framework = "ksadk"
|
|
669
|
+
return SourceRef(
|
|
670
|
+
framework=framework,
|
|
671
|
+
protocol=protocol,
|
|
672
|
+
native_run_id=handle.run_id,
|
|
673
|
+
metadata={
|
|
674
|
+
"agent_id": str(handle.native_ref.get("agent_id") or "agent"),
|
|
675
|
+
"user_id": str(handle.native_ref.get("user_id") or "user"),
|
|
676
|
+
"session_id": handle.session_id,
|
|
677
|
+
"invocation_id": handle.run_id,
|
|
678
|
+
},
|
|
679
|
+
)
|
|
844
680
|
|
|
845
|
-
def
|
|
681
|
+
def _canonical_kwargs(
|
|
846
682
|
self,
|
|
847
683
|
handle: RunHandle,
|
|
684
|
+
*,
|
|
685
|
+
scope_id: str,
|
|
686
|
+
item_id: str,
|
|
848
687
|
event_type: str,
|
|
849
|
-
|
|
688
|
+
part_id: str,
|
|
689
|
+
) -> dict[str, Any]:
|
|
690
|
+
"""Build common EventEnvelope kwargs for the dict-chunk degraded path."""
|
|
691
|
+
framework = self._runtime_type
|
|
692
|
+
run_id = handle.run_id
|
|
693
|
+
# TODO(runtime-event-v2): dict chunk 退化路径,chunk_ordinal 用 seq counter;
|
|
694
|
+
# LangGraph/Codex 切 stream_canonical_events 后清理
|
|
695
|
+
n = self._next_seq()
|
|
696
|
+
return {
|
|
697
|
+
"schema_version": 2,
|
|
698
|
+
"event_id": stable_event_id(
|
|
699
|
+
framework, scope_id, item_id, event_type, part_id, run_id, n
|
|
700
|
+
),
|
|
701
|
+
"seq": n,
|
|
702
|
+
"timestamp": time.time(),
|
|
703
|
+
"run_id": run_id,
|
|
704
|
+
"scope_id": scope_id,
|
|
705
|
+
"source": self._make_source(handle),
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
def _make_run_started(self, handle: RunHandle) -> RunStarted:
|
|
709
|
+
framework = self._runtime_type
|
|
710
|
+
run_id = handle.run_id
|
|
711
|
+
scope_id = stable_scope_id(framework, run_id)
|
|
712
|
+
item_id = stable_item_id(framework, run_id, "$run")
|
|
713
|
+
return RunStarted(
|
|
714
|
+
schema_version=2,
|
|
715
|
+
event_id=stable_event_id(framework, scope_id, item_id, "run.started", "run", run_id, 0),
|
|
716
|
+
seq=self._next_seq(),
|
|
717
|
+
timestamp=time.time(),
|
|
718
|
+
run_id=run_id,
|
|
719
|
+
scope_id=scope_id,
|
|
720
|
+
source=self._make_source(handle),
|
|
721
|
+
status="running",
|
|
722
|
+
)
|
|
723
|
+
|
|
724
|
+
def _make_run_completed(
|
|
725
|
+
self,
|
|
726
|
+
handle: RunHandle,
|
|
850
727
|
*,
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
728
|
+
run: Optional[_ActiveRun] = None,
|
|
729
|
+
metrics: Mapping[str, Any] | None = None,
|
|
730
|
+
) -> RunCompleted:
|
|
731
|
+
framework = self._runtime_type
|
|
732
|
+
run_id = handle.run_id
|
|
733
|
+
scope_id = stable_scope_id(framework, run_id)
|
|
734
|
+
item_id = stable_item_id(framework, run_id, "$run")
|
|
735
|
+
output_refs: tuple[OutputRef, ...] = ()
|
|
736
|
+
if run is not None and run.final_answer_item_id:
|
|
737
|
+
output_refs = (
|
|
738
|
+
OutputRef(
|
|
739
|
+
scope_id=scope_id,
|
|
740
|
+
item_id=run.final_answer_item_id,
|
|
741
|
+
part_id="text-0",
|
|
742
|
+
),
|
|
743
|
+
)
|
|
744
|
+
source = self._make_source(handle)
|
|
745
|
+
if metrics:
|
|
746
|
+
source = source.model_copy(
|
|
747
|
+
update={"metadata": {**source.metadata, "metrics": dict(metrics)}}
|
|
748
|
+
)
|
|
749
|
+
return RunCompleted(
|
|
750
|
+
schema_version=2,
|
|
751
|
+
event_id=stable_event_id(
|
|
752
|
+
framework, scope_id, item_id, "run.completed", "run", run_id, 0
|
|
753
|
+
),
|
|
754
|
+
seq=self._next_seq(),
|
|
755
|
+
timestamp=time.time(),
|
|
756
|
+
run_id=run_id,
|
|
757
|
+
scope_id=scope_id,
|
|
758
|
+
source=source,
|
|
759
|
+
status="completed",
|
|
760
|
+
output_refs=output_refs,
|
|
761
|
+
)
|
|
762
|
+
|
|
763
|
+
def _make_run_canceled(self, handle: RunHandle, *, reason: str | None = None) -> RunCanceled:
|
|
764
|
+
framework = self._runtime_type
|
|
765
|
+
run_id = handle.run_id
|
|
766
|
+
scope_id = stable_scope_id(framework, run_id)
|
|
767
|
+
item_id = stable_item_id(framework, run_id, "$run")
|
|
768
|
+
return RunCanceled(
|
|
769
|
+
schema_version=2,
|
|
770
|
+
event_id=stable_event_id(
|
|
771
|
+
framework, scope_id, item_id, "run.canceled", "run", run_id, 0
|
|
772
|
+
),
|
|
773
|
+
seq=self._next_seq(),
|
|
774
|
+
timestamp=time.time(),
|
|
775
|
+
run_id=run_id,
|
|
776
|
+
scope_id=scope_id,
|
|
777
|
+
source=self._make_source(handle),
|
|
778
|
+
status="canceled",
|
|
779
|
+
reason=reason,
|
|
780
|
+
)
|
|
781
|
+
|
|
782
|
+
def _make_run_interrupted(
|
|
783
|
+
self, handle: RunHandle, *, reason: str | None = None
|
|
784
|
+
) -> RunInterrupted:
|
|
785
|
+
framework = self._runtime_type
|
|
786
|
+
run_id = handle.run_id
|
|
787
|
+
scope_id = stable_scope_id(framework, run_id)
|
|
788
|
+
item_id = stable_item_id(framework, run_id, "$run")
|
|
789
|
+
return RunInterrupted(
|
|
790
|
+
schema_version=2,
|
|
791
|
+
event_id=stable_event_id(
|
|
792
|
+
framework, scope_id, item_id, "run.interrupted", "run", run_id, 0
|
|
793
|
+
),
|
|
794
|
+
seq=self._next_seq(),
|
|
795
|
+
timestamp=time.time(),
|
|
796
|
+
run_id=run_id,
|
|
797
|
+
scope_id=scope_id,
|
|
798
|
+
source=self._make_source(handle),
|
|
799
|
+
status="interrupted",
|
|
800
|
+
reason=reason,
|
|
862
801
|
)
|
|
863
802
|
|
|
864
803
|
@staticmethod
|