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
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
"""Frozen SubagentProvider/v1 seam with explicit lineage and policy bounds.
|
|
2
|
+
|
|
3
|
+
The Kernel does not know whether a child is implemented by Codex, DSH,
|
|
4
|
+
Claude, another KsADK AgentProvider, or a remote service. It only routes a
|
|
5
|
+
bounded request to a named provider and retains the returned child identity.
|
|
6
|
+
Provider-private state and event logs remain with that provider; projected
|
|
7
|
+
child events keep their own ids and sequence numbers.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from collections.abc import AsyncIterator, Mapping, Sequence
|
|
13
|
+
from datetime import datetime
|
|
14
|
+
from typing import Any, Literal, Protocol, cast, runtime_checkable
|
|
15
|
+
|
|
16
|
+
from pydantic import Field, field_validator, model_validator
|
|
17
|
+
|
|
18
|
+
from ksadk.plugins.contracts import PluginContractModel, PluginReference
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class SubagentPolicy(PluginContractModel):
|
|
22
|
+
"""Parent-owned limits that a child provider may only narrow."""
|
|
23
|
+
|
|
24
|
+
max_depth: int = Field(default=1, ge=1, le=16)
|
|
25
|
+
timeout_seconds: int = Field(default=120, ge=1, le=86_400)
|
|
26
|
+
max_steps: int = Field(default=12, ge=1, le=10_000)
|
|
27
|
+
background: bool = False
|
|
28
|
+
allowed_tools: tuple[str, ...] = ()
|
|
29
|
+
allowed_permissions: tuple[str, ...] = ()
|
|
30
|
+
|
|
31
|
+
@field_validator("allowed_tools", "allowed_permissions")
|
|
32
|
+
@classmethod
|
|
33
|
+
def validate_unique_values(cls, value: tuple[str, ...]) -> tuple[str, ...]:
|
|
34
|
+
if any(not item.strip() for item in value):
|
|
35
|
+
raise ValueError("subagent policy entries must be non-empty")
|
|
36
|
+
if len(value) != len(set(value)):
|
|
37
|
+
raise ValueError("subagent policy entries must be unique")
|
|
38
|
+
return tuple(sorted(value))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class SpawnSubagentRequest(PluginContractModel):
|
|
42
|
+
"""One bounded child task requested by an authenticated parent Run."""
|
|
43
|
+
|
|
44
|
+
request_format: Literal["ksadk.subagent-spawn/v1"] = "ksadk.subagent-spawn/v1"
|
|
45
|
+
provider_ref: str
|
|
46
|
+
parent_session_id: str = Field(min_length=1, max_length=256)
|
|
47
|
+
parent_run_id: str = Field(min_length=1, max_length=256)
|
|
48
|
+
task: str = Field(min_length=1, max_length=131_072)
|
|
49
|
+
depth: int = Field(default=1, ge=1, le=16)
|
|
50
|
+
policy: SubagentPolicy = Field(default_factory=SubagentPolicy)
|
|
51
|
+
metadata: dict[str, Any] = Field(default_factory=dict)
|
|
52
|
+
|
|
53
|
+
@field_validator("provider_ref")
|
|
54
|
+
@classmethod
|
|
55
|
+
def validate_provider_ref(cls, value: str) -> str:
|
|
56
|
+
return cast(str, PluginReference(ref=value).ref)
|
|
57
|
+
|
|
58
|
+
@field_validator("metadata")
|
|
59
|
+
@classmethod
|
|
60
|
+
def validate_metadata(cls, value: dict[str, Any]) -> dict[str, Any]:
|
|
61
|
+
_reject_secret_values(value)
|
|
62
|
+
return value
|
|
63
|
+
|
|
64
|
+
@model_validator(mode="after")
|
|
65
|
+
def validate_depth(self) -> "SpawnSubagentRequest":
|
|
66
|
+
if self.depth > self.policy.max_depth:
|
|
67
|
+
raise ValueError("subagent depth exceeds the parent policy maxDepth")
|
|
68
|
+
return self
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class ChildHandle(PluginContractModel):
|
|
72
|
+
"""Stable lineage and recovery descriptor for one provider-owned child."""
|
|
73
|
+
|
|
74
|
+
handle_format: Literal["ksadk.child-handle/v1"] = "ksadk.child-handle/v1"
|
|
75
|
+
handle_id: str = Field(min_length=1, max_length=256)
|
|
76
|
+
provider_ref: str
|
|
77
|
+
parent_session_id: str = Field(min_length=1, max_length=256)
|
|
78
|
+
parent_run_id: str = Field(min_length=1, max_length=256)
|
|
79
|
+
child_session_id: str | None = Field(default=None, max_length=256)
|
|
80
|
+
child_run_id: str | None = Field(default=None, max_length=256)
|
|
81
|
+
depth: int = Field(ge=1, le=16)
|
|
82
|
+
capabilities: tuple[str, ...] = ()
|
|
83
|
+
capability_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$")
|
|
84
|
+
created_at: datetime
|
|
85
|
+
resumable: bool = False
|
|
86
|
+
resume_descriptor: dict[str, Any] | None = None
|
|
87
|
+
|
|
88
|
+
@field_validator("provider_ref")
|
|
89
|
+
@classmethod
|
|
90
|
+
def validate_provider_ref(cls, value: str) -> str:
|
|
91
|
+
return cast(str, PluginReference(ref=value).ref)
|
|
92
|
+
|
|
93
|
+
@field_validator("capabilities")
|
|
94
|
+
@classmethod
|
|
95
|
+
def validate_capabilities(cls, value: tuple[str, ...]) -> tuple[str, ...]:
|
|
96
|
+
if any(not item.strip() for item in value):
|
|
97
|
+
raise ValueError("child capabilities must be non-empty")
|
|
98
|
+
if len(value) != len(set(value)):
|
|
99
|
+
raise ValueError("child capabilities must be unique")
|
|
100
|
+
return tuple(sorted(value))
|
|
101
|
+
|
|
102
|
+
@field_validator("created_at")
|
|
103
|
+
@classmethod
|
|
104
|
+
def validate_created_at(cls, value: datetime) -> datetime:
|
|
105
|
+
if value.tzinfo is None or value.utcoffset() is None:
|
|
106
|
+
raise ValueError("child handle createdAt must include a timezone")
|
|
107
|
+
return value
|
|
108
|
+
|
|
109
|
+
@field_validator("resume_descriptor")
|
|
110
|
+
@classmethod
|
|
111
|
+
def validate_resume_descriptor(
|
|
112
|
+
cls, value: dict[str, Any] | None
|
|
113
|
+
) -> dict[str, Any] | None:
|
|
114
|
+
if value is not None:
|
|
115
|
+
_reject_secret_values(value)
|
|
116
|
+
return value
|
|
117
|
+
|
|
118
|
+
@model_validator(mode="after")
|
|
119
|
+
def validate_recovery_shape(self) -> "ChildHandle":
|
|
120
|
+
if self.resumable and not self.resume_descriptor:
|
|
121
|
+
raise ValueError("resumable child handle requires a resumeDescriptor")
|
|
122
|
+
if not self.resumable and self.resume_descriptor is not None:
|
|
123
|
+
raise ValueError("non-resumable child handle cannot carry a resumeDescriptor")
|
|
124
|
+
return self
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class SubagentStatus(PluginContractModel):
|
|
128
|
+
status_format: Literal["ksadk.subagent-status/v1"] = "ksadk.subagent-status/v1"
|
|
129
|
+
handle_id: str = Field(min_length=1, max_length=256)
|
|
130
|
+
state: Literal[
|
|
131
|
+
"accepted",
|
|
132
|
+
"running",
|
|
133
|
+
"waiting_input",
|
|
134
|
+
"succeeded",
|
|
135
|
+
"failed",
|
|
136
|
+
"cancelled",
|
|
137
|
+
"interrupted",
|
|
138
|
+
"disposed",
|
|
139
|
+
]
|
|
140
|
+
last_seq: int = Field(default=0, ge=0)
|
|
141
|
+
updated_at: datetime
|
|
142
|
+
reason: str | None = Field(default=None, max_length=2048)
|
|
143
|
+
|
|
144
|
+
@field_validator("updated_at")
|
|
145
|
+
@classmethod
|
|
146
|
+
def validate_updated_at(cls, value: datetime) -> datetime:
|
|
147
|
+
if value.tzinfo is None or value.utcoffset() is None:
|
|
148
|
+
raise ValueError("subagent status updatedAt must include a timezone")
|
|
149
|
+
return value
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class SubagentEvent(PluginContractModel):
|
|
153
|
+
"""Identity-preserving child event; parent projection must not merge by text."""
|
|
154
|
+
|
|
155
|
+
event_format: Literal["ksadk.subagent-event/v1"] = "ksadk.subagent-event/v1"
|
|
156
|
+
handle_id: str = Field(min_length=1, max_length=256)
|
|
157
|
+
event_id: str = Field(min_length=1, max_length=256)
|
|
158
|
+
seq: int = Field(ge=1)
|
|
159
|
+
kind: Literal["progress", "item", "interaction", "terminal"]
|
|
160
|
+
payload: dict[str, Any] = Field(default_factory=dict)
|
|
161
|
+
native_ref: dict[str, str] = Field(default_factory=dict)
|
|
162
|
+
|
|
163
|
+
@field_validator("payload")
|
|
164
|
+
@classmethod
|
|
165
|
+
def validate_payload(cls, value: dict[str, Any]) -> dict[str, Any]:
|
|
166
|
+
_reject_secret_values(value)
|
|
167
|
+
return value
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class SubagentResult(PluginContractModel):
|
|
171
|
+
result_format: Literal["ksadk.subagent-result/v1"] = "ksadk.subagent-result/v1"
|
|
172
|
+
handle_id: str = Field(min_length=1, max_length=256)
|
|
173
|
+
state: Literal["succeeded", "failed", "cancelled", "interrupted"]
|
|
174
|
+
output: Any = None
|
|
175
|
+
output_refs: tuple[str, ...] = ()
|
|
176
|
+
error_code: str | None = Field(default=None, max_length=256)
|
|
177
|
+
error_message: str | None = Field(default=None, max_length=2048)
|
|
178
|
+
|
|
179
|
+
@field_validator("output_refs")
|
|
180
|
+
@classmethod
|
|
181
|
+
def validate_output_refs(cls, value: tuple[str, ...]) -> tuple[str, ...]:
|
|
182
|
+
if any(not item.strip() for item in value):
|
|
183
|
+
raise ValueError("subagent output references must be non-empty")
|
|
184
|
+
if len(value) != len(set(value)):
|
|
185
|
+
raise ValueError("subagent output references must be unique")
|
|
186
|
+
return tuple(sorted(value))
|
|
187
|
+
|
|
188
|
+
@model_validator(mode="after")
|
|
189
|
+
def validate_terminal_shape(self) -> "SubagentResult":
|
|
190
|
+
if self.state == "succeeded" and (self.error_code or self.error_message):
|
|
191
|
+
raise ValueError("successful subagent result cannot carry an error")
|
|
192
|
+
if self.state == "failed" and not self.error_code:
|
|
193
|
+
raise ValueError("failed subagent result requires errorCode")
|
|
194
|
+
return self
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
@runtime_checkable
|
|
198
|
+
class SubagentProvider(Protocol):
|
|
199
|
+
"""Named child execution provider; every method is provider-owned."""
|
|
200
|
+
|
|
201
|
+
async def describe(self) -> Mapping[str, Any]: ...
|
|
202
|
+
|
|
203
|
+
async def available(self) -> bool: ...
|
|
204
|
+
|
|
205
|
+
async def spawn(self, request: SpawnSubagentRequest) -> ChildHandle: ...
|
|
206
|
+
|
|
207
|
+
async def followup(self, handle: ChildHandle, input: Any) -> None: ...
|
|
208
|
+
|
|
209
|
+
async def status(self, handle: ChildHandle) -> SubagentStatus: ...
|
|
210
|
+
|
|
211
|
+
async def interrupt(self, handle: ChildHandle) -> None: ...
|
|
212
|
+
|
|
213
|
+
async def cancel(self, handle: ChildHandle) -> None: ...
|
|
214
|
+
|
|
215
|
+
def subscribe(
|
|
216
|
+
self, handle: ChildHandle, *, after_seq: int = 0
|
|
217
|
+
) -> AsyncIterator[SubagentEvent]: ...
|
|
218
|
+
|
|
219
|
+
async def result(self, handle: ChildHandle) -> SubagentResult: ...
|
|
220
|
+
|
|
221
|
+
async def dispose(self, handle: ChildHandle) -> None: ...
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
class SubagentProviderError(RuntimeError):
|
|
225
|
+
"""Stable typed failure at the provider routing boundary."""
|
|
226
|
+
|
|
227
|
+
def __init__(self, code: str, message: str) -> None:
|
|
228
|
+
super().__init__(message)
|
|
229
|
+
self.code = code
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
class SubagentProviderRouter:
|
|
233
|
+
"""Route child handles to exact providers without interpreting their state."""
|
|
234
|
+
|
|
235
|
+
def __init__(self, providers: Mapping[str, SubagentProvider]) -> None:
|
|
236
|
+
self._providers = dict(providers)
|
|
237
|
+
|
|
238
|
+
async def spawn(self, request: SpawnSubagentRequest) -> ChildHandle:
|
|
239
|
+
provider = self._provider(request.provider_ref)
|
|
240
|
+
if not await provider.available():
|
|
241
|
+
raise SubagentProviderError(
|
|
242
|
+
"subagent_provider_unavailable",
|
|
243
|
+
f"SubagentProvider {request.provider_ref} is unavailable",
|
|
244
|
+
)
|
|
245
|
+
handle = await provider.spawn(request)
|
|
246
|
+
self._validate_handle(request, handle)
|
|
247
|
+
return handle
|
|
248
|
+
|
|
249
|
+
async def status(self, handle: ChildHandle) -> SubagentStatus:
|
|
250
|
+
return await self._provider_for_handle(handle).status(handle)
|
|
251
|
+
|
|
252
|
+
async def followup(self, handle: ChildHandle, input: Any) -> None:
|
|
253
|
+
await self._provider_for_handle(handle).followup(handle, input)
|
|
254
|
+
|
|
255
|
+
async def interrupt(self, handle: ChildHandle) -> None:
|
|
256
|
+
await self._provider_for_handle(handle).interrupt(handle)
|
|
257
|
+
|
|
258
|
+
async def cancel(self, handle: ChildHandle) -> None:
|
|
259
|
+
await self._provider_for_handle(handle).cancel(handle)
|
|
260
|
+
|
|
261
|
+
def subscribe(
|
|
262
|
+
self, handle: ChildHandle, *, after_seq: int = 0
|
|
263
|
+
) -> AsyncIterator[SubagentEvent]:
|
|
264
|
+
if after_seq < 0:
|
|
265
|
+
raise SubagentProviderError(
|
|
266
|
+
"subagent_cursor_invalid", "subagent after_seq cannot be negative"
|
|
267
|
+
)
|
|
268
|
+
return self._provider_for_handle(handle).subscribe(handle, after_seq=after_seq)
|
|
269
|
+
|
|
270
|
+
async def result(self, handle: ChildHandle) -> SubagentResult:
|
|
271
|
+
return await self._provider_for_handle(handle).result(handle)
|
|
272
|
+
|
|
273
|
+
async def dispose(self, handle: ChildHandle) -> None:
|
|
274
|
+
await self._provider_for_handle(handle).dispose(handle)
|
|
275
|
+
|
|
276
|
+
def _provider_for_handle(self, handle: ChildHandle) -> SubagentProvider:
|
|
277
|
+
return self._provider(handle.provider_ref)
|
|
278
|
+
|
|
279
|
+
def _provider(self, provider_ref: str) -> SubagentProvider:
|
|
280
|
+
provider = self._providers.get(provider_ref)
|
|
281
|
+
if provider is None:
|
|
282
|
+
raise SubagentProviderError(
|
|
283
|
+
"subagent_provider_not_found",
|
|
284
|
+
f"SubagentProvider {provider_ref} is not registered",
|
|
285
|
+
)
|
|
286
|
+
return provider
|
|
287
|
+
|
|
288
|
+
@staticmethod
|
|
289
|
+
def _validate_handle(
|
|
290
|
+
request: SpawnSubagentRequest,
|
|
291
|
+
handle: ChildHandle,
|
|
292
|
+
) -> None:
|
|
293
|
+
if (
|
|
294
|
+
handle.provider_ref != request.provider_ref
|
|
295
|
+
or handle.parent_session_id != request.parent_session_id
|
|
296
|
+
or handle.parent_run_id != request.parent_run_id
|
|
297
|
+
or handle.depth != request.depth
|
|
298
|
+
):
|
|
299
|
+
raise SubagentProviderError(
|
|
300
|
+
"subagent_handle_mismatch",
|
|
301
|
+
"SubagentProvider returned a child handle outside the requested lineage",
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
_SECRET_KEY_PARTS = ("secret", "password", "token", "apikey", "api_key")
|
|
306
|
+
_SECRET_REF_PREFIXES = ("secret://", "env://", "credential://", "vault://")
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def _reject_secret_values(value: Any, *, path: str = "payload") -> None:
|
|
310
|
+
if isinstance(value, Mapping):
|
|
311
|
+
for key, child in value.items():
|
|
312
|
+
key_text = str(key)
|
|
313
|
+
normalized = key_text.replace("-", "").lower()
|
|
314
|
+
if any(part in normalized for part in _SECRET_KEY_PARTS) and child is not None:
|
|
315
|
+
if not isinstance(child, str) or not child.startswith(_SECRET_REF_PREFIXES):
|
|
316
|
+
raise ValueError(f"{path}.{key_text} must contain a secret reference")
|
|
317
|
+
_reject_secret_values(child, path=f"{path}.{key_text}")
|
|
318
|
+
elif isinstance(value, Sequence) and not isinstance(value, (str, bytes, bytearray)):
|
|
319
|
+
for index, child in enumerate(value):
|
|
320
|
+
_reject_secret_values(child, path=f"{path}[{index}]")
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
__all__ = [
|
|
324
|
+
"ChildHandle",
|
|
325
|
+
"SpawnSubagentRequest",
|
|
326
|
+
"SubagentEvent",
|
|
327
|
+
"SubagentPolicy",
|
|
328
|
+
"SubagentProvider",
|
|
329
|
+
"SubagentProviderError",
|
|
330
|
+
"SubagentProviderRouter",
|
|
331
|
+
"SubagentResult",
|
|
332
|
+
"SubagentStatus",
|
|
333
|
+
]
|
|
@@ -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
|
+
]
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"""PromptCompiler —— 确定性编译 Prompt 分区(方案第 7 节)。
|
|
2
|
+
|
|
3
|
+
第一个 PR 只落地稳定数据模型;本(第二个)PR 实现 ``compile()`` 的确定性行为:排序、
|
|
4
|
+
标准化、merge policy、protected 覆盖检测、SHA-256、section token 与 stable_prefix_hash。
|
|
5
|
+
|
|
6
|
+
PR2 仍是 shadow:``CompiledPrompt`` 仅用于 hash/可观测/未来 projection,**不替换** Runner
|
|
7
|
+
实际发送的 instructions→new_message/SystemMessage/base_instructions 拼装,线上行为不变。
|
|
8
|
+
``CompiledPrompt.content`` 不保证等于 Runner 最终物理输入(方案 7.2)。
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import hashlib
|
|
14
|
+
import re
|
|
15
|
+
from dataclasses import dataclass, replace
|
|
16
|
+
from typing import Iterable
|
|
17
|
+
|
|
18
|
+
from ksadk.context_engine.tokenizer import get_default_token_counter
|
|
19
|
+
from ksadk.prompts.models import (
|
|
20
|
+
PROMPT_COMPILER_VERSION,
|
|
21
|
+
CompiledPrompt,
|
|
22
|
+
PromptSection,
|
|
23
|
+
PromptSectionKind,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
# canonical 顺序:按 priority 升序,priority 相同按 kind 字典序。同一 section_id 的
|
|
27
|
+
# source/stability/merge_policy 必须固定,不因 Runner 遍历顺序变化(方案 7.3 第 8 条)。
|
|
28
|
+
_KIND_ORDER: tuple[PromptSectionKind, ...] = (
|
|
29
|
+
"platform_safety",
|
|
30
|
+
"agent_identity",
|
|
31
|
+
"agent_policy",
|
|
32
|
+
"runtime_capabilities",
|
|
33
|
+
"resource_manifest",
|
|
34
|
+
"request_instructions",
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _section_sort_key(section: PromptSection) -> tuple[int, str, str]:
|
|
39
|
+
kind_rank = _KIND_ORDER.index(section.kind) if section.kind in _KIND_ORDER else len(_KIND_ORDER)
|
|
40
|
+
kind_key = _KIND_ORDER[kind_rank] if kind_rank < len(_KIND_ORDER) else section.kind
|
|
41
|
+
return (section.priority, kind_key, section.section_id)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _normalize_text(text: str) -> str:
|
|
45
|
+
"""标准化换行与尾部空白,但不改变正文语义(方案 7.3 第 2 条)。
|
|
46
|
+
|
|
47
|
+
- CRLF/CR → LF
|
|
48
|
+
- 去除每行尾部空白
|
|
49
|
+
- 合并 3+ 连续空行为 1 行,去除首尾空白
|
|
50
|
+
"""
|
|
51
|
+
if not text:
|
|
52
|
+
return ""
|
|
53
|
+
normalized = str(text).replace("\r\n", "\n").replace("\r", "\n")
|
|
54
|
+
lines = [line.rstrip() for line in normalized.split("\n")]
|
|
55
|
+
# 合并 2+ 连续空行 → 单空行(统一段落间距,不改变正文语义)
|
|
56
|
+
collapsed: list[str] = []
|
|
57
|
+
blank_run = 0
|
|
58
|
+
for line in lines:
|
|
59
|
+
if line == "":
|
|
60
|
+
blank_run += 1
|
|
61
|
+
if blank_run >= 2:
|
|
62
|
+
continue
|
|
63
|
+
collapsed.append(line)
|
|
64
|
+
else:
|
|
65
|
+
blank_run = 0
|
|
66
|
+
collapsed.append(line)
|
|
67
|
+
return "\n".join(collapsed).strip()
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _content_sha256(text: str) -> str:
|
|
71
|
+
return "sha256:" + hashlib.sha256(text.encode("utf-8")).hexdigest()
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _wrap_section(section: PromptSection, content: str) -> str:
|
|
75
|
+
"""用标签消除区段歧义,但不应把所有动态上下文拼成 XML(方案 7.3 推荐格式)。"""
|
|
76
|
+
body = content.strip()
|
|
77
|
+
if not body:
|
|
78
|
+
return ""
|
|
79
|
+
return f"<{section.kind}>\n{body}\n</{section.kind}>"
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _merge_sections(sections: list[PromptSection]) -> list[PromptSection]:
|
|
83
|
+
"""同 kind 多来源时执行显式 merge policy,禁止"最后写入悄悄覆盖"(方案 7.3 第 3 条)。
|
|
84
|
+
|
|
85
|
+
- ``replace``: 保留最后一条(同 section_id 之内)
|
|
86
|
+
- ``append``: 按顺序拼接
|
|
87
|
+
- ``merge_unique``: 去重拼接
|
|
88
|
+
- ``protected``: 不允许覆盖;发生覆盖尝试时抛 ``ProtectedSectionOverrideError``
|
|
89
|
+
"""
|
|
90
|
+
grouped: dict[str, list[PromptSection]] = {}
|
|
91
|
+
order: list[str] = []
|
|
92
|
+
for section in sections:
|
|
93
|
+
if section.section_id not in grouped:
|
|
94
|
+
grouped[section.section_id] = []
|
|
95
|
+
order.append(section.section_id)
|
|
96
|
+
grouped[section.section_id].append(section)
|
|
97
|
+
|
|
98
|
+
merged: list[PromptSection] = []
|
|
99
|
+
for section_id in order:
|
|
100
|
+
bucket = grouped[section_id]
|
|
101
|
+
head = bucket[0]
|
|
102
|
+
if len(bucket) == 1:
|
|
103
|
+
merged.append(head)
|
|
104
|
+
continue
|
|
105
|
+
policy = head.merge_policy
|
|
106
|
+
# 同一 section_id 的来源/稳定性/merge_policy 必须固定(方案 7.3 第 8 条)。
|
|
107
|
+
inconsistent = any(
|
|
108
|
+
b.merge_policy != policy or b.stability != head.stability or b.kind != head.kind
|
|
109
|
+
for b in bucket[1:]
|
|
110
|
+
)
|
|
111
|
+
if inconsistent:
|
|
112
|
+
raise InconsistentSectionError(
|
|
113
|
+
f"section {section_id!r} 的来源/稳定性/merge_policy 不一致"
|
|
114
|
+
)
|
|
115
|
+
if policy == "replace":
|
|
116
|
+
merged.append(replace(head, content=bucket[-1].content))
|
|
117
|
+
elif policy == "protected":
|
|
118
|
+
# 任意两条同 section_id 内容不同即视为覆盖尝试。
|
|
119
|
+
contents = {b.content for b in bucket}
|
|
120
|
+
if len(contents) > 1:
|
|
121
|
+
raise ProtectedSectionOverrideError(
|
|
122
|
+
f"protected section {section_id!r} 发生覆盖尝试"
|
|
123
|
+
)
|
|
124
|
+
merged.append(head)
|
|
125
|
+
elif policy == "merge_unique":
|
|
126
|
+
seen: set[str] = set()
|
|
127
|
+
parts: list[str] = []
|
|
128
|
+
for b in bucket:
|
|
129
|
+
for chunk in re.split(r"\n{2,}", b.content.strip()):
|
|
130
|
+
chunk = chunk.strip()
|
|
131
|
+
if chunk and chunk not in seen:
|
|
132
|
+
seen.add(chunk)
|
|
133
|
+
parts.append(chunk)
|
|
134
|
+
merged.append(replace(head, content="\n\n".join(parts)))
|
|
135
|
+
else: # append
|
|
136
|
+
merged.append(
|
|
137
|
+
replace(
|
|
138
|
+
head,
|
|
139
|
+
content="\n\n".join(b.content.strip() for b in bucket if b.content.strip()),
|
|
140
|
+
)
|
|
141
|
+
)
|
|
142
|
+
return merged
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class ProtectedSectionOverrideError(RuntimeError):
|
|
146
|
+
"""``protected`` section 被尝试覆盖。编译失败并产生审计事件,不静默忽略(方案 7.3 第 9 条)。"""
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class InconsistentSectionError(RuntimeError):
|
|
150
|
+
"""同一 section_id 的来源/稳定性/merge_policy 不固定。"""
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
@dataclass(frozen=True)
|
|
154
|
+
class PromptCompiler:
|
|
155
|
+
"""确定性 Prompt 编译器。
|
|
156
|
+
|
|
157
|
+
``compile()`` 必须对相同输入产生相同输出(方案 7.3)。构造器无状态,可复用。
|
|
158
|
+
"""
|
|
159
|
+
|
|
160
|
+
compiler_version: str = PROMPT_COMPILER_VERSION
|
|
161
|
+
|
|
162
|
+
def compile(self, sections: Iterable[PromptSection]) -> CompiledPrompt:
|
|
163
|
+
# 1. 排序(确定性)
|
|
164
|
+
ordered = sorted(sections, key=_section_sort_key)
|
|
165
|
+
# 2. merge(同 section_id 的多来源按 merge policy 合并)
|
|
166
|
+
merged = _merge_sections(ordered)
|
|
167
|
+
# 3. platform_safety 不允许被 request_instructions 覆盖(方案 7.3 第 4 条)。
|
|
168
|
+
# protected/replace 在 _merge_sections 内已处理;这里额外校验跨 section_id 的
|
|
169
|
+
# 信任边界:request_instructions 不得声明 platform 的 kind。
|
|
170
|
+
for section in merged:
|
|
171
|
+
if (
|
|
172
|
+
section.kind == "platform_safety"
|
|
173
|
+
and section.trust_level in ("untrusted", "user")
|
|
174
|
+
):
|
|
175
|
+
raise ProtectedSectionOverrideError(
|
|
176
|
+
"platform_safety 不得由 untrusted/user 来源声明"
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
counter = get_default_token_counter()
|
|
180
|
+
# 4. 空 section 不输出占位文本(方案 7.3 第 5 条)。
|
|
181
|
+
section_hashes: dict[str, str] = {}
|
|
182
|
+
tokens_by_section: dict[str, int] = {}
|
|
183
|
+
wrapped_blocks: list[str] = []
|
|
184
|
+
for section in merged:
|
|
185
|
+
body = _normalize_text(section.content)
|
|
186
|
+
section_hashes[section.section_id] = _content_sha256(body)
|
|
187
|
+
tokens_by_section[section.section_id] = counter.count_text(body)
|
|
188
|
+
if body:
|
|
189
|
+
wrapped_blocks.append(_wrap_section(section, body))
|
|
190
|
+
canonical_content = "\n\n".join(block for block in wrapped_blocks if block).strip()
|
|
191
|
+
|
|
192
|
+
# 5. stable_prefix_hash:仅覆盖 stability="stable" 的 section(platform_safety /
|
|
193
|
+
# agent_identity / agent_policy)。部署级/动态 section 不进稳定前缀(方案 7.4)。
|
|
194
|
+
stable_body = "\n\n".join(
|
|
195
|
+
_wrap_section(s, _normalize_text(s.content))
|
|
196
|
+
for s in merged
|
|
197
|
+
if s.stability == "stable" and _normalize_text(s.content)
|
|
198
|
+
).strip()
|
|
199
|
+
stable_prefix_hash = _content_sha256(stable_body) if stable_body else ""
|
|
200
|
+
|
|
201
|
+
return CompiledPrompt(
|
|
202
|
+
sections=tuple(merged),
|
|
203
|
+
content=canonical_content,
|
|
204
|
+
content_hash=_content_sha256(canonical_content),
|
|
205
|
+
estimated_tokens=counter.count_text(canonical_content),
|
|
206
|
+
stable_prefix_hash=stable_prefix_hash,
|
|
207
|
+
section_hashes=section_hashes,
|
|
208
|
+
tokens_by_section=tokens_by_section,
|
|
209
|
+
compiler_version=self.compiler_version,
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def compile_prompt(sections: Iterable[PromptSection]) -> CompiledPrompt:
|
|
214
|
+
"""便捷入口:用默认 compiler 编译。"""
|
|
215
|
+
return PromptCompiler().compile(sections)
|