agentengine-sdk-python 0.8.1__py3-none-any.whl → 0.8.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/METADATA +25 -12
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/RECORD +421 -232
- ksadk/_build_provenance.json +1 -0
- ksadk/a2a/_space_client_events.py +381 -0
- ksadk/a2a/event_adapter.py +156 -64
- ksadk/a2a/executor.py +179 -63
- ksadk/a2a/space_client.py +6 -333
- ksadk/a2ui/core.py +222 -53
- ksadk/agui/_agent_helpers.py +247 -0
- ksadk/agui/a2ui_projection.py +12 -5
- ksadk/agui/agent.py +443 -259
- ksadk/api/client.py +528 -27
- ksadk/builders/code_builder.py +284 -8
- ksadk/builders/container_builder.py +8 -1
- ksadk/builders/managed_runtime_builder.py +42 -35
- ksadk/cli/__init__.py +23 -0
- ksadk/cli/cmd_dashboard.py +15 -1
- ksadk/cli/cmd_deploy.py +10 -2
- ksadk/cli/cmd_eval.py +66 -9
- ksadk/cli/cmd_evalset.py +284 -0
- ksadk/cli/cmd_files.py +5 -1
- ksadk/cli/cmd_hermes.py +1 -126
- ksadk/cli/cmd_invoke.py +28 -38
- ksadk/cli/cmd_managed_runtime.py +95 -0
- ksadk/cli/cmd_observe.py +85 -0
- ksadk/cli/cmd_openclaw.py +1 -435
- ksadk/cli/cmd_plugin.py +657 -0
- ksadk/cli/cmd_replay.py +28 -4
- ksadk/cli/cmd_studio.py +99 -8
- ksadk/cli/cmd_web.py +10 -2
- ksadk/cli/hermes_env.py +151 -0
- ksadk/cli/invoke_payload.py +49 -0
- ksadk/cli/openclaw_env.py +458 -0
- ksadk/codex/client.py +180 -30
- ksadk/codex/runtime.py +475 -331
- ksadk/configs/env_registry.py +94 -12
- ksadk/configs/env_registry_pcm.py +181 -0
- ksadk/configs/env_var_spec.py +18 -0
- ksadk/configs/global_config.py +5 -0
- ksadk/configs/settings.py +9 -0
- ksadk/context_engine/__init__.py +98 -0
- ksadk/context_engine/assembler.py +176 -0
- ksadk/context_engine/baseline.py +419 -0
- ksadk/context_engine/cache_observability.py +228 -0
- ksadk/context_engine/capabilities.py +443 -0
- ksadk/context_engine/contributors.py +409 -0
- ksadk/context_engine/hosted_pipeline.py +417 -0
- ksadk/context_engine/models.py +117 -0
- ksadk/context_engine/planner.py +698 -0
- ksadk/context_engine/policies.py +319 -0
- ksadk/context_engine/projection.py +31 -0
- ksadk/context_engine/shadow_plan.py +266 -0
- ksadk/context_engine/tokenizer.py +164 -0
- ksadk/conversations/__init__.py +19 -0
- ksadk/conversations/context.py +230 -30
- ksadk/conversations/contracts.py +266 -0
- ksadk/conversations/message_projection.py +308 -26
- ksadk/conversations/model_context.py +49 -3
- ksadk/conversations/projector.py +616 -0
- ksadk/conversations/reducer.py +98 -0
- ksadk/conversations/runtime_compaction.py +207 -5
- ksadk/conversations/runtime_input.py +184 -2
- ksadk/conversations/runtime_invocation.py +81 -3
- ksadk/conversations/runtime_observability.py +141 -0
- ksadk/conversations/runtime_payloads.py +42 -0
- ksadk/conversations/runtime_preparation.py +272 -2
- ksadk/conversations/runtime_resume.py +20 -1
- ksadk/conversations/runtime_stream_events.py +94 -9
- ksadk/conversations/semantic_summary.py +311 -1
- ksadk/conversations/session_lock.py +51 -0
- ksadk/deployment/env_forward.py +72 -0
- ksadk/deployment/managed_runtime.py +5 -0
- ksadk/deployment/providers/serverless.py +143 -69
- ksadk/evaluation/__init__.py +32 -0
- ksadk/evaluation/a2a_adapter.py +9 -1
- ksadk/evaluation/adapters.py +18 -5
- ksadk/evaluation/agent_eval_client.py +395 -0
- ksadk/evaluation/cloud_binding.py +80 -0
- ksadk/evaluation/cloud_converter.py +194 -0
- ksadk/evaluation/cloud_service.py +199 -0
- ksadk/evaluation/contracts.py +73 -4
- ksadk/evaluation/evaluators.py +183 -17
- ksadk/evaluation/evidence.py +258 -0
- ksadk/evaluation/executor.py +31 -6
- ksadk/evaluation/local_adapter.py +550 -0
- ksadk/evaluation/service_env.py +27 -0
- ksadk/evaluation/studio_build_adapter.py +253 -0
- ksadk/evaluation/target.py +15 -6
- ksadk/events/__init__.py +13 -13
- ksadk/events/_v1_compat/__init__.py +1 -0
- ksadk/events/_v1_compat/models.py +299 -0
- ksadk/events/_v1_compat/parser.py +247 -0
- ksadk/events/_v1_compat/projection.py +755 -0
- ksadk/events/adapters/__init__.py +34 -0
- ksadk/events/adapters/_a2a_snapshot.py +622 -0
- ksadk/events/adapters/_a2a_support.py +275 -0
- ksadk/events/adapters/_codex_interactions.py +375 -0
- ksadk/events/adapters/_codex_items.py +801 -0
- ksadk/events/adapters/_codex_validators.py +311 -0
- ksadk/events/adapters/_langgraph_support.py +785 -0
- ksadk/events/adapters/a2a.py +841 -0
- ksadk/events/adapters/adk.py +503 -0
- ksadk/events/adapters/codex.py +907 -0
- ksadk/events/adapters/langgraph.py +745 -0
- ksadk/events/canonical.py +440 -0
- ksadk/events/canonical_replay.py +497 -0
- ksadk/events/canonical_store.py +468 -0
- ksadk/events/cold_recovery.py +257 -0
- ksadk/events/content.py +89 -0
- ksadk/events/identity.py +86 -0
- ksadk/events/pipeline.py +455 -0
- ksadk/events/projections.py +66 -0
- ksadk/events/reducer.py +661 -0
- ksadk/events/replay.py +3 -36
- ksadk/events/runtime_event.py +20 -265
- ksadk/events/session_event.py +324 -0
- ksadk/events/store.py +3 -316
- ksadk/events/v1_compat.py +41 -0
- ksadk/harness/__init__.py +45 -35
- ksadk/harness/runtime.py +220 -58
- ksadk/identity/resolver.py +4 -3
- ksadk/interaction/__init__.py +28 -0
- ksadk/interaction/contracts.py +136 -0
- ksadk/interaction/ledger.py +189 -0
- ksadk/interaction/provider.py +122 -0
- ksadk/interaction/providers/__init__.py +52 -0
- ksadk/interaction/providers/adk.py +40 -0
- ksadk/interaction/providers/codex.py +94 -0
- ksadk/interaction/providers/langgraph.py +58 -0
- ksadk/kernel/__init__.py +117 -0
- ksadk/kernel/authorization.py +258 -0
- ksadk/kernel/bootstrap.py +1074 -0
- ksadk/kernel/contract_fingerprints.py +62 -0
- ksadk/kernel/contracts.py +370 -0
- ksadk/kernel/control.py +220 -0
- ksadk/kernel/errors.py +79 -0
- ksadk/kernel/ingress.py +1123 -0
- ksadk/kernel/mapping.py +111 -0
- ksadk/kernel/memory_store.py +1134 -0
- ksadk/kernel/postgres_store.py +1757 -0
- ksadk/kernel/recovery.py +452 -0
- ksadk/kernel/runtime_identity.py +103 -0
- ksadk/kernel/sql/001_agent_kernel.sql +120 -0
- ksadk/kernel/sqlite_store.py +1411 -0
- ksadk/kernel/state.py +145 -0
- ksadk/kernel/store.py +232 -0
- ksadk/kernel/worker.py +964 -0
- ksadk/knowledge_base/client.py +7 -0
- ksadk/knowledge_base/service.py +32 -5
- ksadk/memory/__init__.py +61 -0
- ksadk/memory/adk/backends/base_ltm_backend.py +96 -1
- ksadk/memory/adk/backends/http_ltm_backend.py +14 -5
- ksadk/memory/adk/backends/inmemory_ltm_backend.py +136 -3
- ksadk/memory/adk/backends/sdk_ltm_backend.py +384 -2
- ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
- ksadk/memory/coordinator.py +461 -0
- ksadk/memory/events.py +202 -0
- ksadk/memory/extraction.py +228 -0
- ksadk/memory/ltm_backend_factory.py +16 -3
- ksadk/memory/models.py +316 -0
- ksadk/memory/policy.py +215 -0
- ksadk/memory/provider.py +47 -0
- ksadk/memory/provider_adapter.py +159 -0
- ksadk/memory/provider_resolver.py +71 -0
- ksadk/memory/providers/__init__.py +5 -0
- ksadk/memory/providers/local_sqlite.py +497 -0
- ksadk/memory/resolved_policy.py +145 -0
- ksadk/memory/service.py +188 -6
- ksadk/model_proxy/bootstrap.py +16 -9
- ksadk/model_proxy/detect.py +202 -9
- ksadk/model_proxy/namespace.py +39 -15
- ksadk/model_proxy/server.py +24 -5
- ksadk/model_proxy/transform.py +60 -2
- ksadk/observability/__init__.py +25 -0
- ksadk/observability/session_log.py +420 -0
- ksadk/observability/trajectory.py +105 -0
- ksadk/plugins/__init__.py +167 -0
- ksadk/plugins/bridges/__init__.py +45 -0
- ksadk/plugins/bridges/codex.py +552 -0
- ksadk/plugins/bridges/dsh.py +1116 -0
- ksadk/plugins/builtins.py +747 -0
- ksadk/plugins/bundle.py +246 -0
- ksadk/plugins/bundle_security.py +167 -0
- ksadk/plugins/composition.py +529 -0
- ksadk/plugins/context_contributor.py +437 -0
- ksadk/plugins/contracts.py +451 -0
- ksadk/plugins/dsh_toolchain.py +935 -0
- ksadk/plugins/ecosystem_bridge.py +1105 -0
- ksadk/plugins/ecosystem_probe.py +191 -0
- ksadk/plugins/host.py +724 -0
- ksadk/plugins/providers/__init__.py +85 -0
- ksadk/plugins/providers/bundles/ksadk-codex/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +18 -0
- ksadk/plugins/providers/bundles/ksadk-codex/package.json +19 -0
- ksadk/plugins/providers/bundles/ksadk-harness/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +19 -0
- ksadk/plugins/providers/bundles/ksadk-harness/package.json +19 -0
- ksadk/plugins/providers/codex.py +722 -0
- ksadk/plugins/providers/codex_dsh.py +83 -0
- ksadk/plugins/providers/dsh.py +951 -0
- ksadk/plugins/providers/dsh_descriptor_host.py +226 -0
- ksadk/plugins/providers/harness.py +627 -0
- ksadk/plugins/providers/harness_dsh.py +91 -0
- ksadk/plugins/providers/legacy.py +215 -0
- ksadk/plugins/providers/legacy_catalog.py +100 -0
- ksadk/plugins/providers/shipped_dsh.py +370 -0
- ksadk/plugins/resolver.py +331 -0
- ksadk/plugins/subagent_providers/__init__.py +12 -0
- ksadk/plugins/subagent_providers/codex.py +443 -0
- ksadk/plugins/subagents.py +333 -0
- ksadk/prompts/__init__.py +71 -0
- ksadk/prompts/compiler.py +215 -0
- ksadk/prompts/models.py +82 -0
- ksadk/prompts/projection.py +89 -0
- ksadk/prompts/resolved.py +137 -0
- ksadk/prompts/sources.py +233 -0
- ksadk/runners/_langgraph_runner_streams.py +822 -0
- ksadk/runners/adk_runner.py +5 -5
- ksadk/runners/base_runner.py +16 -0
- ksadk/runners/factory.py +1 -2
- ksadk/runners/langgraph_runner.py +198 -437
- ksadk/runtime/_runner_adapter/__init__.py +1 -0
- ksadk/runtime/_runner_adapter/stream_mapping.py +797 -0
- ksadk/runtime/adapter.py +119 -2
- ksadk/runtime/conversation_execution.py +316 -182
- ksadk/runtime/executor.py +144 -3
- ksadk/runtime/factory.py +268 -8
- ksadk/runtime/framework_adapters.py +18 -0
- ksadk/runtime/hosted_finalizer.py +268 -0
- ksadk/runtime/launch.py +14 -1
- ksadk/runtime/preprocessing.py +25 -3
- ksadk/runtime/runner_adapter.py +293 -508
- ksadk/runtime/usage.py +33 -0
- ksadk/sandbox/__init__.py +2 -1
- ksadk/sandbox/backends/e2b.py +35 -2
- ksadk/sandbox/factory.py +72 -0
- ksadk/scheduler/__init__.py +18 -0
- ksadk/scheduler/calendar.py +102 -0
- ksadk/scheduler/contracts.py +254 -0
- ksadk/scheduler/dispatcher.py +129 -0
- ksadk/scheduler/engine.py +416 -0
- ksadk/scheduler/sqlite_store.py +563 -0
- ksadk/server/composition.py +8 -0
- ksadk/server/factory.py +69 -6
- ksadk/server/routes/kernel_ingress.py +258 -0
- ksadk/server/routes/openai_compat.py +88 -8
- ksadk/server/routes/projection.py +35 -20
- ksadk/server/routes/run.py +94 -0
- ksadk/server/routes/sessions.py +2 -0
- ksadk/server/routes/streaming.py +5 -2
- ksadk/server/static/assets/{ArtifactsPanel-CakCqxEN.js → ArtifactsPanel-10GPXIJ6.js} +1 -1
- ksadk/server/static/assets/{CodeBlock-CynLknyO.js → CodeBlock-BXk1l-G1.js} +4 -4
- ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
- ksadk/server/static/assets/{MathMessageMarkdown-3sQdOysS.js → MathMessageMarkdown-D9uB55Oh.js} +4 -4
- ksadk/server/static/assets/MermaidBlock--OEYoXIJ.js +312 -0
- ksadk/server/static/assets/NativeTerminalPanel-DrEe1syq.js +1 -0
- ksadk/server/static/assets/abnfDiagram-VCTEODGH-eeTFJLvo.js +1 -0
- ksadk/server/static/assets/arc-S3ZNbIAd.js +1 -0
- ksadk/server/static/assets/architecture-7GRP2DOG-Dk9nRQ6-.js +1 -0
- ksadk/server/static/assets/architectureDiagram-5GKGNRK7-CRjgEJDX.js +36 -0
- ksadk/server/static/assets/blockDiagram-NRAW4CY4-C7bsBoNH.js +129 -0
- ksadk/server/static/assets/c4Diagram-UCG6FXSJ-BX3c33Ob.js +38 -0
- ksadk/server/static/assets/channel-s354Yo6o.js +1 -0
- ksadk/server/static/assets/chunk-2Q5K7J3B-CDpPpKR5.js +1 -0
- ksadk/server/static/assets/{chunk-FMBD7UC4-B_fH2YuH.js → chunk-5VM5RSS4-bZ7ws-8m.js} +1 -1
- ksadk/server/static/assets/{chunk-ND2GUHAM-D6rFLaVV.js → chunk-F27PBJKO-D2r0pvhY.js} +1 -1
- ksadk/server/static/assets/chunk-G27WJ6UU-CZwF3oUP.js +231 -0
- ksadk/server/static/assets/{chunk-4BX2VUAB-B9drTgOW.js → chunk-JWPE2WC7-DigFYCML.js} +1 -1
- ksadk/server/static/assets/chunk-LCL6LL3I-CnorGV5q.js +206 -0
- ksadk/server/static/assets/chunk-POPQ4Y6H-CexntQA-.js +1 -0
- ksadk/server/static/assets/chunk-RHFEMEQ7-CHTC7UxA.js +168 -0
- ksadk/server/static/assets/chunk-SVP7TREG-BC1EWt_-.js +88 -0
- ksadk/server/static/assets/chunk-XXDRQBXY-BTG24xN0.js +1 -0
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-Dd0nucl9.js +1 -0
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Dd0nucl9.js +1 -0
- ksadk/server/static/assets/{cose-bilkent-S5V4N54A-ChNs_Mdk.js → cose-bilkent-JH36ORCC-CkonRdAS.js} +1 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-BBlT4uMf.js +1 -0
- ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-DEOCBe15.js +62 -0
- ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
- ksadk/server/static/assets/dagre-3AP2YEHR-DBThPuLa.js +4 -0
- ksadk/server/static/assets/dagre-ClTPrTht.js +1 -0
- ksadk/server/static/assets/diagram-S7CK7UJ4-DsZHrnpJ.js +30 -0
- ksadk/server/static/assets/diagram-UQ7AKVKN-BJR4nhVr.js +41 -0
- ksadk/server/static/assets/diagram-VSXAHHWV-xzcERX0a.js +3 -0
- ksadk/server/static/assets/diagram-VX7I27RA-tn2xM1xu.js +24 -0
- ksadk/server/static/assets/diagram-Z3DM3KII-BZPGBkw5.js +24 -0
- ksadk/server/static/assets/{dist-gLnrGsoU.js → dist-4zN1_tq5.js} +1 -1
- ksadk/server/static/assets/{dist-C1sz5Eo3.js → dist-8VWI-2bZ.js} +1 -1
- ksadk/server/static/assets/{dist-BjOdlDjj.js → dist-B-46q3Hk.js} +1 -1
- ksadk/server/static/assets/{dist-o2OVmKvt.js → dist-B0gdk4rl.js} +1 -1
- ksadk/server/static/assets/{dist-4N2NMVYg.js → dist-B1oWRmrH.js} +1 -1
- ksadk/server/static/assets/{dist-CmZHzlwZ.js → dist-BI1qQH4n.js} +1 -1
- ksadk/server/static/assets/{dist-X4TnqwOK.js → dist-BJLUwH6W.js} +1 -1
- ksadk/server/static/assets/{dist-B5oS1zcj.js → dist-Bbwqa8TG.js} +1 -1
- ksadk/server/static/assets/{dist-j6Dxmf_j.js → dist-Btyo4vX4.js} +1 -1
- ksadk/server/static/assets/{dist-DQU9EWw-.js → dist-C71CsujO.js} +1 -1
- ksadk/server/static/assets/{dist-BIlKoW0k.js → dist-CXpH_Rdd.js} +1 -1
- ksadk/server/static/assets/{dist-DJN_6Y39.js → dist-Cq4OL6nO.js} +1 -1
- ksadk/server/static/assets/{dist-Dli7qW-B.js → dist-D1V3f1B4.js} +1 -1
- ksadk/server/static/assets/{dist-fhOuWds5.js → dist-DJmCPRVB.js} +1 -1
- ksadk/server/static/assets/{dist-CWV4lDr1.js → dist-DQAB0qn_.js} +2 -2
- ksadk/server/static/assets/{dist-D6MpCZtz.js → dist-DUwKa_l6.js} +1 -1
- ksadk/server/static/assets/dist-DdRBIceA.js +1 -0
- ksadk/server/static/assets/{dist-DWKByxWV.js → dist-DfGFrb0v.js} +1 -1
- ksadk/server/static/assets/{dist-DsHPdk3W.js → dist-DjhwGUgZ.js} +1 -1
- ksadk/server/static/assets/{dist-B-jNR6Vn.js → dist-DyqV4fL4.js} +1 -1
- ksadk/server/static/assets/{dist-BB3-OwTQ.js → dist-M67Hwu0n.js} +1 -1
- ksadk/server/static/assets/{dist-_pHPTyZ-.js → dist-u8tVH5Ak.js} +1 -1
- ksadk/server/static/assets/ebnfDiagram-PWID7BFC-DVfMsLge.js +1 -0
- ksadk/server/static/assets/erDiagram-SSCWMZ5O-CWEZSYaw.js +99 -0
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-Dr5okd8V.js +1 -0
- ksadk/server/static/assets/flowDiagram-A5DVABFB-VEO-cVcO.js +1 -0
- ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-TWIxoyYL.js +292 -0
- ksadk/server/static/assets/gitGraph-4MIJSDKK-CKiKY9Cf.js +1 -0
- ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-DDh2hd2S.js +106 -0
- ksadk/server/static/assets/index-B2k_urY8.js +241 -0
- ksadk/server/static/assets/index-ILPt6IWF.css +2 -0
- ksadk/server/static/assets/info-A6RAGUB7-ubA4Nm_p.js +1 -0
- ksadk/server/static/assets/infoDiagram-RXCK75RN-CgoyWiDR.js +2 -0
- ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-K0OOfVna.js → ishikawaDiagram-5VMMS53U-CyRIu_om.js} +6 -6
- ksadk/server/static/assets/{journeyDiagram-JHISSGLW-8LeOJaZp.js → journeyDiagram-EYS64GPL-DN5JXHzN.js} +6 -6
- ksadk/server/static/assets/{kanban-definition-UN3LZRKU-C6uCgZrW.js → kanban-definition-3QL26DDD-CNP3ui66.js} +10 -10
- ksadk/server/static/assets/katex-DWEzQy1d.js +257 -0
- ksadk/server/static/assets/{linear-hdBcYzM8.js → linear-C-qHp7d2.js} +1 -1
- ksadk/server/static/assets/mermaid-parser.core-Cl-K943T.js +166 -0
- ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-Bjy_2v4_.js → mindmap-definition-FBJOCRG2-D5DB5mYm.js} +29 -29
- ksadk/server/static/assets/packet-AYTQ26CC-C7R3NUlK.js +1 -0
- ksadk/server/static/assets/pegDiagram-XKGWAZYB-BQVc9ia_.js +1 -0
- ksadk/server/static/assets/pie-WAS4IAKB-BIT6qjr3.js +1 -0
- ksadk/server/static/assets/pieDiagram-E7YTZNPT-B6UCAvtY.js +39 -0
- ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-BmkRbwCg.js → quadrantDiagram-AXDQQJYC-mIr2d3eb.js} +6 -6
- ksadk/server/static/assets/radar-RG4KPBEZ-l5noef9X.js +1 -0
- ksadk/server/static/assets/railroad-74A4TZTK-Baea6ZvM.js +1 -0
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-OKn8zZnU.js +1 -0
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-DdKAKC4l.js +1 -0
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-Bds8udlG.js +1 -0
- ksadk/server/static/assets/railroadDiagram-O6MQD6OU-Dt3FFDmK.js +1 -0
- ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-Cz_vQtgF.js +84 -0
- ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-l6iXmU65.js → sankeyDiagram-P5KCCOFB-wlO1TsH5.js} +7 -7
- ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-Cq6UBeQB.js → sequenceDiagram-WJ2MYXX4-CHRbElYq.js} +10 -10
- ksadk/server/static/assets/sizeCapture-X5ZJPWSS-DXX54iyO.js +1 -0
- ksadk/server/static/assets/stateDiagram-HBIQ2CUA-Dp_lw9II.js +1 -0
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-5b-8o2iS.js +1 -0
- ksadk/server/static/assets/swimlanes-XN3QIQJK-D8O5UlLG.js +1 -0
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uf6WPRA4.js +8 -0
- ksadk/server/static/assets/{timeline-definition-PNZ67QCA-DEz24vV0.js → timeline-definition-24CTP7MA-8mfKcxvG.js} +7 -7
- ksadk/server/static/assets/treeView-Q6P3EWNA-CK5CSrSO.js +1 -0
- ksadk/server/static/assets/treemap-WGGIJYW6-Ch2BKgAM.js +1 -0
- ksadk/server/static/assets/vennDiagram-4TSXK5OY-EnNl0DE7.js +34 -0
- ksadk/server/static/assets/wardley-WFR3VGLG-YW3Q0ml_.js +1 -0
- ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DBu5fbYr.js +78 -0
- ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-BSVXs4IY.js +7 -0
- ksadk/server/static/index.html +2 -2
- ksadk/sessions/__init__.py +26 -9
- ksadk/sessions/_local_service_sync.py +688 -0
- ksadk/sessions/_local_tables.py +21 -0
- ksadk/sessions/_postgres_schema.py +305 -0
- ksadk/sessions/_postgres_tables.py +15 -0
- ksadk/sessions/base.py +80 -1
- ksadk/sessions/in_memory.py +53 -2
- ksadk/sessions/local_service.py +63 -604
- ksadk/sessions/postgres_service.py +58 -148
- ksadk/sessions/resilient.py +35 -1
- ksadk/skills/service_client.py +48 -0
- ksadk/studio/agent_lifecycle.py +26 -20
- ksadk/studio/api.py +1063 -69
- ksadk/studio/api_catalog_routes.py +5 -0
- ksadk/studio/api_contracts.py +148 -6
- ksadk/studio/api_memory_routes.py +82 -0
- ksadk/studio/api_plugin_routes.py +480 -0
- ksadk/studio/attachment_store.py +187 -0
- ksadk/studio/authoring.py +259 -28
- ksadk/studio/authoring_coordinator.py +809 -67
- ksadk/studio/builder.py +197 -40
- ksadk/studio/capabilities.py +17 -0
- ksadk/studio/cloud.py +1920 -95
- ksadk/studio/codex_agent_service.py +137 -15
- ksadk/studio/codex_authoring.py +469 -0
- ksadk/studio/codex_builder.py +177 -25
- ksadk/studio/codex_manifest.py +71 -22
- ksadk/studio/codex_run.py +59 -4
- ksadk/studio/compatibility_report.py +445 -0
- ksadk/studio/compiler.py +7 -1
- ksadk/studio/contracts.py +234 -4
- ksadk/studio/dsh_provider_registration.py +768 -0
- ksadk/studio/event_store.py +79 -101
- ksadk/studio/framework_run.py +264 -3
- ksadk/studio/hosted_kernel.py +317 -0
- ksadk/studio/manifest_resolver.py +131 -0
- ksadk/studio/model_client.py +95 -9
- ksadk/studio/model_profile_service.py +1 -1
- ksadk/studio/operations.py +47 -5
- ksadk/studio/otel_trace.py +348 -42
- ksadk/studio/pcm_memory.py +85 -0
- ksadk/studio/plugin_composition.py +301 -0
- ksadk/studio/plugin_kernel_adapter.py +128 -0
- ksadk/studio/plugin_runtime.py +652 -0
- ksadk/studio/repository.py +23 -2
- ksadk/studio/resource_catalog.py +49 -1
- ksadk/studio/run_service.py +1266 -202
- ksadk/studio/runtime_source.py +51 -17
- ksadk/studio/scheduler_runtime.py +374 -0
- ksadk/studio/scheduler_service.py +211 -0
- ksadk/studio/service.py +1815 -117
- ksadk/studio/shared_web.py +199 -50
- ksadk/studio/soul.py +52 -0
- ksadk/studio/static/assets/index-DXs1Eq4M.css +1 -0
- ksadk/studio/static/assets/index-DeDqwTsD.js +283 -0
- ksadk/studio/static/index.html +2 -2
- ksadk/studio/templates.py +100 -8
- ksadk/studio/validator.py +20 -1
- ksadk/studio/workspace.py +31 -32
- ksadk/tracing/setup.py +304 -3
- ksadk/version.py +1 -1
- ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
- ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
- ksadk_runtime_common/workspace_files/path_utils.py +41 -0
- ksadk/events/parser.py +0 -191
- ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
- ksadk/server/static/assets/MermaidBlock-NERD_ef7.js +0 -303
- ksadk/server/static/assets/NativeTerminalPanel-CiHWf82q.js +0 -1
- ksadk/server/static/assets/arc-DrgjcKhl.js +0 -1
- ksadk/server/static/assets/architecture-7EHR7CIX-CpZLRCcY.js +0 -1
- ksadk/server/static/assets/architectureDiagram-3BPJPVTR-BXoVRbQ6.js +0 -36
- ksadk/server/static/assets/blockDiagram-GPEHLZMM-BnaB3Ywv.js +0 -132
- ksadk/server/static/assets/c4Diagram-AAUBKEIU-Dw4weZcp.js +0 -10
- ksadk/server/static/assets/channel-Dt3rQTFI.js +0 -1
- ksadk/server/static/assets/chunk-2J33WTMH-ChjpLK7j.js +0 -1
- ksadk/server/static/assets/chunk-55IACEB6-CK4ROATy.js +0 -1
- ksadk/server/static/assets/chunk-727SXJPM-B9KtTTgw.js +0 -206
- ksadk/server/static/assets/chunk-AQP2D5EJ-1O1mki3m.js +0 -231
- ksadk/server/static/assets/chunk-QZHKN3VN-iXEZtKQc.js +0 -1
- ksadk/server/static/assets/classDiagram-4FO5ZUOK-DIveV17Q.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-DIveV17Q.js +0 -1
- ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
- ksadk/server/static/assets/dagre-BM42HDAG-D0QXg_MQ.js +0 -4
- ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
- ksadk/server/static/assets/diagram-2AECGRRQ-DBDDKwBQ.js +0 -43
- ksadk/server/static/assets/diagram-5GNKFQAL-BkwDOxmO.js +0 -10
- ksadk/server/static/assets/diagram-KO2AKTUF-Bv8waYvY.js +0 -3
- ksadk/server/static/assets/diagram-LMA3HP47-e1VECDdu.js +0 -24
- ksadk/server/static/assets/diagram-OG6HWLK6-Ds9adfRl.js +0 -24
- ksadk/server/static/assets/dist-B5J2uhNk.js +0 -1
- ksadk/server/static/assets/erDiagram-TEJ5UH35-BPItFKH6.js +0 -85
- ksadk/server/static/assets/eventmodeling-FCH6USID-DYFSxbqr.js +0 -1
- ksadk/server/static/assets/flowDiagram-I6XJVG4X-BbYB9w5Y.js +0 -162
- ksadk/server/static/assets/ganttDiagram-6RSMTGT7-TQXa0KXv.js +0 -292
- ksadk/server/static/assets/gitGraph-WXDBUCRP-DyNYp6BN.js +0 -1
- ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-bKblCnpa.js +0 -106
- ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
- ksadk/server/static/assets/index-R52pJJvg.js +0 -177
- ksadk/server/static/assets/index-jJr3_955.css +0 -2
- ksadk/server/static/assets/info-J43DQDTF-WUx7qTde.js +0 -1
- ksadk/server/static/assets/infoDiagram-5YYISTIA-BGVT7J_i.js +0 -2
- ksadk/server/static/assets/katex-CYWseY5E.js +0 -265
- ksadk/server/static/assets/mermaid-parser.core-BWrDjSZM.js +0 -161
- ksadk/server/static/assets/packet-YPE3B663-BN13y_xl.js +0 -1
- ksadk/server/static/assets/pie-LRSECV5Y-ftSLXhhc.js +0 -1
- ksadk/server/static/assets/pieDiagram-4H26LBE5-GmmqNiVH.js +0 -30
- ksadk/server/static/assets/radar-GUYGQ44K-jaICkIeO.js +0 -1
- ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DSWFqL7c.js +0 -84
- ksadk/server/static/assets/stateDiagram-AJRCARHV-qzTQpg3Y.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-BYCoYGAN.js +0 -1
- ksadk/server/static/assets/treeView-BLDUP644-Cpib_vlz.js +0 -1
- ksadk/server/static/assets/treemap-LRROVOQU-DQxfmVHK.js +0 -1
- ksadk/server/static/assets/vennDiagram-CIIHVFJN-CMCixki2.js +0 -34
- ksadk/server/static/assets/wardley-L42UT6IY-BQYHnnkU.js +0 -1
- ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-CVzB8F9K.js +0 -78
- ksadk/server/static/assets/xychartDiagram-2RQKCTM6-BFBqBLc1.js +0 -7
- ksadk/studio/evaluation.py +0 -192
- ksadk/studio/static/assets/index-CaEN0eTR.css +0 -1
- ksadk/studio/static/assets/index-DI2eY_NH.js +0 -252
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/WHEEL +0 -0
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/top_level.txt +0 -0
ksadk/server/factory.py
CHANGED
|
@@ -194,6 +194,7 @@ class RuntimeAppConfig:
|
|
|
194
194
|
agui: Optional[Any] = None,
|
|
195
195
|
runtime_executor: RuntimeExecutor | None = None,
|
|
196
196
|
launch_context: RuntimeLaunchContext | None = None,
|
|
197
|
+
kernel_adapter_provider: Callable[[], RuntimeAdapter] | None = None,
|
|
197
198
|
session_service_provider: Callable[[], Any] | None = None,
|
|
198
199
|
session_backend_provider: Callable[[], dict[str, Any]] | None = None,
|
|
199
200
|
) -> None:
|
|
@@ -208,6 +209,9 @@ class RuntimeAppConfig:
|
|
|
208
209
|
self.agui = agui
|
|
209
210
|
self.runtime_executor = runtime_executor
|
|
210
211
|
self.launch_context = launch_context
|
|
212
|
+
# 特殊 runtime 可显式提供 worker/recovery 的 adapter;常规部署从
|
|
213
|
+
# runtime_executor 的同一 registry 派生,见 _kernel_adapter_provider。
|
|
214
|
+
self.kernel_adapter_provider = kernel_adapter_provider
|
|
211
215
|
self.session_service_provider = session_service_provider
|
|
212
216
|
self.session_backend_provider = session_backend_provider
|
|
213
217
|
|
|
@@ -353,6 +357,40 @@ def create_runtime_app(
|
|
|
353
357
|
|
|
354
358
|
@asynccontextmanager
|
|
355
359
|
async def _lifespan(app: FastAPI) -> AsyncIterator[None]:
|
|
360
|
+
# 生产 kernel 的 composition root 必须启动 worker/lease/recovery,
|
|
361
|
+
# 不能只注册一个可接收命令、却永远不会消费的 ingress kernel。
|
|
362
|
+
from ksadk.kernel import ingress as _kernel_ingress
|
|
363
|
+
from ksadk.kernel.bootstrap import (
|
|
364
|
+
bootstrap_agent_kernel_runtime_from_env,
|
|
365
|
+
clear_agent_kernel_runtime,
|
|
366
|
+
)
|
|
367
|
+
from ksadk.runtime.factory import kernel_start_request_defaults
|
|
368
|
+
|
|
369
|
+
adapter_provider = _kernel_adapter_provider(config)
|
|
370
|
+
request_defaults = (
|
|
371
|
+
kernel_start_request_defaults(config.launch_context)
|
|
372
|
+
if config.launch_context is not None
|
|
373
|
+
else {}
|
|
374
|
+
)
|
|
375
|
+
kernel_runtime = await bootstrap_agent_kernel_runtime_from_env(
|
|
376
|
+
adapter_provider=adapter_provider,
|
|
377
|
+
runtime_executor=config.runtime_executor,
|
|
378
|
+
launch_context=config.launch_context,
|
|
379
|
+
start_request_defaults=request_defaults,
|
|
380
|
+
session_service=state.resolve_session_service(),
|
|
381
|
+
)
|
|
382
|
+
app.state.agent_kernel_runtime = kernel_runtime
|
|
383
|
+
if kernel_runtime is not None:
|
|
384
|
+
# Kernel canonical events are the replay authority for the normal
|
|
385
|
+
# Session APIs as well. In memory/ephemeral mode bootstrap reuses
|
|
386
|
+
# the app-owned service above; in PostgreSQL mode it owns the
|
|
387
|
+
# durable service and the HTTP routes must adopt that exact one.
|
|
388
|
+
# Keeping two services made foreground SSE look correct while a
|
|
389
|
+
# later ListSessionEvents call returned an empty history forever.
|
|
390
|
+
kernel_session_service = kernel_runtime.config.session_service
|
|
391
|
+
if kernel_session_service is None: # pragma: no cover - defensive
|
|
392
|
+
raise RuntimeError("agent kernel runtime has no Session service")
|
|
393
|
+
state.session_service = kernel_session_service
|
|
356
394
|
try:
|
|
357
395
|
if state.a2a_bootstrap is not None:
|
|
358
396
|
await state.a2a_bootstrap.start()
|
|
@@ -360,6 +398,10 @@ def create_runtime_app(
|
|
|
360
398
|
finally:
|
|
361
399
|
if state.a2a_bootstrap is not None:
|
|
362
400
|
await state.a2a_bootstrap.stop()
|
|
401
|
+
if kernel_runtime is not None:
|
|
402
|
+
await kernel_runtime.close()
|
|
403
|
+
clear_agent_kernel_runtime()
|
|
404
|
+
_kernel_ingress.clear_agent_kernel()
|
|
363
405
|
await shutdown_runtime_resources(state)
|
|
364
406
|
|
|
365
407
|
app = FastAPI(
|
|
@@ -488,6 +530,25 @@ def create_runtime_app(
|
|
|
488
530
|
return app
|
|
489
531
|
|
|
490
532
|
|
|
533
|
+
def _kernel_adapter_provider(
|
|
534
|
+
config: RuntimeAppConfig,
|
|
535
|
+
) -> Callable[[], RuntimeAdapter] | None:
|
|
536
|
+
"""Return the adapter source used by the durable kernel runtime.
|
|
537
|
+
|
|
538
|
+
Hosted startup deliberately fails when neither a provider nor a Runtime
|
|
539
|
+
launch context is available. It must never construct an unrelated local
|
|
540
|
+
adapter merely to make the ingress look healthy.
|
|
541
|
+
"""
|
|
542
|
+
|
|
543
|
+
if config.kernel_adapter_provider is not None:
|
|
544
|
+
return config.kernel_adapter_provider
|
|
545
|
+
if config.a2a_runtime_adapter is not None:
|
|
546
|
+
return lambda: config.a2a_runtime_adapter
|
|
547
|
+
if config.runtime_executor is not None and config.launch_context is not None:
|
|
548
|
+
return lambda: config.runtime_executor.create_adapter(config.launch_context)
|
|
549
|
+
return None
|
|
550
|
+
|
|
551
|
+
|
|
491
552
|
def _wire_a2a_if_enabled(app: FastAPI, state: RuntimeAppState, config: RuntimeAppConfig) -> None:
|
|
492
553
|
"""Mount A2A with an explicitly injected RuntimeAdapter.
|
|
493
554
|
|
|
@@ -569,15 +630,17 @@ def _wire_agui_if_enabled(app: FastAPI, state: RuntimeAppState, config: RuntimeA
|
|
|
569
630
|
self._service = service
|
|
570
631
|
self._store = RuntimeEventStore(service)
|
|
571
632
|
|
|
572
|
-
async def append_one(self, event: Any) -> Any:
|
|
573
|
-
existing = await self._service.get_session(
|
|
633
|
+
async def append_one(self, session_id: str, event: Any) -> Any:
|
|
634
|
+
existing = await self._service.get_session(session_id)
|
|
574
635
|
if existing is None:
|
|
636
|
+
metadata = getattr(event, "source", None)
|
|
637
|
+
meta = metadata.metadata if metadata is not None else {}
|
|
575
638
|
await self._service.create_session(
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
639
|
+
str(meta.get("agent_id") or "agent"),
|
|
640
|
+
str(meta.get("user_id") or "user"),
|
|
641
|
+
session_id,
|
|
579
642
|
)
|
|
580
|
-
return await self._store.append_one(event)
|
|
643
|
+
return await self._store.append_one(session_id, event)
|
|
581
644
|
|
|
582
645
|
async def reserve_once(self, event: Any) -> Any:
|
|
583
646
|
existing = await self._service.get_session(event.session_id)
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""RunAgent / Responses 入口的 kernel 路径(Phase 1 Task 8 Step 3-5)。
|
|
3
|
+
|
|
4
|
+
只在 ``kernel_route_active()`` 时启用(灰度 opt-in);旧 HTTP 行为保持兼容:
|
|
5
|
+
- accepted -> 202、duplicate -> 200、rejected -> 400、unsupported -> 409、
|
|
6
|
+
queue_full -> 429、persistence_uncertain -> 503(RECEIPT_HTTP_STATUS)。
|
|
7
|
+
- 旧响应 shape 不变;非流式在 receipt accepted 后才开始消费 stream。
|
|
8
|
+
- SSE 的 reconnect cursor 源自同一 Session seq(SessionEventSubscription)。
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import json
|
|
14
|
+
import logging
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
from fastapi.responses import JSONResponse, StreamingResponse
|
|
18
|
+
|
|
19
|
+
from ksadk.kernel import ingress
|
|
20
|
+
from ksadk.kernel.contracts import AgentControlReceipt
|
|
21
|
+
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _envelope_text(payload: dict[str, Any]) -> str:
|
|
26
|
+
return str(payload.get("delta") or payload.get("text") or "")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
async def _kernel_submit(
|
|
30
|
+
*,
|
|
31
|
+
mapper: str,
|
|
32
|
+
session_id: str,
|
|
33
|
+
idempotency_key: str,
|
|
34
|
+
content: Any,
|
|
35
|
+
correlation_ref: str | None,
|
|
36
|
+
source_kind: str,
|
|
37
|
+
runtime_options: dict[str, Any] | None = None,
|
|
38
|
+
) -> tuple[AgentControlReceipt, ingress.TrustedRuntimeContext]:
|
|
39
|
+
trusted = ingress.trusted_context(
|
|
40
|
+
source_kind=source_kind,
|
|
41
|
+
source_ref=idempotency_key,
|
|
42
|
+
session_id=session_id,
|
|
43
|
+
# A foreground compatibility request admits a mutation and then reads
|
|
44
|
+
# the same session's canonical stream. It remains session-bound, but
|
|
45
|
+
# needs explicit authority for both operations.
|
|
46
|
+
operations=("enqueue", "subscribe_events"),
|
|
47
|
+
)
|
|
48
|
+
correlation_kwarg = {
|
|
49
|
+
"map_run_request": "invocation_id",
|
|
50
|
+
"map_responses_request": "response_id",
|
|
51
|
+
"map_agui_request": "run_id",
|
|
52
|
+
"map_a2a_task": "task_id",
|
|
53
|
+
"map_studio_request": "run_id",
|
|
54
|
+
}[mapper]
|
|
55
|
+
command = getattr(ingress, mapper)(
|
|
56
|
+
trusted=trusted,
|
|
57
|
+
session_id=session_id,
|
|
58
|
+
idempotency_key=idempotency_key,
|
|
59
|
+
content=content,
|
|
60
|
+
**({correlation_kwarg: correlation_ref} if correlation_ref else {}),
|
|
61
|
+
**({"runtime_options": runtime_options} if runtime_options else {}),
|
|
62
|
+
)
|
|
63
|
+
receipt = await ingress.submit_command(command, permit=trusted.permit)
|
|
64
|
+
return receipt, trusted
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _kernel_error_response(receipt: AgentControlReceipt) -> JSONResponse:
|
|
68
|
+
return JSONResponse(
|
|
69
|
+
status_code=ingress.receipt_http_status(receipt),
|
|
70
|
+
content={
|
|
71
|
+
"error": ingress.receipt_error_payload(receipt),
|
|
72
|
+
},
|
|
73
|
+
headers=ingress.receipt_response_headers(receipt),
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _sse_chunk(payload: dict[str, Any], *, event: str | None, seq: int) -> str:
|
|
78
|
+
prefix = f"event: {event}\n" if event else ""
|
|
79
|
+
return f"id: {seq}\n{prefix}data: {json.dumps(payload, ensure_ascii=False)}\n\n"
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def kernel_stream_response(
|
|
83
|
+
*,
|
|
84
|
+
receipt: AgentControlReceipt,
|
|
85
|
+
trusted: ingress.TrustedRuntimeContext,
|
|
86
|
+
session_id: str,
|
|
87
|
+
) -> StreamingResponse:
|
|
88
|
+
"""统一 cursor:从 receipt.accepted_seq 之后读 Session 事件。"""
|
|
89
|
+
|
|
90
|
+
after_seq = int(receipt.accepted_seq or 0)
|
|
91
|
+
|
|
92
|
+
async def generator():
|
|
93
|
+
async for seq, projected in ingress.subscribe_projected(
|
|
94
|
+
session_id,
|
|
95
|
+
trusted=trusted,
|
|
96
|
+
after_seq=after_seq,
|
|
97
|
+
projector=_new_responses_projector(),
|
|
98
|
+
):
|
|
99
|
+
if projected is None:
|
|
100
|
+
continue
|
|
101
|
+
kind, payload = projected
|
|
102
|
+
yield _sse_chunk(payload, event=kind, seq=seq)
|
|
103
|
+
if kind == "response.output_item.done" and (
|
|
104
|
+
(payload.get("item") or {}).get("type") == "mcp_approval_request"
|
|
105
|
+
):
|
|
106
|
+
yield _sse_chunk(
|
|
107
|
+
{"type": "response.incomplete"},
|
|
108
|
+
event="response.incomplete",
|
|
109
|
+
seq=seq,
|
|
110
|
+
)
|
|
111
|
+
return
|
|
112
|
+
# A foreground response stream is scoped to one admitted run.
|
|
113
|
+
# SessionEventStore subscriptions are deliberately long-lived for
|
|
114
|
+
# replay/SSE clients, so do not leave this HTTP response open after
|
|
115
|
+
# the terminal fact has been projected.
|
|
116
|
+
if kind in {"response.completed", "response.failed", "response.canceled"}:
|
|
117
|
+
return
|
|
118
|
+
|
|
119
|
+
return StreamingResponse(generator(), media_type="text/event-stream")
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _responses_projector(envelope: Any) -> tuple[str, dict[str, Any]] | None:
|
|
123
|
+
"""Session envelope -> 旧 Responses SSE shape(cursor 仍用 envelope.seq)。"""
|
|
124
|
+
|
|
125
|
+
payload = envelope.payload or {}
|
|
126
|
+
event_type = envelope.event_type
|
|
127
|
+
if event_type == "interaction.requested":
|
|
128
|
+
request = payload.get("request") or {}
|
|
129
|
+
presentation = request.get("presentation") or {}
|
|
130
|
+
description = presentation.get("description") or ""
|
|
131
|
+
try:
|
|
132
|
+
visible = json.loads(description) if description else {}
|
|
133
|
+
except (TypeError, json.JSONDecodeError):
|
|
134
|
+
visible = {}
|
|
135
|
+
arguments = visible.get("arguments") if isinstance(visible, dict) else {}
|
|
136
|
+
return "response.output_item.done", {
|
|
137
|
+
"type": "response.output_item.done",
|
|
138
|
+
"item": {
|
|
139
|
+
"id": str(payload.get("interaction_id") or ""),
|
|
140
|
+
"type": "mcp_approval_request",
|
|
141
|
+
"name": str(presentation.get("title") or payload.get("kind") or "approval"),
|
|
142
|
+
"arguments": json.dumps(arguments or {}, ensure_ascii=False),
|
|
143
|
+
},
|
|
144
|
+
}
|
|
145
|
+
if event_type == "run.completed":
|
|
146
|
+
text = str(payload.get("output_text") or "")
|
|
147
|
+
return "response.completed", {
|
|
148
|
+
"type": "response.completed",
|
|
149
|
+
"output_text": text,
|
|
150
|
+
"delta": text,
|
|
151
|
+
}
|
|
152
|
+
if event_type == "run.failed":
|
|
153
|
+
return "response.failed", {
|
|
154
|
+
"type": "response.failed",
|
|
155
|
+
"error": payload.get("error") or {"code": "runtime_failed"},
|
|
156
|
+
}
|
|
157
|
+
if event_type in {"run.canceled", "run.interrupted"}:
|
|
158
|
+
return "response.canceled", {
|
|
159
|
+
"type": "response.canceled",
|
|
160
|
+
"reason": payload.get("reason") or event_type,
|
|
161
|
+
}
|
|
162
|
+
text = _envelope_text(payload)
|
|
163
|
+
if text:
|
|
164
|
+
return "response.output_text.delta", {
|
|
165
|
+
"type": "response.output_text.delta",
|
|
166
|
+
"delta": text,
|
|
167
|
+
}
|
|
168
|
+
return None
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def _new_responses_projector():
|
|
172
|
+
"""Create a session-scoped canonical RuntimeEvent -> Responses projector.
|
|
173
|
+
|
|
174
|
+
``run.completed.output_refs`` deliberately point at canonical items instead
|
|
175
|
+
of duplicating answer text. A projector therefore keeps only the small
|
|
176
|
+
item snapshot needed for this one HTTP/SSE response and resolves those
|
|
177
|
+
refs when the terminal fact arrives.
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
item_text: dict[str, str] = {}
|
|
181
|
+
|
|
182
|
+
def project(envelope: Any) -> tuple[str, dict[str, Any]] | None:
|
|
183
|
+
payload = envelope.payload or {}
|
|
184
|
+
event_type = envelope.event_type
|
|
185
|
+
if event_type == "item.updated":
|
|
186
|
+
item_id = str(payload.get("item_id") or "")
|
|
187
|
+
update = payload.get("update") or {}
|
|
188
|
+
text = str(update.get("text") or "")
|
|
189
|
+
if item_id and text:
|
|
190
|
+
item_text[item_id] = (
|
|
191
|
+
text if payload.get("op") == "replace" else item_text.get(item_id, "") + text
|
|
192
|
+
)
|
|
193
|
+
return None
|
|
194
|
+
if event_type == "item.completed":
|
|
195
|
+
item_id = str(payload.get("item_id") or "")
|
|
196
|
+
parts = (payload.get("snapshot") or {}).get("parts") or []
|
|
197
|
+
if item_id and isinstance(parts, list):
|
|
198
|
+
item_text[item_id] = "".join(
|
|
199
|
+
str(part.get("text") or "") for part in parts if isinstance(part, dict)
|
|
200
|
+
)
|
|
201
|
+
return None
|
|
202
|
+
if event_type == "run.completed":
|
|
203
|
+
refs = payload.get("output_refs") or []
|
|
204
|
+
output = "".join(
|
|
205
|
+
item_text.get(str(ref.get("item_id") or ""), "")
|
|
206
|
+
for ref in refs
|
|
207
|
+
if isinstance(ref, dict)
|
|
208
|
+
)
|
|
209
|
+
projected_payload = dict(payload)
|
|
210
|
+
projected_payload["output_text"] = output or str(payload.get("output_text") or "")
|
|
211
|
+
return _responses_projector(
|
|
212
|
+
type("Envelope", (), {"event_type": event_type, "payload": projected_payload})()
|
|
213
|
+
)
|
|
214
|
+
return _responses_projector(envelope)
|
|
215
|
+
|
|
216
|
+
return project
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
async def kernel_conversation_turn(
|
|
220
|
+
*,
|
|
221
|
+
receipt: AgentControlReceipt,
|
|
222
|
+
trusted: ingress.TrustedRuntimeContext,
|
|
223
|
+
session_id: str,
|
|
224
|
+
build_payload,
|
|
225
|
+
):
|
|
226
|
+
"""非流式 kernel 路径:receipt accepted 后订阅聚合 output_text。"""
|
|
227
|
+
|
|
228
|
+
if receipt.status not in ("accepted", "duplicate"):
|
|
229
|
+
return _kernel_error_response(receipt)
|
|
230
|
+
output_text = ""
|
|
231
|
+
async for _seq, projected in ingress.subscribe_projected(
|
|
232
|
+
session_id,
|
|
233
|
+
trusted=trusted,
|
|
234
|
+
after_seq=int(receipt.accepted_seq or 0),
|
|
235
|
+
projector=_new_responses_projector(),
|
|
236
|
+
):
|
|
237
|
+
if projected and projected[0] == "response.completed":
|
|
238
|
+
output_text = str(projected[1].get("output_text") or output_text)
|
|
239
|
+
break
|
|
240
|
+
if projected and projected[0] in {"response.failed", "response.canceled"}:
|
|
241
|
+
return JSONResponse(
|
|
242
|
+
status_code=502,
|
|
243
|
+
content={"error": projected[1]},
|
|
244
|
+
)
|
|
245
|
+
elif projected:
|
|
246
|
+
output_text += str(projected[1].get("delta") or "")
|
|
247
|
+
payload = build_payload(output_text)
|
|
248
|
+
return JSONResponse(
|
|
249
|
+
status_code=ingress.receipt_http_status(receipt),
|
|
250
|
+
content=payload,
|
|
251
|
+
headers=ingress.receipt_response_headers(receipt),
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
__all__ = [
|
|
256
|
+
"kernel_conversation_turn",
|
|
257
|
+
"kernel_stream_response",
|
|
258
|
+
]
|
|
@@ -6,6 +6,7 @@ import uuid
|
|
|
6
6
|
from collections.abc import Mapping
|
|
7
7
|
from typing import Any, Dict, List, Optional
|
|
8
8
|
|
|
9
|
+
from fastapi import HTTPException
|
|
9
10
|
from fastapi.responses import StreamingResponse
|
|
10
11
|
from pydantic import BaseModel
|
|
11
12
|
|
|
@@ -20,11 +21,18 @@ from ksadk.conversations.runtime_streaming import (
|
|
|
20
21
|
stream_runtime_conversation_turn,
|
|
21
22
|
stream_runtime_responses_conversation_turn,
|
|
22
23
|
)
|
|
24
|
+
from ksadk.kernel.ingress import kernel_route_active
|
|
23
25
|
from ksadk.runtime.conversation_execution import invoke_runtime_conversation_once
|
|
24
26
|
from ksadk.server.factory import get_runtime_execution
|
|
25
27
|
|
|
26
28
|
from . import dependencies as deps
|
|
27
29
|
from .checkpoint_resolution import _resolve_checkpoint_resume_input_from_session
|
|
30
|
+
from .kernel_ingress import (
|
|
31
|
+
_kernel_error_response,
|
|
32
|
+
_kernel_submit,
|
|
33
|
+
kernel_conversation_turn,
|
|
34
|
+
kernel_stream_response,
|
|
35
|
+
)
|
|
28
36
|
from .models import (
|
|
29
37
|
ResponsesRequest,
|
|
30
38
|
_clean_optional_string,
|
|
@@ -60,6 +68,26 @@ async def list_openai_models():
|
|
|
60
68
|
"""Expose the current model catalog through the OpenAI-compatible path."""
|
|
61
69
|
|
|
62
70
|
payload = await _build_models_payload()
|
|
71
|
+
try:
|
|
72
|
+
_executor, launch_context = get_runtime_execution()
|
|
73
|
+
except HTTPException:
|
|
74
|
+
launch_context = None
|
|
75
|
+
if launch_context is not None:
|
|
76
|
+
config = dict(launch_context.config)
|
|
77
|
+
raw_allowed = (
|
|
78
|
+
config.get("models") or config.get("allowed_models") or config.get("allowedModels")
|
|
79
|
+
)
|
|
80
|
+
if isinstance(raw_allowed, (list, tuple, set)):
|
|
81
|
+
allowed = {str(item).strip() for item in raw_allowed if str(item).strip()}
|
|
82
|
+
default_model = str(config.get("model") or "").strip()
|
|
83
|
+
if default_model:
|
|
84
|
+
allowed.add(default_model)
|
|
85
|
+
payload = dict(payload)
|
|
86
|
+
payload["data"] = [
|
|
87
|
+
item
|
|
88
|
+
for item in payload.get("data", [])
|
|
89
|
+
if str(item.get("id") or "").strip() in allowed
|
|
90
|
+
]
|
|
63
91
|
return {
|
|
64
92
|
"object": "list",
|
|
65
93
|
"data": payload.get("data", []),
|
|
@@ -72,6 +100,8 @@ async def list_openai_models():
|
|
|
72
100
|
async def responses(request: ResponsesRequest):
|
|
73
101
|
"""OpenAI Responses 兼容接口。"""
|
|
74
102
|
executor, launch_context = get_runtime_execution()
|
|
103
|
+
if kernel_route_active():
|
|
104
|
+
return await _kernel_responses(request, launch_context)
|
|
75
105
|
resolved_session_id, resolved_user_id = _resolve_responses_session_and_user(request)
|
|
76
106
|
agent_id = _runtime_agent_id(launch_context)
|
|
77
107
|
|
|
@@ -82,11 +112,7 @@ async def responses(request: ResponsesRequest):
|
|
|
82
112
|
session_id=resolved_session_id,
|
|
83
113
|
resume_input=resume_input,
|
|
84
114
|
)
|
|
85
|
-
messages = (
|
|
86
|
-
[]
|
|
87
|
-
if resume_input is not None
|
|
88
|
-
else normalize_responses_input(request.input)
|
|
89
|
-
)
|
|
115
|
+
messages = [] if resume_input is not None else normalize_responses_input(request.input)
|
|
90
116
|
custom_metadata, request_metadata = _split_custom_metadata(request.metadata)
|
|
91
117
|
if request.previous_response_id:
|
|
92
118
|
request_metadata["previous_response_id"] = request.previous_response_id
|
|
@@ -105,9 +131,7 @@ async def responses(request: ResponsesRequest):
|
|
|
105
131
|
|
|
106
132
|
if request.stream:
|
|
107
133
|
runtime_preparation = (
|
|
108
|
-
None
|
|
109
|
-
if resume_input is not None
|
|
110
|
-
else await executor.prepare_start(launch_context)
|
|
134
|
+
None if resume_input is not None else await executor.prepare_start(launch_context)
|
|
111
135
|
)
|
|
112
136
|
resume_key = _detached_resume_key_from_input(resolved_session_id, resume_input)
|
|
113
137
|
_reject_if_detached_resume_active(resume_key)
|
|
@@ -169,6 +193,62 @@ async def responses(request: ResponsesRequest):
|
|
|
169
193
|
)
|
|
170
194
|
|
|
171
195
|
|
|
196
|
+
async def _kernel_responses(request: ResponsesRequest, launch_context):
|
|
197
|
+
"""kernel 路径(灰度 opt-in):Responses -> AgentControlCommand -> receipt。"""
|
|
198
|
+
|
|
199
|
+
from ksadk.conversations.runtime_persistence import ensure_conversation_session
|
|
200
|
+
|
|
201
|
+
resolved_session_id, resolved_user_id = _resolve_responses_session_and_user(request)
|
|
202
|
+
session = await ensure_conversation_session(
|
|
203
|
+
agent_id=_runtime_agent_id(launch_context),
|
|
204
|
+
user_id=resolved_user_id,
|
|
205
|
+
session_id=resolved_session_id,
|
|
206
|
+
session_service_provider=deps.resolve_session_service,
|
|
207
|
+
)
|
|
208
|
+
session_id = session.id
|
|
209
|
+
metadata = request.metadata if isinstance(request.metadata, dict) else {}
|
|
210
|
+
idempotency_key = (
|
|
211
|
+
_clean_optional_string(metadata.get("idempotency_key"))
|
|
212
|
+
or _metadata_invocation_id(metadata)
|
|
213
|
+
or f"resp_{uuid.uuid4().hex}"
|
|
214
|
+
)
|
|
215
|
+
messages = normalize_responses_input(request.input)
|
|
216
|
+
response_id = f"resp_{uuid.uuid4().hex}"
|
|
217
|
+
receipt, trusted = await _kernel_submit(
|
|
218
|
+
mapper="map_responses_request",
|
|
219
|
+
session_id=session_id,
|
|
220
|
+
idempotency_key=idempotency_key,
|
|
221
|
+
content=messages,
|
|
222
|
+
correlation_ref=response_id,
|
|
223
|
+
source_kind="responses",
|
|
224
|
+
)
|
|
225
|
+
if receipt.status not in ("accepted", "duplicate"):
|
|
226
|
+
return _kernel_error_response(receipt)
|
|
227
|
+
|
|
228
|
+
def build_payload(output_text: str):
|
|
229
|
+
return build_responses_payload(
|
|
230
|
+
output_text=output_text,
|
|
231
|
+
model=request.model,
|
|
232
|
+
session_id=session_id,
|
|
233
|
+
response_id=response_id,
|
|
234
|
+
metadata=None,
|
|
235
|
+
usage=None,
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
if request.stream:
|
|
239
|
+
return kernel_stream_response(
|
|
240
|
+
receipt=receipt,
|
|
241
|
+
trusted=trusted,
|
|
242
|
+
session_id=session_id,
|
|
243
|
+
)
|
|
244
|
+
return await kernel_conversation_turn(
|
|
245
|
+
receipt=receipt,
|
|
246
|
+
trusted=trusted,
|
|
247
|
+
session_id=session_id,
|
|
248
|
+
build_payload=build_payload,
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
|
|
172
252
|
@openai_compat_router.post("/v1/chat/completions")
|
|
173
253
|
async def chat_completions(request: ChatCompletionRequest):
|
|
174
254
|
"""OpenAI 兼容的聊天补全接口 (支持流式和非流式)"""
|
|
@@ -15,7 +15,8 @@ from ksadk.conversations.session_title import (
|
|
|
15
15
|
build_fallback_title,
|
|
16
16
|
build_heuristic_title,
|
|
17
17
|
)
|
|
18
|
-
from ksadk.events.
|
|
18
|
+
from ksadk.events.canonical import ContinuationCreated
|
|
19
|
+
from ksadk.events.canonical_store import session_event_to_runtime_event
|
|
19
20
|
from ksadk.server.factory import get_runtime_execution, get_state
|
|
20
21
|
from ksadk.sessions import Session, SessionEvent
|
|
21
22
|
|
|
@@ -149,6 +150,13 @@ def _runtime_continuity_payload() -> dict[str, Any]:
|
|
|
149
150
|
|
|
150
151
|
|
|
151
152
|
def _event_to_action_payload(event: SessionEvent) -> dict[str, Any]:
|
|
153
|
+
"""Serialize a stored SessionEvent for the REST action wire.
|
|
154
|
+
|
|
155
|
+
公开承诺字段(契约声明见 ``ksadk/events/projections.py``):
|
|
156
|
+
``EventId``/``SessionId``/``Author``/``EventType``/``Content``/``Timestamp``/
|
|
157
|
+
``SeqId``(有值时附 ``InvocationId``)。这是存储事件形态本身的透传,
|
|
158
|
+
``Content``/``Metadata`` 的内部结构不在承诺范围。
|
|
159
|
+
"""
|
|
152
160
|
payload = {
|
|
153
161
|
"EventId": event.id,
|
|
154
162
|
"SessionId": event.session_id,
|
|
@@ -231,34 +239,41 @@ async def _iter_with_idle_heartbeat(source: AsyncIterator[Any]):
|
|
|
231
239
|
|
|
232
240
|
|
|
233
241
|
def _checkpoint_event_to_action_payload(event: SessionEvent) -> dict[str, Any] | None:
|
|
242
|
+
"""Project a checkpoint-bearing event into the REST checkpoint action payload.
|
|
243
|
+
|
|
244
|
+
公开承诺字段(契约声明见 ``ksadk/events/projections.py``):``EventId``/
|
|
245
|
+
``SessionId``/``InvocationId``/``SeqId``/``Timestamp``/``RunId``/
|
|
246
|
+
``CheckpointId``/``Framework``/``FrameworkRef``/``IsResumable``/
|
|
247
|
+
``ResumeStatus``/``IsTerminal``/``NextNode``。来源为显式 ``run_checkpoint``
|
|
248
|
+
事件元数据,或 ``continuation.created`` canonical 事件的投影。
|
|
249
|
+
非 checkpoint 事件(或不可识别的 continuation_kind)返回 ``None``。
|
|
250
|
+
内部不保证字段:其余元数据透传键(``Metadata`` 内容随存储演进可变)。
|
|
251
|
+
"""
|
|
234
252
|
if event.event_type == "run_checkpoint":
|
|
235
253
|
metadata = event.metadata or {}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if not isinstance(payload, Mapping):
|
|
254
|
+
else:
|
|
255
|
+
canonical = session_event_to_runtime_event(event)
|
|
256
|
+
if not isinstance(canonical, ContinuationCreated):
|
|
240
257
|
return None
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
framework = str(next(iter(framework_ref)))
|
|
247
|
-
capability = payload.get("capability")
|
|
258
|
+
if canonical.continuation_kind != "graph_checkpoint":
|
|
259
|
+
return None
|
|
260
|
+
framework = canonical.source.framework
|
|
261
|
+
framework_ref = {framework: dict(canonical.ref)}
|
|
262
|
+
capability = canonical.source.metadata.get("capability")
|
|
248
263
|
capability = capability if isinstance(capability, Mapping) else {}
|
|
249
264
|
metadata = {
|
|
250
265
|
**dict(event.metadata or {}),
|
|
251
|
-
|
|
252
|
-
"
|
|
266
|
+
**dict(canonical.source.metadata),
|
|
267
|
+
"continuation_kind": canonical.continuation_kind,
|
|
268
|
+
"run_id": canonical.run_id,
|
|
269
|
+
"checkpoint_id": canonical.continuation_id,
|
|
253
270
|
"framework": framework,
|
|
254
271
|
"framework_ref": dict(framework_ref),
|
|
255
|
-
"backend": str(
|
|
256
|
-
"scope": str(
|
|
257
|
-
"durable": bool(
|
|
258
|
-
"is_resumable":
|
|
272
|
+
"backend": str(capability.get("backend") or "unknown"),
|
|
273
|
+
"scope": str(capability.get("scope") or "unknown"),
|
|
274
|
+
"durable": bool(capability.get("durable", False)),
|
|
275
|
+
"is_resumable": canonical.resumable,
|
|
259
276
|
}
|
|
260
|
-
else:
|
|
261
|
-
return None
|
|
262
277
|
run_id = str(metadata.get("run_id") or "").strip()
|
|
263
278
|
checkpoint_id = str(metadata.get("checkpoint_id") or "").strip()
|
|
264
279
|
framework = str(metadata.get("framework") or "").strip()
|