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
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
"""Versioned, fixed-watermark JSONL exports for canonical RuntimeEvents.
|
|
2
|
+
|
|
3
|
+
New exports use the schema-v2 RuntimeEvent envelope. The legacy v1 log is
|
|
4
|
+
still accepted by :func:`verify_session_log` so existing diagnostic files stay
|
|
5
|
+
readable, but a v2 Store must never be coerced back into a v1 write model just
|
|
6
|
+
to produce an export.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import json
|
|
12
|
+
import os
|
|
13
|
+
import tempfile
|
|
14
|
+
from dataclasses import dataclass
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from typing import Any, TextIO
|
|
17
|
+
|
|
18
|
+
from ksadk.events.canonical import dump_runtime_event, parse_runtime_event
|
|
19
|
+
from ksadk.events.store import RuntimeEventStore
|
|
20
|
+
from ksadk.events.v1_compat import EventTypeV1, RuntimeEventV1
|
|
21
|
+
from ksadk.sessions.base import BaseSessionService
|
|
22
|
+
|
|
23
|
+
SESSION_LOG_SCHEMA = "ksadk.session-log/v2"
|
|
24
|
+
_SESSION_LOG_VERSION = 2
|
|
25
|
+
_LEGACY_SESSION_LOG_SCHEMA = "ksadk.session-log/v1"
|
|
26
|
+
_LEGACY_SESSION_LOG_VERSION = 1
|
|
27
|
+
_PAGE_SIZE = 500
|
|
28
|
+
_LEGACY_PACKED_EVENT_TYPES = {
|
|
29
|
+
EventTypeV1.TEXT_DELTA: "text-chunks",
|
|
30
|
+
EventTypeV1.REASONING_DELTA: "reasoning-chunks",
|
|
31
|
+
}
|
|
32
|
+
_LEGACY_PACKED_RECORD_TYPES = {value: key for key, value in _LEGACY_PACKED_EVENT_TYPES.items()}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class SessionLogError(ValueError):
|
|
36
|
+
"""A stable Session Log export or validation failure."""
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass(frozen=True)
|
|
40
|
+
class SessionLogResult:
|
|
41
|
+
path: Path
|
|
42
|
+
event_count: int
|
|
43
|
+
first_seq_id: int | None
|
|
44
|
+
last_seq_id: int | None
|
|
45
|
+
exported_through_seq_id: int | None
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _raise(code: str, message: str) -> None:
|
|
49
|
+
raise SessionLogError(f"{code}: {message}")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _write_json_line(stream: TextIO, value: dict[str, Any]) -> None:
|
|
53
|
+
stream.write(
|
|
54
|
+
json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + "\n"
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _legacy_packed_base(event: RuntimeEventV1) -> dict[str, Any]:
|
|
59
|
+
value = event.to_dict()
|
|
60
|
+
for key in ("event_id", "seq_id", "timestamp"):
|
|
61
|
+
value.pop(key)
|
|
62
|
+
payload = dict(value["payload"])
|
|
63
|
+
payload.pop("text")
|
|
64
|
+
value["payload"] = payload
|
|
65
|
+
return value
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _write_legacy_event_run(stream: TextIO, events: list[RuntimeEventV1]) -> None:
|
|
69
|
+
if len(events) < 3:
|
|
70
|
+
for event in events:
|
|
71
|
+
_write_json_line(stream, event.to_dict())
|
|
72
|
+
return
|
|
73
|
+
_write_json_line(
|
|
74
|
+
stream,
|
|
75
|
+
{
|
|
76
|
+
"type": _LEGACY_PACKED_EVENT_TYPES[events[0].event_type],
|
|
77
|
+
"seq0": events[0].seq_id,
|
|
78
|
+
"data": {
|
|
79
|
+
"base": _legacy_packed_base(events[0]),
|
|
80
|
+
"event_ids": [event.event_id for event in events],
|
|
81
|
+
"timestamps": [event.timestamp for event in events],
|
|
82
|
+
"texts": [event.payload["text"] for event in events],
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _same_legacy_event_run(events: list[RuntimeEventV1], event: RuntimeEventV1) -> bool:
|
|
89
|
+
return (
|
|
90
|
+
bool(events)
|
|
91
|
+
and event.event_type == events[0].event_type
|
|
92
|
+
and event.seq_id == events[-1].seq_id + 1
|
|
93
|
+
and _legacy_packed_base(event) == _legacy_packed_base(events[0])
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
async def export_session_log(
|
|
98
|
+
session_service: BaseSessionService,
|
|
99
|
+
session_id: str,
|
|
100
|
+
target: Path | str,
|
|
101
|
+
*,
|
|
102
|
+
invocation_id: str | None = None,
|
|
103
|
+
) -> SessionLogResult:
|
|
104
|
+
"""Export committed RuntimeEvents through a fixed session cursor."""
|
|
105
|
+
session = await session_service.get_session_metadata(session_id)
|
|
106
|
+
if session is None:
|
|
107
|
+
_raise("SESSION_LOG_SESSION_NOT_FOUND", f"session {session_id!r} not found")
|
|
108
|
+
|
|
109
|
+
target_path = Path(target)
|
|
110
|
+
if target_path.exists():
|
|
111
|
+
_raise("SESSION_LOG_TARGET_EXISTS", f"target {target_path} already exists")
|
|
112
|
+
|
|
113
|
+
store = RuntimeEventStore(session_service)
|
|
114
|
+
tail = await store.list(session_id, limit=1)
|
|
115
|
+
cutoff = tail[-1].seq if tail else None
|
|
116
|
+
header: dict[str, Any] = {
|
|
117
|
+
"type": "session",
|
|
118
|
+
"schema": SESSION_LOG_SCHEMA,
|
|
119
|
+
"version": _SESSION_LOG_VERSION,
|
|
120
|
+
"session_id": session.id,
|
|
121
|
+
"agent_id": session.agent_id,
|
|
122
|
+
"user_id": session.user_id,
|
|
123
|
+
"created_at": session.created_at,
|
|
124
|
+
"updated_at": session.updated_at,
|
|
125
|
+
"exported_through_seq_id": cutoff,
|
|
126
|
+
"event_schema_version": 2,
|
|
127
|
+
}
|
|
128
|
+
if invocation_id is not None:
|
|
129
|
+
header["invocation_id"] = invocation_id
|
|
130
|
+
|
|
131
|
+
temporary_path: Path | None = None
|
|
132
|
+
published = False
|
|
133
|
+
event_count = 0
|
|
134
|
+
first_seq_id: int | None = None
|
|
135
|
+
last_seq_id: int | None = None
|
|
136
|
+
try:
|
|
137
|
+
descriptor, temporary_name = tempfile.mkstemp(
|
|
138
|
+
dir=target_path.parent,
|
|
139
|
+
prefix=".session-log-",
|
|
140
|
+
suffix=".tmp",
|
|
141
|
+
)
|
|
142
|
+
temporary_path = Path(temporary_name)
|
|
143
|
+
os.fchmod(descriptor, 0o600)
|
|
144
|
+
with os.fdopen(descriptor, "w", encoding="utf-8") as stream:
|
|
145
|
+
_write_json_line(stream, header)
|
|
146
|
+
cursor = 0
|
|
147
|
+
while cutoff is not None and cursor < cutoff:
|
|
148
|
+
window_end = min(cursor + _PAGE_SIZE, cutoff)
|
|
149
|
+
events = await store.page(
|
|
150
|
+
session_id,
|
|
151
|
+
after_seq=cursor,
|
|
152
|
+
before_seq=window_end + 1,
|
|
153
|
+
limit=_PAGE_SIZE,
|
|
154
|
+
)
|
|
155
|
+
for event in events:
|
|
156
|
+
if invocation_id is not None and event.run_id != invocation_id:
|
|
157
|
+
continue
|
|
158
|
+
# A v2 fact is the durable source of truth. The v1
|
|
159
|
+
# packed delta format cannot losslessly encode all v2
|
|
160
|
+
# item operations, so v2 logs retain one canonical event
|
|
161
|
+
# per row instead of silently projecting/dropping facts.
|
|
162
|
+
_write_json_line(stream, dump_runtime_event(event))
|
|
163
|
+
event_count += 1
|
|
164
|
+
first_seq_id = first_seq_id or event.seq
|
|
165
|
+
last_seq_id = event.seq
|
|
166
|
+
cursor = window_end
|
|
167
|
+
stream.flush()
|
|
168
|
+
os.fsync(stream.fileno())
|
|
169
|
+
|
|
170
|
+
try:
|
|
171
|
+
os.link(temporary_path, target_path)
|
|
172
|
+
published = True
|
|
173
|
+
except FileExistsError as exc:
|
|
174
|
+
raise SessionLogError(
|
|
175
|
+
f"SESSION_LOG_TARGET_EXISTS: target {target_path} already exists"
|
|
176
|
+
) from exc
|
|
177
|
+
except OSError as exc:
|
|
178
|
+
raise SessionLogError(
|
|
179
|
+
"SESSION_LOG_ATOMIC_PUBLISH_UNSUPPORTED: "
|
|
180
|
+
f"cannot atomically publish {target_path}"
|
|
181
|
+
) from exc
|
|
182
|
+
|
|
183
|
+
directory_fd = os.open(target_path.parent, os.O_RDONLY)
|
|
184
|
+
try:
|
|
185
|
+
os.fsync(directory_fd)
|
|
186
|
+
finally:
|
|
187
|
+
os.close(directory_fd)
|
|
188
|
+
except SessionLogError:
|
|
189
|
+
if published:
|
|
190
|
+
target_path.unlink(missing_ok=True)
|
|
191
|
+
raise
|
|
192
|
+
except OSError as exc:
|
|
193
|
+
if published:
|
|
194
|
+
target_path.unlink(missing_ok=True)
|
|
195
|
+
raise SessionLogError(f"SESSION_LOG_WRITE_FAILED: {target_path}") from exc
|
|
196
|
+
finally:
|
|
197
|
+
if temporary_path is not None:
|
|
198
|
+
temporary_path.unlink(missing_ok=True)
|
|
199
|
+
|
|
200
|
+
return SessionLogResult(
|
|
201
|
+
path=target_path,
|
|
202
|
+
event_count=event_count,
|
|
203
|
+
first_seq_id=first_seq_id,
|
|
204
|
+
last_seq_id=last_seq_id,
|
|
205
|
+
exported_through_seq_id=cutoff,
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def _read_json_line(raw: str, line_number: int) -> dict[str, Any]:
|
|
210
|
+
try:
|
|
211
|
+
value = json.loads(raw)
|
|
212
|
+
except json.JSONDecodeError as exc:
|
|
213
|
+
raise SessionLogError(f"SESSION_LOG_INVALID: line {line_number} is not valid JSON") from exc
|
|
214
|
+
if not isinstance(value, dict):
|
|
215
|
+
_raise("SESSION_LOG_INVALID", f"line {line_number} must be an object")
|
|
216
|
+
return value
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def _legacy_events_from_record(
|
|
220
|
+
value: dict[str, Any], line_number: int, *, allow_packed: bool
|
|
221
|
+
) -> list[RuntimeEventV1]:
|
|
222
|
+
record_type = value.get("type")
|
|
223
|
+
if record_type not in _LEGACY_PACKED_RECORD_TYPES:
|
|
224
|
+
try:
|
|
225
|
+
return [RuntimeEventV1.from_dict(value)]
|
|
226
|
+
except (TypeError, ValueError) as exc:
|
|
227
|
+
raise SessionLogError(
|
|
228
|
+
f"SESSION_LOG_INVALID: line {line_number} is not a RuntimeEvent"
|
|
229
|
+
) from exc
|
|
230
|
+
if not allow_packed:
|
|
231
|
+
_raise("SESSION_LOG_INVALID", f"line {line_number} uses packed rows in v1")
|
|
232
|
+
|
|
233
|
+
seq0 = value.get("seq0")
|
|
234
|
+
data = value.get("data")
|
|
235
|
+
if isinstance(seq0, bool) or not isinstance(seq0, int) or seq0 < 0:
|
|
236
|
+
_raise("SESSION_LOG_INVALID", f"line {line_number} packed seq0 is invalid")
|
|
237
|
+
if not isinstance(data, dict) or not isinstance(data.get("base"), dict):
|
|
238
|
+
_raise("SESSION_LOG_INVALID", f"line {line_number} packed data is invalid")
|
|
239
|
+
event_ids = data.get("event_ids")
|
|
240
|
+
timestamps = data.get("timestamps")
|
|
241
|
+
texts = data.get("texts")
|
|
242
|
+
if not all(isinstance(items, list) for items in (event_ids, timestamps, texts)):
|
|
243
|
+
_raise("SESSION_LOG_INVALID", f"line {line_number} packed arrays are invalid")
|
|
244
|
+
if len(event_ids) < 3 or len(event_ids) != len(timestamps) or len(event_ids) != len(texts):
|
|
245
|
+
_raise("SESSION_LOG_INVALID", f"line {line_number} packed arrays do not align")
|
|
246
|
+
|
|
247
|
+
base = dict(data["base"])
|
|
248
|
+
expected_event_type = _LEGACY_PACKED_RECORD_TYPES[record_type]
|
|
249
|
+
if base.get("event_type") != expected_event_type:
|
|
250
|
+
_raise("SESSION_LOG_INVALID", f"line {line_number} packed event type does not match")
|
|
251
|
+
payload = base.get("payload")
|
|
252
|
+
if not isinstance(payload, dict) or "text" in payload:
|
|
253
|
+
_raise("SESSION_LOG_INVALID", f"line {line_number} packed payload is invalid")
|
|
254
|
+
|
|
255
|
+
events: list[RuntimeEventV1] = []
|
|
256
|
+
for index, (event_id, timestamp, text) in enumerate(
|
|
257
|
+
zip(event_ids, timestamps, texts, strict=True)
|
|
258
|
+
):
|
|
259
|
+
value = {
|
|
260
|
+
**base,
|
|
261
|
+
"event_id": event_id,
|
|
262
|
+
"seq_id": seq0 + index,
|
|
263
|
+
"timestamp": timestamp,
|
|
264
|
+
"payload": {**payload, "text": text},
|
|
265
|
+
}
|
|
266
|
+
try:
|
|
267
|
+
events.append(RuntimeEventV1.from_dict(value))
|
|
268
|
+
except (TypeError, ValueError) as exc:
|
|
269
|
+
raise SessionLogError(
|
|
270
|
+
f"SESSION_LOG_INVALID: line {line_number} contains an invalid packed event"
|
|
271
|
+
) from exc
|
|
272
|
+
return events
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def _validate_header(
|
|
276
|
+
header: dict[str, Any], *, schema: str, version: int
|
|
277
|
+
) -> tuple[int | None, str | None]:
|
|
278
|
+
if header.get("type") != "session":
|
|
279
|
+
_raise("SESSION_LOG_INVALID", "first line must be a session header")
|
|
280
|
+
if header.get("schema") != schema or header.get("version") != version:
|
|
281
|
+
_raise("SESSION_LOG_INVALID", "unsupported schema")
|
|
282
|
+
session_id = header.get("session_id")
|
|
283
|
+
if not isinstance(session_id, str) or not session_id:
|
|
284
|
+
_raise("SESSION_LOG_INVALID", "header session id is required")
|
|
285
|
+
cutoff = header.get("exported_through_seq_id")
|
|
286
|
+
if cutoff is not None and (
|
|
287
|
+
isinstance(cutoff, bool) or not isinstance(cutoff, int) or cutoff < 0
|
|
288
|
+
):
|
|
289
|
+
_raise("SESSION_LOG_INVALID", "exported watermark must be null or non-negative")
|
|
290
|
+
return cutoff, header.get("invocation_id")
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def _finish_verification(
|
|
294
|
+
*,
|
|
295
|
+
source: Path,
|
|
296
|
+
event_count: int,
|
|
297
|
+
first_seq_id: int | None,
|
|
298
|
+
last_seq_id: int | None,
|
|
299
|
+
cutoff: int | None,
|
|
300
|
+
filtered: bool,
|
|
301
|
+
) -> SessionLogResult:
|
|
302
|
+
if not filtered:
|
|
303
|
+
if cutoff is None and event_count:
|
|
304
|
+
_raise("SESSION_LOG_INVALID", "empty watermark cannot contain events")
|
|
305
|
+
if cutoff is not None and last_seq_id != cutoff:
|
|
306
|
+
_raise("SESSION_LOG_INVALID", "full session must end at exported watermark")
|
|
307
|
+
return SessionLogResult(
|
|
308
|
+
path=source,
|
|
309
|
+
event_count=event_count,
|
|
310
|
+
first_seq_id=first_seq_id,
|
|
311
|
+
last_seq_id=last_seq_id,
|
|
312
|
+
exported_through_seq_id=cutoff,
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def _verify_v2(stream: TextIO, *, source: Path, header: dict[str, Any]) -> SessionLogResult:
|
|
317
|
+
cutoff, invocation_id = _validate_header(
|
|
318
|
+
header, schema=SESSION_LOG_SCHEMA, version=_SESSION_LOG_VERSION
|
|
319
|
+
)
|
|
320
|
+
filtered = invocation_id is not None
|
|
321
|
+
event_count = 0
|
|
322
|
+
first_seq_id: int | None = None
|
|
323
|
+
last_seq_id: int | None = None
|
|
324
|
+
for line_number, raw in enumerate(stream, start=2):
|
|
325
|
+
if not raw.strip():
|
|
326
|
+
_raise("SESSION_LOG_INVALID", f"line {line_number} is empty")
|
|
327
|
+
try:
|
|
328
|
+
event = parse_runtime_event(_read_json_line(raw, line_number))
|
|
329
|
+
except (TypeError, ValueError) as exc:
|
|
330
|
+
raise SessionLogError(
|
|
331
|
+
f"SESSION_LOG_INVALID: line {line_number} is not a RuntimeEvent/v2"
|
|
332
|
+
) from exc
|
|
333
|
+
if filtered and event.run_id != invocation_id:
|
|
334
|
+
_raise("SESSION_LOG_INVALID", f"line {line_number} run id does not match")
|
|
335
|
+
if last_seq_id is not None and event.seq <= last_seq_id:
|
|
336
|
+
_raise("SESSION_LOG_INVALID", "event seq must be strictly increasing")
|
|
337
|
+
if cutoff is None or event.seq > cutoff:
|
|
338
|
+
_raise("SESSION_LOG_INVALID", "event seq exceeds exported watermark")
|
|
339
|
+
if not filtered:
|
|
340
|
+
expected = 1 if last_seq_id is None else last_seq_id + 1
|
|
341
|
+
if event.seq != expected:
|
|
342
|
+
_raise("SESSION_LOG_INVALID", "full session seq must be continuous")
|
|
343
|
+
event_count += 1
|
|
344
|
+
first_seq_id = first_seq_id or event.seq
|
|
345
|
+
last_seq_id = event.seq
|
|
346
|
+
return _finish_verification(
|
|
347
|
+
source=source,
|
|
348
|
+
event_count=event_count,
|
|
349
|
+
first_seq_id=first_seq_id,
|
|
350
|
+
last_seq_id=last_seq_id,
|
|
351
|
+
cutoff=cutoff,
|
|
352
|
+
filtered=filtered,
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
def _verify_v1(stream: TextIO, *, source: Path, header: dict[str, Any]) -> SessionLogResult:
|
|
357
|
+
cutoff, invocation_id = _validate_header(
|
|
358
|
+
header, schema=_LEGACY_SESSION_LOG_SCHEMA, version=_LEGACY_SESSION_LOG_VERSION
|
|
359
|
+
)
|
|
360
|
+
session_id = str(header["session_id"])
|
|
361
|
+
filtered = invocation_id is not None
|
|
362
|
+
event_count = 0
|
|
363
|
+
first_seq_id: int | None = None
|
|
364
|
+
last_seq_id: int | None = None
|
|
365
|
+
for line_number, raw in enumerate(stream, start=2):
|
|
366
|
+
if not raw.strip():
|
|
367
|
+
_raise("SESSION_LOG_INVALID", f"line {line_number} is empty")
|
|
368
|
+
value = _read_json_line(raw, line_number)
|
|
369
|
+
for event in _legacy_events_from_record(value, line_number, allow_packed=True):
|
|
370
|
+
if event.session_id != session_id:
|
|
371
|
+
_raise("SESSION_LOG_INVALID", f"line {line_number} session id does not match")
|
|
372
|
+
if filtered and event.invocation_id != invocation_id:
|
|
373
|
+
_raise("SESSION_LOG_INVALID", f"line {line_number} invocation id does not match")
|
|
374
|
+
if last_seq_id is not None and event.seq_id <= last_seq_id:
|
|
375
|
+
_raise("SESSION_LOG_INVALID", "event seq_id must be strictly increasing")
|
|
376
|
+
if cutoff is None or event.seq_id > cutoff:
|
|
377
|
+
_raise("SESSION_LOG_INVALID", "event seq_id exceeds exported watermark")
|
|
378
|
+
if not filtered:
|
|
379
|
+
expected = 1 if last_seq_id is None else last_seq_id + 1
|
|
380
|
+
if event.seq_id != expected:
|
|
381
|
+
_raise("SESSION_LOG_INVALID", "full session seq_id must be continuous")
|
|
382
|
+
event_count += 1
|
|
383
|
+
first_seq_id = first_seq_id or event.seq_id
|
|
384
|
+
last_seq_id = event.seq_id
|
|
385
|
+
return _finish_verification(
|
|
386
|
+
source=source,
|
|
387
|
+
event_count=event_count,
|
|
388
|
+
first_seq_id=first_seq_id,
|
|
389
|
+
last_seq_id=last_seq_id,
|
|
390
|
+
cutoff=cutoff,
|
|
391
|
+
filtered=filtered,
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
def verify_session_log(path: Path | str) -> SessionLogResult:
|
|
396
|
+
"""Stream and validate a v2 Session Log or a legacy v1 diagnostic file."""
|
|
397
|
+
source = Path(path)
|
|
398
|
+
try:
|
|
399
|
+
stream = source.open(encoding="utf-8")
|
|
400
|
+
except OSError as exc:
|
|
401
|
+
raise SessionLogError(f"SESSION_LOG_READ_FAILED: {source}") from exc
|
|
402
|
+
with stream:
|
|
403
|
+
first_line = stream.readline()
|
|
404
|
+
if not first_line:
|
|
405
|
+
_raise("SESSION_LOG_INVALID", "missing session header")
|
|
406
|
+
header = _read_json_line(first_line, 1)
|
|
407
|
+
if header.get("schema") == SESSION_LOG_SCHEMA:
|
|
408
|
+
return _verify_v2(stream, source=source, header=header)
|
|
409
|
+
if header.get("schema") == _LEGACY_SESSION_LOG_SCHEMA:
|
|
410
|
+
return _verify_v1(stream, source=source, header=header)
|
|
411
|
+
_raise("SESSION_LOG_INVALID", "unsupported schema")
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
__all__ = [
|
|
415
|
+
"SESSION_LOG_SCHEMA",
|
|
416
|
+
"SessionLogError",
|
|
417
|
+
"SessionLogResult",
|
|
418
|
+
"export_session_log",
|
|
419
|
+
"verify_session_log",
|
|
420
|
+
]
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""Stable UI trajectory projection for canonical RuntimeEvents.
|
|
2
|
+
|
|
3
|
+
The durable store owns only RuntimeEvent/v2 facts. This module derives its
|
|
4
|
+
compact trajectory shape from the Studio v2 projection; it must not reach into
|
|
5
|
+
the read-only RuntimeEvent/v1 compatibility model.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
from ksadk.events.canonical import RuntimeEvent, dump_runtime_event
|
|
14
|
+
from ksadk.studio.run_service import project_runtime_event
|
|
15
|
+
|
|
16
|
+
PROJECTION_VERSION = 1
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _record_id(event: RuntimeEvent, event_type: str, data: dict[str, Any]) -> str:
|
|
20
|
+
if event_type.startswith(("message.", "thinking.")):
|
|
21
|
+
return f"assistant:{data.get('itemId') or event.scope_id}"
|
|
22
|
+
if event_type.startswith(("tool.", "command.")):
|
|
23
|
+
return f"tool:{data.get('callId') or data.get('itemId') or event.event_id}"
|
|
24
|
+
if event_type.startswith("approval."):
|
|
25
|
+
return f"approval:{data.get('approvalId') or data.get('itemId') or event.event_id}"
|
|
26
|
+
if event_type.startswith("checkpoint."):
|
|
27
|
+
return f"checkpoint:{data.get('checkpointId') or data.get('itemId') or event.event_id}"
|
|
28
|
+
if event_type.startswith("a2ui.surface."):
|
|
29
|
+
return f"surface:{data.get('surfaceId') or data.get('itemId') or event.event_id}"
|
|
30
|
+
if event_type.startswith("context.compaction."):
|
|
31
|
+
return f"context:{event.scope_id}:compaction"
|
|
32
|
+
return f"system:{event.event_id}"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _category(event_type: str) -> str:
|
|
36
|
+
if event_type.startswith(("message.", "thinking.")):
|
|
37
|
+
return "assistant"
|
|
38
|
+
if event_type.startswith(("tool.", "command.")):
|
|
39
|
+
return "tool"
|
|
40
|
+
if event_type.startswith("approval."):
|
|
41
|
+
return "approval"
|
|
42
|
+
if event_type.startswith("context.compaction."):
|
|
43
|
+
return "context"
|
|
44
|
+
if event_type.startswith("artifact."):
|
|
45
|
+
return "artifact"
|
|
46
|
+
return "system"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _status(event_type: str, data: dict[str, Any]) -> str | None:
|
|
50
|
+
value = data.get("status")
|
|
51
|
+
if isinstance(value, str) and value:
|
|
52
|
+
return value
|
|
53
|
+
if event_type.endswith((".started", ".delta", ".requested", ".progress")):
|
|
54
|
+
return "running"
|
|
55
|
+
if event_type.endswith((".completed", ".resolved")):
|
|
56
|
+
return "completed"
|
|
57
|
+
if event_type.endswith(".failed"):
|
|
58
|
+
return "failed"
|
|
59
|
+
if event_type.endswith(".cancelled"):
|
|
60
|
+
return "canceled"
|
|
61
|
+
if event_type.endswith(".interrupted"):
|
|
62
|
+
return "interrupted"
|
|
63
|
+
return None
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _summary(event_type: str, data: dict[str, Any]) -> str:
|
|
67
|
+
if event_type.startswith(("message.", "thinking.")):
|
|
68
|
+
return "Message"
|
|
69
|
+
for key in ("tool", "command", "message", "reason", "error"):
|
|
70
|
+
value = data.get(key)
|
|
71
|
+
if isinstance(value, str) and value:
|
|
72
|
+
return value
|
|
73
|
+
return event_type
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def project_trajectory_event(event: RuntimeEvent) -> dict[str, Any]:
|
|
77
|
+
"""Project one immutable v2 fact into the stable trajectory display shape."""
|
|
78
|
+
|
|
79
|
+
event_type, data = project_runtime_event(event)
|
|
80
|
+
details = dict(data)
|
|
81
|
+
details.pop("runtimeEvent", None)
|
|
82
|
+
return {
|
|
83
|
+
"projectionVersion": PROJECTION_VERSION,
|
|
84
|
+
"seqId": event.seq,
|
|
85
|
+
"eventId": event.event_id,
|
|
86
|
+
"recordId": _record_id(event, event_type, details),
|
|
87
|
+
"type": event_type,
|
|
88
|
+
"category": _category(event_type),
|
|
89
|
+
"turnId": None,
|
|
90
|
+
"stepId": None,
|
|
91
|
+
"timestamp": event.timestamp,
|
|
92
|
+
"status": _status(event_type, details),
|
|
93
|
+
"durationMs": details.get("durationMs"),
|
|
94
|
+
"summary": _summary(event_type, details),
|
|
95
|
+
"details": details,
|
|
96
|
+
"source": dump_runtime_event(event),
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def encode_sse(value: dict[str, Any], *, event_id: int) -> str:
|
|
101
|
+
data = json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
|
|
102
|
+
return f"id: {event_id}\nevent: runtime_event\ndata: {data}\n\n"
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
__all__ = ["PROJECTION_VERSION", "encode_sse", "project_trajectory_event"]
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""Prompt 分区与编译数据模型(方案第 7 节)。
|
|
2
|
+
|
|
3
|
+
第一个 PR 只导出稳定类型:``PromptSection`` / ``CompiledPrompt`` / ``PromptProjectionResult``。
|
|
4
|
+
``PromptCompiler`` 的确定性编译、merge、hash、指令文件发现与预算留第二个 PR。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from ksadk.prompts.compiler import (
|
|
8
|
+
InconsistentSectionError,
|
|
9
|
+
PromptCompiler,
|
|
10
|
+
ProtectedSectionOverrideError,
|
|
11
|
+
compile_prompt,
|
|
12
|
+
)
|
|
13
|
+
from ksadk.prompts.models import (
|
|
14
|
+
PROMPT_COMPILER_VERSION,
|
|
15
|
+
CompiledPrompt,
|
|
16
|
+
PromptMergePolicy,
|
|
17
|
+
PromptProjectionResult,
|
|
18
|
+
PromptSection,
|
|
19
|
+
PromptSectionKind,
|
|
20
|
+
PromptStability,
|
|
21
|
+
PromptTrustLevel,
|
|
22
|
+
)
|
|
23
|
+
from ksadk.prompts.resolved import (
|
|
24
|
+
RESOLVED_PROMPT_SOURCES_VERSION,
|
|
25
|
+
EnvPlatformPolicySource,
|
|
26
|
+
PlatformPolicySource,
|
|
27
|
+
ResolvedPromptSources,
|
|
28
|
+
compile_resolved_prompt_dict,
|
|
29
|
+
get_default_platform_policy_source,
|
|
30
|
+
sections_from_resolved_sources,
|
|
31
|
+
)
|
|
32
|
+
from ksadk.prompts.sources import (
|
|
33
|
+
PLATFORM_SAFETY_TEXT,
|
|
34
|
+
agent_identity_section,
|
|
35
|
+
agent_policy_section,
|
|
36
|
+
discover_instruction_files,
|
|
37
|
+
platform_safety_section,
|
|
38
|
+
request_instructions_section,
|
|
39
|
+
resource_manifest_section,
|
|
40
|
+
sections_from_instructions,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
__all__ = [
|
|
44
|
+
"PLATFORM_SAFETY_TEXT",
|
|
45
|
+
"PROMPT_COMPILER_VERSION",
|
|
46
|
+
"RESOLVED_PROMPT_SOURCES_VERSION",
|
|
47
|
+
"CompiledPrompt",
|
|
48
|
+
"EnvPlatformPolicySource",
|
|
49
|
+
"InconsistentSectionError",
|
|
50
|
+
"PlatformPolicySource",
|
|
51
|
+
"PromptCompiler",
|
|
52
|
+
"PromptMergePolicy",
|
|
53
|
+
"PromptProjectionResult",
|
|
54
|
+
"PromptSection",
|
|
55
|
+
"PromptSectionKind",
|
|
56
|
+
"PromptStability",
|
|
57
|
+
"PromptTrustLevel",
|
|
58
|
+
"ProtectedSectionOverrideError",
|
|
59
|
+
"ResolvedPromptSources",
|
|
60
|
+
"agent_identity_section",
|
|
61
|
+
"agent_policy_section",
|
|
62
|
+
"compile_prompt",
|
|
63
|
+
"compile_resolved_prompt_dict",
|
|
64
|
+
"discover_instruction_files",
|
|
65
|
+
"get_default_platform_policy_source",
|
|
66
|
+
"platform_safety_section",
|
|
67
|
+
"request_instructions_section",
|
|
68
|
+
"resource_manifest_section",
|
|
69
|
+
"sections_from_instructions",
|
|
70
|
+
"sections_from_resolved_sources",
|
|
71
|
+
]
|