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/events/pipeline.py
ADDED
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
"""Validated canonical event ingestion and deterministic conformance recovery."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import copy
|
|
7
|
+
import hashlib
|
|
8
|
+
import json
|
|
9
|
+
from collections import Counter
|
|
10
|
+
from collections.abc import Awaitable, Callable
|
|
11
|
+
from typing import Any, cast
|
|
12
|
+
|
|
13
|
+
from ksadk.events.canonical import (
|
|
14
|
+
ErrorInfo,
|
|
15
|
+
ItemCompleted,
|
|
16
|
+
ItemFailed,
|
|
17
|
+
ItemKind,
|
|
18
|
+
ItemSnapshotReplaced,
|
|
19
|
+
RunFailed,
|
|
20
|
+
RuntimeEvent,
|
|
21
|
+
SourceRef,
|
|
22
|
+
dump_runtime_event,
|
|
23
|
+
)
|
|
24
|
+
from ksadk.events.canonical_store import RuntimeEventStore
|
|
25
|
+
from ksadk.events.identity import stable_event_id
|
|
26
|
+
from ksadk.events.reducer import StreamConformanceError, StreamReducer
|
|
27
|
+
from ksadk.kernel.contracts import ActivationWriteGuard, WriteContext
|
|
28
|
+
|
|
29
|
+
Publisher = Callable[[str, RuntimeEvent], Awaitable[None]]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _reconciliation_reason(event: RuntimeEvent) -> str:
|
|
33
|
+
if isinstance(event, ItemCompleted):
|
|
34
|
+
return "completed_snapshot_mismatch"
|
|
35
|
+
if isinstance(event, ItemSnapshotReplaced):
|
|
36
|
+
return "authoritative_snapshot_replace"
|
|
37
|
+
raise RuntimeError(f"reconciled patch has no declared metric semantics: {event.event_type!r}")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class PipelineMetrics:
|
|
41
|
+
"""Small metrics seam; production collectors can mirror ``increment``."""
|
|
42
|
+
|
|
43
|
+
def __init__(self) -> None:
|
|
44
|
+
self._counts: Counter[tuple[str, tuple[tuple[str, str], ...]]] = Counter()
|
|
45
|
+
|
|
46
|
+
def increment(self, name: str, **labels: str) -> None:
|
|
47
|
+
self._counts[(name, tuple(sorted(labels.items())))] += 1
|
|
48
|
+
|
|
49
|
+
def value(self, name: str, **labels: str) -> int:
|
|
50
|
+
return self._counts[(name, tuple(sorted(labels.items())))]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class CanonicalEventPipeline:
|
|
54
|
+
"""Prevalidate, persist, reduce and publish one canonical source mutation."""
|
|
55
|
+
|
|
56
|
+
def __init__(
|
|
57
|
+
self,
|
|
58
|
+
store: RuntimeEventStore,
|
|
59
|
+
*,
|
|
60
|
+
session_id: str,
|
|
61
|
+
reducer: StreamReducer | None = None,
|
|
62
|
+
publisher: Publisher | None = None,
|
|
63
|
+
metrics: PipelineMetrics | None = None,
|
|
64
|
+
) -> None:
|
|
65
|
+
if not session_id.strip():
|
|
66
|
+
raise ValueError("session_id must be nonempty")
|
|
67
|
+
self.store = store
|
|
68
|
+
self.session_id = session_id
|
|
69
|
+
self.reducer = reducer or StreamReducer()
|
|
70
|
+
self.publisher = publisher
|
|
71
|
+
self.metrics = metrics or PipelineMetrics()
|
|
72
|
+
self._ingest_lock = asyncio.Lock()
|
|
73
|
+
self._hydrated_run_id = self.reducer.snapshot().run_id
|
|
74
|
+
|
|
75
|
+
async def ingest(self, event: RuntimeEvent) -> tuple[RuntimeEvent, ...]:
|
|
76
|
+
"""Ingest one fact; invalid source facts become durable failure facts."""
|
|
77
|
+
|
|
78
|
+
async with self._ingest_lock:
|
|
79
|
+
return await self._ingest_locked(event)
|
|
80
|
+
|
|
81
|
+
async def emit(
|
|
82
|
+
self, event: RuntimeEvent, *, write_context: WriteContext
|
|
83
|
+
) -> RuntimeEvent:
|
|
84
|
+
"""Fenced typed append: persist (guard CAS) before publish.
|
|
85
|
+
|
|
86
|
+
与 :meth:`ingest` 的差异:``emit`` 是 owner 内部写入路径,要求
|
|
87
|
+
``WriteContext(activation_id, fencing_token)``,通过 typed
|
|
88
|
+
``RuntimeEventStore``(SessionEventStore envelope 视图)走
|
|
89
|
+
``append(event, guard=write_context)``;Store 在事务内比较 fence 后
|
|
90
|
+
才分配 seq,旧 owner 在 takeover 后写入会得到
|
|
91
|
+
:class:`~ksadk.kernel.errors.StaleFenceError`。WriteContext 只作为
|
|
92
|
+
写权限 guard,不进入 RuntimeEvent payload,也不进入公网 projection。
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
if not isinstance(write_context, ActivationWriteGuard):
|
|
96
|
+
raise TypeError(
|
|
97
|
+
"emit requires a typed WriteContext(activation_id, fencing_token)"
|
|
98
|
+
)
|
|
99
|
+
if self.store.event_store is None:
|
|
100
|
+
raise RuntimeError(
|
|
101
|
+
"emit requires a SessionEventStore-backed typed RuntimeEventStore"
|
|
102
|
+
)
|
|
103
|
+
if getattr(self.store, "session_id", None) != self.session_id:
|
|
104
|
+
raise ValueError("typed RuntimeEventStore session does not match pipeline")
|
|
105
|
+
# 先在影子 reducer 上预检 conformance,非法事实绝不落库。
|
|
106
|
+
shadow = copy.deepcopy(self.reducer)
|
|
107
|
+
shadow.apply(event.model_copy(update={"seq": self._validation_seq(event)}))
|
|
108
|
+
persisted = await self.store.append(event, guard=write_context)
|
|
109
|
+
last_seq = self.reducer.snapshot().last_seq
|
|
110
|
+
if last_seq is None or persisted.seq > last_seq:
|
|
111
|
+
self.reducer.apply(persisted)
|
|
112
|
+
await self._publish(persisted)
|
|
113
|
+
return persisted
|
|
114
|
+
|
|
115
|
+
async def _ingest_locked(self, event: RuntimeEvent) -> tuple[RuntimeEvent, ...]:
|
|
116
|
+
await self._hydrate_run_if_needed(event.run_id)
|
|
117
|
+
existing = await self.store.resolve_existing(self.session_id, event)
|
|
118
|
+
if existing is not None:
|
|
119
|
+
last_seq = self.reducer.snapshot().last_seq
|
|
120
|
+
if last_seq is None or existing.seq > last_seq:
|
|
121
|
+
self.reducer.apply(existing)
|
|
122
|
+
await self._publish(existing)
|
|
123
|
+
return (existing,)
|
|
124
|
+
|
|
125
|
+
candidate = event.model_copy(update={"seq": self._validation_seq(event)})
|
|
126
|
+
shadow = copy.deepcopy(self.reducer)
|
|
127
|
+
try:
|
|
128
|
+
preview = shadow.apply(candidate)
|
|
129
|
+
except StreamConformanceError as error:
|
|
130
|
+
return await self._recover(event, error)
|
|
131
|
+
reconciliation_reason = _reconciliation_reason(candidate) if preview.reconciled else None
|
|
132
|
+
|
|
133
|
+
persisted, created = await self.store.persist_one(self.session_id, event)
|
|
134
|
+
self.reducer.apply(persisted)
|
|
135
|
+
if created and reconciliation_reason is not None:
|
|
136
|
+
self.metrics.increment(
|
|
137
|
+
"stream_projection_reconciled_total",
|
|
138
|
+
source=event.source.framework,
|
|
139
|
+
reason=reconciliation_reason,
|
|
140
|
+
)
|
|
141
|
+
await self._publish(persisted)
|
|
142
|
+
return (persisted,)
|
|
143
|
+
|
|
144
|
+
async def _hydrate_run_if_needed(self, run_id: str) -> None:
|
|
145
|
+
if self._hydrated_run_id == run_id:
|
|
146
|
+
return
|
|
147
|
+
snapshot = self.reducer.snapshot()
|
|
148
|
+
if snapshot.run_id is not None and snapshot.run_id != run_id:
|
|
149
|
+
# Let the reducer produce its normal structured run-id error.
|
|
150
|
+
return
|
|
151
|
+
for persisted in await self.store.list(self.session_id, run_id=run_id):
|
|
152
|
+
self.reducer.apply(persisted)
|
|
153
|
+
self._hydrated_run_id = run_id
|
|
154
|
+
|
|
155
|
+
def _validation_seq(self, event: RuntimeEvent) -> int:
|
|
156
|
+
last_seq = self.reducer.snapshot().last_seq
|
|
157
|
+
return max((last_seq or 0) + 1, event.seq)
|
|
158
|
+
|
|
159
|
+
async def _recover(
|
|
160
|
+
self, offending: RuntimeEvent, error: StreamConformanceError
|
|
161
|
+
) -> tuple[RuntimeEvent, ...]:
|
|
162
|
+
fingerprint = _canonical_fingerprint(offending)
|
|
163
|
+
terminal = await self.store.event_by_id(
|
|
164
|
+
self.session_id,
|
|
165
|
+
self._recovery_terminal_event_id(offending),
|
|
166
|
+
)
|
|
167
|
+
owner_locator = await self.store.event_by_id(
|
|
168
|
+
self.session_id,
|
|
169
|
+
self._recovery_owner_event_id(offending),
|
|
170
|
+
)
|
|
171
|
+
if terminal is not None or owner_locator is not None:
|
|
172
|
+
plan = self._load_recovery_plan(
|
|
173
|
+
offending,
|
|
174
|
+
fingerprint,
|
|
175
|
+
terminal=terminal,
|
|
176
|
+
owner_locator=owner_locator,
|
|
177
|
+
)
|
|
178
|
+
else:
|
|
179
|
+
plan = self._new_recovery_plan(offending, error, fingerprint)
|
|
180
|
+
self.metrics.increment(
|
|
181
|
+
"stream_conformance_error_total",
|
|
182
|
+
source=error.source,
|
|
183
|
+
reason=error.code,
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
planned = self._recovery_facts(offending, plan, fingerprint)
|
|
187
|
+
persisted_group: list[RuntimeEvent] = []
|
|
188
|
+
# Persist the complete plan before changing live projection or emitting.
|
|
189
|
+
for fact in planned:
|
|
190
|
+
persisted, _created = await self.store.persist_one(self.session_id, fact)
|
|
191
|
+
persisted_group.append(persisted)
|
|
192
|
+
# Apply the complete durable group before the first publish attempt.
|
|
193
|
+
for persisted in persisted_group:
|
|
194
|
+
last_seq = self.reducer.snapshot().last_seq
|
|
195
|
+
if last_seq is None or persisted.seq > last_seq:
|
|
196
|
+
self.reducer.apply(persisted)
|
|
197
|
+
# A retry republishes the whole group from its first member. Duplicate
|
|
198
|
+
# event ids are allowed at this live boundary; missing facts are not.
|
|
199
|
+
for persisted in persisted_group:
|
|
200
|
+
await self._publish(persisted)
|
|
201
|
+
return tuple(persisted_group)
|
|
202
|
+
|
|
203
|
+
def _load_recovery_plan(
|
|
204
|
+
self,
|
|
205
|
+
offending: RuntimeEvent,
|
|
206
|
+
fingerprint: str,
|
|
207
|
+
*,
|
|
208
|
+
terminal: RuntimeEvent | None,
|
|
209
|
+
owner_locator: RuntimeEvent | None,
|
|
210
|
+
) -> dict[str, Any]:
|
|
211
|
+
terminal_id = self._recovery_terminal_event_id(offending)
|
|
212
|
+
owner_locator_id = self._recovery_owner_event_id(offending)
|
|
213
|
+
existing = tuple(event for event in (terminal, owner_locator) if event is not None)
|
|
214
|
+
owner_ids: set[str] = set()
|
|
215
|
+
for persisted in existing:
|
|
216
|
+
metadata = persisted.source.metadata
|
|
217
|
+
if (
|
|
218
|
+
metadata.get("recovery_for_event_id") != offending.event_id
|
|
219
|
+
or metadata.get("offending_fingerprint") != fingerprint
|
|
220
|
+
):
|
|
221
|
+
raise ValueError(f"RuntimeEvent recovery collision for {offending.event_id!r}")
|
|
222
|
+
owner_id = metadata.get("recovery_plan_owner_event_id")
|
|
223
|
+
if not isinstance(owner_id, str) or not owner_id:
|
|
224
|
+
raise ValueError("persisted recovery is missing its plan owner ref")
|
|
225
|
+
owner_ids.add(owner_id)
|
|
226
|
+
if len(owner_ids) != 1:
|
|
227
|
+
raise ValueError(f"RuntimeEvent recovery collision for {offending.event_id!r}")
|
|
228
|
+
|
|
229
|
+
owner_id = owner_ids.pop()
|
|
230
|
+
if owner_id == terminal_id:
|
|
231
|
+
owner = terminal
|
|
232
|
+
elif owner_id == owner_locator_id:
|
|
233
|
+
owner = owner_locator
|
|
234
|
+
else:
|
|
235
|
+
raise ValueError(f"RuntimeEvent recovery collision for {offending.event_id!r}")
|
|
236
|
+
if owner is None:
|
|
237
|
+
raise ValueError("persisted recovery plan owner is missing")
|
|
238
|
+
if terminal is not None and (
|
|
239
|
+
terminal.event_id != terminal_id or terminal.event_type != "run.failed"
|
|
240
|
+
):
|
|
241
|
+
raise ValueError(f"RuntimeEvent recovery collision for {offending.event_id!r}")
|
|
242
|
+
if owner_locator is not None and (
|
|
243
|
+
owner_locator.event_id != owner_locator_id or owner_locator.event_type != "item.failed"
|
|
244
|
+
):
|
|
245
|
+
raise ValueError(f"RuntimeEvent recovery collision for {offending.event_id!r}")
|
|
246
|
+
owner_metadata = owner.source.metadata
|
|
247
|
+
if (
|
|
248
|
+
owner.event_id != owner_id
|
|
249
|
+
or owner_metadata.get("recovery_for_event_id") != offending.event_id
|
|
250
|
+
or owner_metadata.get("offending_fingerprint") != fingerprint
|
|
251
|
+
or owner_metadata.get("recovery_plan_owner_event_id") != owner_id
|
|
252
|
+
):
|
|
253
|
+
raise ValueError(f"RuntimeEvent recovery collision for {offending.event_id!r}")
|
|
254
|
+
plan_value = owner_metadata.get("recovery_plan")
|
|
255
|
+
if not isinstance(plan_value, dict):
|
|
256
|
+
raise ValueError("persisted recovery plan owner is missing its complete plan")
|
|
257
|
+
if (
|
|
258
|
+
plan_value.get("offending_fingerprint") != fingerprint
|
|
259
|
+
or plan_value.get("owner_event_id") != owner_id
|
|
260
|
+
):
|
|
261
|
+
raise ValueError(f"RuntimeEvent recovery collision for {offending.event_id!r}")
|
|
262
|
+
entries = plan_value.get("events")
|
|
263
|
+
if (
|
|
264
|
+
not isinstance(entries, list)
|
|
265
|
+
or not entries
|
|
266
|
+
or not isinstance(entries[0], dict)
|
|
267
|
+
or entries[0].get("event_id") != owner_id
|
|
268
|
+
or entries[0].get("event_type")
|
|
269
|
+
!= ("run.failed" if owner_id == terminal_id else "item.failed")
|
|
270
|
+
or not isinstance(entries[-1], dict)
|
|
271
|
+
or entries[-1].get("event_id") != terminal_id
|
|
272
|
+
or entries[-1].get("event_type") != "run.failed"
|
|
273
|
+
):
|
|
274
|
+
raise ValueError(f"RuntimeEvent recovery collision for {offending.event_id!r}")
|
|
275
|
+
return plan_value
|
|
276
|
+
|
|
277
|
+
def _new_recovery_plan(
|
|
278
|
+
self,
|
|
279
|
+
offending: RuntimeEvent,
|
|
280
|
+
error: StreamConformanceError,
|
|
281
|
+
fingerprint: str,
|
|
282
|
+
) -> dict[str, Any]:
|
|
283
|
+
entries: list[dict[str, Any]] = []
|
|
284
|
+
open_items = sorted(
|
|
285
|
+
(item for item in self.reducer.snapshot().items if item.status == "open"),
|
|
286
|
+
key=lambda item: (item.scope_id, item.item_id),
|
|
287
|
+
)
|
|
288
|
+
for index, item in enumerate(open_items):
|
|
289
|
+
entries.append(
|
|
290
|
+
{
|
|
291
|
+
"event_id": (
|
|
292
|
+
self._recovery_owner_event_id(offending)
|
|
293
|
+
if index == 0
|
|
294
|
+
else stable_event_id(
|
|
295
|
+
"ksadk",
|
|
296
|
+
item.scope_id,
|
|
297
|
+
item.item_id,
|
|
298
|
+
"item.failed",
|
|
299
|
+
"recovery",
|
|
300
|
+
offending.event_id,
|
|
301
|
+
0,
|
|
302
|
+
)
|
|
303
|
+
),
|
|
304
|
+
"event_type": "item.failed",
|
|
305
|
+
"scope_id": item.scope_id,
|
|
306
|
+
"item_id": item.item_id,
|
|
307
|
+
"item_kind": item.item_kind,
|
|
308
|
+
}
|
|
309
|
+
)
|
|
310
|
+
entries.append(
|
|
311
|
+
{
|
|
312
|
+
"event_id": self._recovery_terminal_event_id(offending),
|
|
313
|
+
"event_type": "run.failed",
|
|
314
|
+
"scope_id": offending.scope_id,
|
|
315
|
+
}
|
|
316
|
+
)
|
|
317
|
+
owner_event_id = str(entries[0]["event_id"])
|
|
318
|
+
return {
|
|
319
|
+
"version": 1,
|
|
320
|
+
"owner_event_id": owner_event_id,
|
|
321
|
+
"offending_fingerprint": fingerprint,
|
|
322
|
+
"error": {
|
|
323
|
+
"code": error.code,
|
|
324
|
+
"source": error.source,
|
|
325
|
+
"scope_id": error.scope_id,
|
|
326
|
+
"item_id": error.item_id,
|
|
327
|
+
},
|
|
328
|
+
"events": entries,
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
@staticmethod
|
|
332
|
+
def _recovery_owner_event_id(offending: RuntimeEvent) -> str:
|
|
333
|
+
return stable_event_id(
|
|
334
|
+
"ksadk",
|
|
335
|
+
"recovery",
|
|
336
|
+
offending.event_id,
|
|
337
|
+
"item.failed",
|
|
338
|
+
"plan-owner",
|
|
339
|
+
offending.event_id,
|
|
340
|
+
0,
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
@staticmethod
|
|
344
|
+
def _recovery_terminal_event_id(offending: RuntimeEvent) -> str:
|
|
345
|
+
# The session-scoped offending event id is the collision domain. Do
|
|
346
|
+
# not include mutable candidate facts such as run/scope here: a retry
|
|
347
|
+
# that reuses event_id with different facts must hit this tombstone and
|
|
348
|
+
# fail fingerprint validation before writing a second recovery group.
|
|
349
|
+
return stable_event_id(
|
|
350
|
+
"ksadk",
|
|
351
|
+
"recovery",
|
|
352
|
+
offending.event_id,
|
|
353
|
+
"run.failed",
|
|
354
|
+
"tombstone",
|
|
355
|
+
offending.event_id,
|
|
356
|
+
0,
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
@staticmethod
|
|
360
|
+
def _recovery_facts(
|
|
361
|
+
offending: RuntimeEvent,
|
|
362
|
+
plan: dict[str, Any],
|
|
363
|
+
fingerprint: str,
|
|
364
|
+
) -> tuple[RuntimeEvent, ...]:
|
|
365
|
+
error_payload = plan.get("error")
|
|
366
|
+
entries = plan.get("events")
|
|
367
|
+
owner_event_id = plan.get("owner_event_id")
|
|
368
|
+
if (
|
|
369
|
+
not isinstance(error_payload, dict)
|
|
370
|
+
or not isinstance(entries, list)
|
|
371
|
+
or not isinstance(owner_event_id, str)
|
|
372
|
+
or not owner_event_id
|
|
373
|
+
):
|
|
374
|
+
raise ValueError("persisted recovery plan is malformed")
|
|
375
|
+
error_info = ErrorInfo(
|
|
376
|
+
code=str(error_payload.get("code") or "stream_conformance_error"),
|
|
377
|
+
message="Canonical stream conformance failure",
|
|
378
|
+
source=str(error_payload.get("source") or offending.source.framework),
|
|
379
|
+
scope_id=str(error_payload.get("scope_id") or offending.scope_id),
|
|
380
|
+
item_id=(str(error_payload["item_id"]) if error_payload.get("item_id") else None),
|
|
381
|
+
source_ref=offending.source,
|
|
382
|
+
)
|
|
383
|
+
facts: list[RuntimeEvent] = []
|
|
384
|
+
for entry in entries:
|
|
385
|
+
if not isinstance(entry, dict):
|
|
386
|
+
raise ValueError("persisted recovery plan event is malformed")
|
|
387
|
+
event_id = str(entry.get("event_id") or "")
|
|
388
|
+
metadata: dict[str, Any] = {
|
|
389
|
+
"recovery_for_event_id": offending.event_id,
|
|
390
|
+
"offending_fingerprint": fingerprint,
|
|
391
|
+
"recovery_plan_owner_event_id": owner_event_id,
|
|
392
|
+
}
|
|
393
|
+
if event_id == owner_event_id:
|
|
394
|
+
metadata["recovery_plan"] = plan
|
|
395
|
+
recovery_source = SourceRef(
|
|
396
|
+
framework="ksadk",
|
|
397
|
+
native_event_id=offending.event_id,
|
|
398
|
+
native_run_id=offending.run_id,
|
|
399
|
+
metadata=metadata,
|
|
400
|
+
)
|
|
401
|
+
if entry.get("event_type") == "item.failed":
|
|
402
|
+
scope_id = str(entry.get("scope_id") or "")
|
|
403
|
+
item_id = str(entry.get("item_id") or "")
|
|
404
|
+
facts.append(
|
|
405
|
+
ItemFailed(
|
|
406
|
+
schema_version=2,
|
|
407
|
+
event_id=event_id,
|
|
408
|
+
seq=0,
|
|
409
|
+
timestamp=offending.timestamp,
|
|
410
|
+
run_id=offending.run_id,
|
|
411
|
+
run_seq=offending.run_seq,
|
|
412
|
+
scope_id=scope_id,
|
|
413
|
+
source=recovery_source,
|
|
414
|
+
item_id=item_id,
|
|
415
|
+
item_kind=cast(ItemKind, entry.get("item_kind") or "message"),
|
|
416
|
+
error=error_info.model_copy(
|
|
417
|
+
update={"scope_id": scope_id, "item_id": item_id}
|
|
418
|
+
),
|
|
419
|
+
)
|
|
420
|
+
)
|
|
421
|
+
elif entry.get("event_type") == "run.failed":
|
|
422
|
+
facts.append(
|
|
423
|
+
RunFailed(
|
|
424
|
+
schema_version=2,
|
|
425
|
+
event_id=event_id,
|
|
426
|
+
seq=0,
|
|
427
|
+
timestamp=offending.timestamp,
|
|
428
|
+
run_id=offending.run_id,
|
|
429
|
+
run_seq=offending.run_seq,
|
|
430
|
+
scope_id=str(entry.get("scope_id") or offending.scope_id),
|
|
431
|
+
parent_scope_id=offending.parent_scope_id,
|
|
432
|
+
source=recovery_source,
|
|
433
|
+
status="failed",
|
|
434
|
+
error=error_info,
|
|
435
|
+
)
|
|
436
|
+
)
|
|
437
|
+
else:
|
|
438
|
+
raise ValueError("persisted recovery plan has unsupported event type")
|
|
439
|
+
return tuple(facts)
|
|
440
|
+
|
|
441
|
+
async def _publish(self, event: RuntimeEvent) -> None:
|
|
442
|
+
if self.publisher is not None:
|
|
443
|
+
await self.publisher(self.session_id, event)
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
__all__ = ["CanonicalEventPipeline", "PipelineMetrics"]
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
def _canonical_fingerprint(event: RuntimeEvent) -> str:
|
|
450
|
+
payload = dump_runtime_event(event)
|
|
451
|
+
payload.pop("seq", None)
|
|
452
|
+
encoded = json.dumps(payload, ensure_ascii=False, separators=(",", ":"), sort_keys=True).encode(
|
|
453
|
+
"utf-8"
|
|
454
|
+
)
|
|
455
|
+
return hashlib.sha256(encoded).hexdigest()
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Canonical 内部事实与公开投影的边界(重设计要素 3/3)。
|
|
2
|
+
|
|
3
|
+
canonical store(``ksadk/events/canonical_store.py`` 及 ``canonical.py`` 的事件
|
|
4
|
+
模型)是唯一的存储事实(append-only、schema_version=2、含内部字段如
|
|
5
|
+
``seq``/``run_seq``/``native_*``/``source.metadata``)。所有对外 wire 形态都是
|
|
6
|
+
从 canonical 事实派生的**投影**:投影只承诺下表列出的最小公开字段集,除此之外
|
|
7
|
+
的字段(含内部序号、native 游标、source 原始 metadata)均属内部不保证字段,
|
|
8
|
+
消费方不得依赖。
|
|
9
|
+
|
|
10
|
+
本模块是边界的**声明处**;契约的**执行形态**是 golden 测试
|
|
11
|
+
``tests/protocol/test_cross_projection_golden.py`` 与 fixture
|
|
12
|
+
``tests/events/fixtures/runtime_projection_golden.json``。修改任何投影的公开字段
|
|
13
|
+
承诺必须同时更新本表与 golden 测试。
|
|
14
|
+
|
|
15
|
+
投影矩阵(投影 | 实现位置 | 消费方 | 最小公开字段承诺):
|
|
16
|
+
|
|
17
|
+
| 投影 | 实现位置 | 消费方 | 公开承诺字段 |
|
|
18
|
+
| --- | --- | --- | --- |
|
|
19
|
+
| v1 legacy wire | ``events/v1_compat.py::project_to_v1`` | canonical_replay、cli cmd_replay、旧 SDK 客户端 | RuntimeEventV1 事件类型 + 各类型 payload(approval_id/call_id/kind/detail、surface_id/block_id/data、output_refs、status/error/reason)+ 身份字段 run_id/scope_id/item_id |
|
|
20
|
+
| Studio 事件流 | ``studio/run_service.py::project_runtime_event`` | 本地/托管 Studio UI(SSE) | ``runId``/``scopeId`` 全事件;message.*/thinking.* 含 ``itemId``/``partId``;tool.*/command.*/approval.*/a2ui.* 含 ``itemId``;a2ui.surface.* 含 ``surfaceId``/``a2uiOperations`` |
|
|
21
|
+
| AG-UI/A2UI operations | ``agui/a2ui_projection.py::project_a2ui_operations`` | AG-UI 兼容客户端与 message_projection | 操作列表 ``[{version: "v0.9", createSurface|updateComponents|updateDataModel|deleteSurface: ...}]``,每条含 ``surfaceId`` |
|
|
22
|
+
| 会话消息历史 | ``conversations/message_projection.py::project_session_messages`` | server GetSession/ListMessages、hosted UI 历史接口 | 消息 dict:``Role``/``Content.text``/``SeqId``/``StartSeqId``,可选 ``Reasoning``/``ToolEvents``(approval 含 ``ApprovalRequestId``)/``Activities``(含 ``surfaceId``) |
|
|
23
|
+
| Responses 历史 | ``conversations/context.py::project_responses_history`` | Responses API 请求回放 input | OpenAI Responses input items(``type``/``call_id``/``output``/role 消息),仅可靠 call_id 的 tool 项 |
|
|
24
|
+
| 模型 history | ``conversations/context.py::project_model_messages`` | 运行时模型上下文(内部投喂) | ``role``/``content`` 消息列表;control 事件不进入上下文 |
|
|
25
|
+
| server checkpoint payload | ``server/routes/projection.py::_checkpoint_event_to_action_payload`` | REST 断点续跑/预览接口 | ``EventId``/``SessionId``/``RunId``/``CheckpointId``/``Framework``/``FrameworkRef``/``IsResumable``/``ResumeStatus``/``IsTerminal``/``NextNode``(经 ``run_checkpoint`` 元数据或 ``continuation.created`` 投影) |
|
|
26
|
+
| server 动作事件 payload | ``server/routes/projection.py::_event_to_action_payload`` | REST 会话动作接口(事件原始形态透传) | ``EventId``/``SessionId``/``Author``/``EventType``/``Content``/``Timestamp``/``SeqId``(可选 ``InvocationId``)——序列化存储形态本身,非 canonical 派生 |
|
|
27
|
+
|
|
28
|
+
内部不保证(任何投影都不承诺、消费方不得依赖):
|
|
29
|
+
- ``seq``/``run_seq`` 的具体数值与连续性(仅保序语义);
|
|
30
|
+
- ``source.native_event_id``/``native_cursor``/``native_run_id``/``native_item_id``;
|
|
31
|
+
- ``source.metadata`` 原始键值(capability 等仅经投影显式提炼后可见);
|
|
32
|
+
- 未列入上表的 payload 附加键。
|
|
33
|
+
|
|
34
|
+
内部投影(非 wire,不构成公开承诺):
|
|
35
|
+
- ``events/reducer.py::StreamReducer.snapshot`` — 进程内 UI 聚合状态;
|
|
36
|
+
- ``events/canonical_replay.py::replay_projection`` — 内部重建 RunProjection 的路径,
|
|
37
|
+
其 v1 输出复用 ``project_to_v1`` 的承诺。
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
from __future__ import annotations
|
|
41
|
+
|
|
42
|
+
PROJECTION_CONTRACT_VERSION = 1
|
|
43
|
+
|
|
44
|
+
#: 各投影实现位置的机器可读索引(供文档/校验工具引用;承诺文本见模块 docstring)。
|
|
45
|
+
PROJECTIONS: dict[str, str] = {
|
|
46
|
+
"v1": "ksadk.events.v1_compat:project_to_v1",
|
|
47
|
+
"studio": "ksadk.studio.run_service:project_runtime_event",
|
|
48
|
+
"a2ui": "ksadk.agui.a2ui_projection:project_a2ui_operations",
|
|
49
|
+
"session_messages": "ksadk.conversations.message_projection:project_session_messages",
|
|
50
|
+
"responses_history": "ksadk.conversations.context:project_responses_history",
|
|
51
|
+
"model_messages": "ksadk.conversations.context:project_model_messages",
|
|
52
|
+
"server_checkpoint": "ksadk.server.routes.projection:_checkpoint_event_to_action_payload",
|
|
53
|
+
"server_action_event": "ksadk.server.routes.projection:_event_to_action_payload",
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
#: 仅内部使用的投影(对外无 wire 契约)。
|
|
57
|
+
INTERNAL_PROJECTIONS: dict[str, str] = {
|
|
58
|
+
"stream_reducer": "ksadk.events.reducer:StreamReducer",
|
|
59
|
+
"replay_projection": "ksadk.events.canonical_replay:replay_projection",
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
__all__ = [
|
|
63
|
+
"INTERNAL_PROJECTIONS",
|
|
64
|
+
"PROJECTION_CONTRACT_VERSION",
|
|
65
|
+
"PROJECTIONS",
|
|
66
|
+
]
|