agentengine-sdk-python 0.8.2__py3-none-any.whl → 0.8.4__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.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/METADATA +22 -28
- agentengine_sdk_python-0.8.4.dist-info/RECORD +1070 -0
- ksadk/_build_provenance.json +1 -0
- ksadk/agui/_agent_helpers.py +4 -0
- ksadk/api/client.py +108 -91
- ksadk/builders/code_builder.py +36 -9
- ksadk/builders/framework_requirements.py +2 -1
- ksadk/builders/ks3_uploader.py +36 -7
- ksadk/builders/managed_runtime_builder.py +4 -0
- ksadk/cli/__init__.py +38 -3
- ksadk/cli/cmd_managed_runtime.py +13 -1
- ksadk/cli/cmd_plugin.py +662 -0
- ksadk/cli/cmd_web.py +2 -5
- ksadk/cli/runtime_bootstrap.py +23 -1
- ksadk/codex/client.py +424 -96
- ksadk/codex/projection.py +24 -0
- ksadk/codex/runtime.py +83 -283
- ksadk/common/auth.py +16 -10
- ksadk/configs/env_registry.py +59 -3
- ksadk/configs/settings.py +9 -0
- ksadk/context_engine/contributors.py +73 -8
- ksadk/conversations/__init__.py +19 -0
- ksadk/conversations/context.py +104 -24
- ksadk/conversations/contracts.py +266 -0
- ksadk/conversations/message_projection.py +154 -15
- ksadk/conversations/projector.py +614 -0
- ksadk/conversations/reducer.py +98 -0
- ksadk/conversations/runtime_invocation.py +5 -0
- ksadk/conversations/runtime_payloads.py +1 -0
- ksadk/conversations/runtime_preparation.py +30 -27
- ksadk/conversations/runtime_resume.py +50 -2
- ksadk/conversations/runtime_stream_events.py +5 -0
- ksadk/conversations/runtime_streaming.py +25 -7
- ksadk/deployment/env_forward.py +2 -2
- ksadk/deployment/providers/serverless.py +1 -1
- ksadk/events/_v1_compat/projection.py +2 -0
- ksadk/events/adapters/_codex_validators.py +18 -7
- ksadk/events/adapters/codex.py +190 -0
- ksadk/events/adapters/langgraph.py +15 -1
- ksadk/events/canonical_store.py +3 -1
- ksadk/events/projections.py +1 -1
- ksadk/harness/__init__.py +45 -35
- ksadk/harness/config.py +2 -2
- ksadk/harness/runtime.py +75 -16
- ksadk/harness/tools.py +38 -13
- ksadk/interaction/provider.py +1 -0
- ksadk/interaction/providers/langgraph.py +1 -0
- ksadk/kernel/bootstrap.py +28 -4
- ksadk/kernel/contract_fingerprints.py +5 -4
- ksadk/kernel/contracts.py +8 -0
- ksadk/kernel/control.py +1 -0
- ksadk/kernel/ingress.py +36 -2
- ksadk/kernel/memory_store.py +1 -0
- ksadk/kernel/postgres_store.py +1 -0
- ksadk/kernel/sqlite_store.py +28 -0
- ksadk/kernel/store.py +3 -0
- ksadk/kernel/worker.py +76 -10
- ksadk/knowledge_base/client.py +57 -27
- ksadk/mcp_runtime/__init__.py +12 -4
- ksadk/memory/adk/backends/sdk_ltm_backend.py +161 -41
- ksadk/memory/adk/resilient_session_service.py +25 -17
- ksadk/memory/adk/short_term_memory.py +26 -9
- ksadk/memory/models.py +7 -4
- ksadk/memory/provider_resolver.py +3 -0
- ksadk/memory/providers/local_sqlite.py +7 -0
- ksadk/model_proxy/server.py +10 -5
- ksadk/plugins/__init__.py +171 -0
- ksadk/plugins/artifacts.py +275 -0
- ksadk/plugins/bridges/__init__.py +47 -0
- ksadk/plugins/bridges/codex.py +659 -0
- ksadk/plugins/bridges/dsh.py +1300 -0
- ksadk/plugins/builtins.py +746 -0
- ksadk/plugins/bundle.py +246 -0
- ksadk/plugins/bundle_security.py +191 -0
- ksadk/plugins/codex_manifest.py +983 -0
- ksadk/plugins/composition.py +537 -0
- ksadk/plugins/context_contributor.py +437 -0
- ksadk/plugins/contracts.py +569 -0
- ksadk/plugins/delivery.py +153 -0
- ksadk/plugins/dsh_installation_digest.py +71 -0
- ksadk/plugins/dsh_toolchain.py +1024 -0
- ksadk/plugins/ecosystem_bridge.py +1105 -0
- ksadk/plugins/ecosystem_probe.py +191 -0
- ksadk/plugins/host.py +787 -0
- ksadk/plugins/kernel_adapter.py +205 -0
- ksadk/plugins/providers/__init__.py +108 -0
- ksadk/plugins/providers/bundles/dsh-knowledge/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-knowledge/index.mjs +53 -0
- ksadk/plugins/providers/bundles/dsh-knowledge/package.json +16 -0
- ksadk/plugins/providers/bundles/dsh-memory/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-memory/index.mjs +175 -0
- ksadk/plugins/providers/bundles/dsh-memory/package.json +16 -0
- ksadk/plugins/providers/bundles/dsh-platform-resources/client.mjs +166 -0
- ksadk/plugins/providers/bundles/dsh-platform-resources/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-platform-resources/index.mjs +9 -0
- ksadk/plugins/providers/bundles/dsh-platform-resources/package.json +12 -0
- ksadk/plugins/providers/bundles/dsh-skill-center/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-skill-center/index.mjs +125 -0
- ksadk/plugins/providers/bundles/dsh-skill-center/package.json +16 -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-dsh-capability-host/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/index.mjs +870 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +27 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-studio/client.js +92 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-studio/index.mjs +15 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-studio/package.json +7 -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 +988 -0
- ksadk/plugins/providers/codex_dsh.py +83 -0
- ksadk/plugins/providers/codex_native.py +368 -0
- ksadk/plugins/providers/codex_turn.py +301 -0
- ksadk/plugins/providers/dsh.py +951 -0
- ksadk/plugins/providers/dsh_capabilities.py +1389 -0
- ksadk/plugins/providers/dsh_descriptor_host.py +226 -0
- ksadk/plugins/providers/dsh_mcp.py +467 -0
- ksadk/plugins/providers/harness.py +632 -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/mcp_projection.py +150 -0
- ksadk/plugins/providers/platform_resources.py +657 -0
- ksadk/plugins/providers/shipped_dsh.py +370 -0
- ksadk/plugins/resolver.py +338 -0
- ksadk/plugins/subagent_providers/__init__.py +12 -0
- ksadk/plugins/subagent_providers/codex.py +443 -0
- ksadk/plugins/subagents.py +333 -0
- ksadk/resource_runtime/__init__.py +4 -0
- ksadk/resource_runtime/broker.py +616 -0
- ksadk/resource_runtime/build_artifacts.py +165 -0
- ksadk/resource_runtime/contracts.py +138 -0
- ksadk/resource_runtime/discovery_receipts.py +100 -0
- ksadk/resource_runtime/discovery_skills.py +172 -0
- ksadk/resource_runtime/errors.py +6 -0
- ksadk/resource_runtime/ipc.py +142 -0
- ksadk/resource_runtime/kernel_approval.py +165 -0
- ksadk/resource_runtime/knowledge.py +114 -0
- ksadk/resource_runtime/langgraph.py +94 -0
- ksadk/resource_runtime/leases.py +191 -0
- ksadk/resource_runtime/managed_projection.py +186 -0
- ksadk/resource_runtime/mcp_server.py +138 -0
- ksadk/resource_runtime/memory_provider.py +318 -0
- ksadk/resource_runtime/memory_receipts.py +34 -0
- ksadk/resource_runtime/operation_ledger.py +211 -0
- ksadk/resource_runtime/plugin_config.py +48 -0
- ksadk/resource_runtime/policy_authorization.py +54 -0
- ksadk/resource_runtime/process.py +110 -0
- ksadk/resource_runtime/skill_artifacts.py +153 -0
- ksadk/resource_runtime/skill_runtime.py +42 -0
- ksadk/resource_runtime/skill_workspace.py +118 -0
- ksadk/resource_runtime/skills.py +215 -0
- ksadk/resource_runtime/snapshots.py +180 -0
- ksadk/resource_runtime/socket_server.py +103 -0
- ksadk/resource_runtime/supervisor.py +380 -0
- ksadk/resource_runtime/worker.py +504 -0
- ksadk/runners/_langgraph_runner_streams.py +74 -6
- ksadk/runners/adk_runner.py +149 -11
- ksadk/runners/base_runner.py +29 -1
- ksadk/runners/langgraph_runner.py +475 -145
- ksadk/runtime/_runner_adapter/stream_mapping.py +193 -60
- ksadk/runtime/adapter.py +3 -0
- ksadk/runtime/conversation_execution.py +92 -16
- ksadk/runtime/executor.py +78 -2
- ksadk/runtime/factory.py +30 -200
- ksadk/runtime/framework_adapters.py +41 -0
- ksadk/runtime/preprocessing.py +10 -2
- ksadk/runtime/runner_adapter.py +78 -14
- ksadk/runtime_context.py +40 -2
- ksadk/sandbox/__init__.py +2 -1
- ksadk/sandbox/backends/e2b.py +52 -11
- ksadk/sandbox/backends/local_process.py +9 -0
- ksadk/sandbox/base.py +2 -0
- ksadk/sandbox/e2b_connection.py +66 -0
- 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 +581 -0
- ksadk/server/composition.py +2 -0
- ksadk/server/factory.py +5 -0
- ksadk/server/persistence_capability.py +516 -0
- ksadk/server/routes/control.py +210 -46
- ksadk/server/routes/dependencies.py +15 -0
- ksadk/server/routes/models.py +47 -4
- ksadk/server/routes/projection.py +252 -12
- ksadk/server/routes/sessions.py +284 -107
- ksadk/server/routes/streaming.py +43 -9
- ksadk/server/static/assets/{ArtifactsPanel-DSU1sWD_.js → ArtifactsPanel-CGbWlMNh.js} +1 -1
- ksadk/server/static/assets/{CodeBlock-DOH6MVcn.js → CodeBlock-b4C7upmO.js} +3 -3
- ksadk/server/static/assets/{MathMessageMarkdown-BL8my1R2.js → MathMessageMarkdown-DbdW5A4_.js} +4 -4
- ksadk/server/static/assets/{MermaidBlock-Dz4IP-Tx.js → MermaidBlock-BEBN4Ksz.js} +6 -6
- ksadk/server/static/assets/{NativeTerminalPanel-DUrK0JpZ.js → NativeTerminalPanel-zvL-WpAn.js} +1 -1
- ksadk/server/static/assets/{abnfDiagram-VCTEODGH-g20pFzNV.js → abnfDiagram-VCTEODGH-BYafW7Za.js} +1 -1
- ksadk/server/static/assets/{arc-C4FzinUA.js → arc-bTohInsS.js} +1 -1
- ksadk/server/static/assets/architecture-7GRP2DOG-BW5UtSnx.js +1 -0
- ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-DpIqL5h4.js → architectureDiagram-5GKGNRK7-Ch5Lbzsi.js} +1 -1
- ksadk/server/static/assets/{blockDiagram-NRAW4CY4-BjkljTNz.js → blockDiagram-NRAW4CY4-kqF4MDOG.js} +1 -1
- ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-Dk_ieq2X.js → c4Diagram-UCG6FXSJ-8uSRIODv.js} +1 -1
- ksadk/server/static/assets/channel-CF5Up3hQ.js +1 -0
- ksadk/server/static/assets/chunk-2Q5K7J3B-KkXX47WI.js +1 -0
- ksadk/server/static/assets/{chunk-5VM5RSS4-BVHAchFb.js → chunk-5VM5RSS4-DkhehZDr.js} +1 -1
- ksadk/server/static/assets/{chunk-F27PBJKO-C-ipQzuS.js → chunk-F27PBJKO-BdXhtPe9.js} +1 -1
- ksadk/server/static/assets/{chunk-G27WJ6UU-C2EyJbIK.js → chunk-G27WJ6UU-DPTpvpwi.js} +1 -1
- ksadk/server/static/assets/{chunk-JWPE2WC7-vYvVJb_M.js → chunk-JWPE2WC7-Pqoh38el.js} +1 -1
- ksadk/server/static/assets/{chunk-LCL6LL3I-BcI6ysPT.js → chunk-LCL6LL3I-DeU00qC-.js} +1 -1
- ksadk/server/static/assets/{chunk-POPQ4Y6H-C030x_Z1.js → chunk-POPQ4Y6H-CzxScFkr.js} +1 -1
- ksadk/server/static/assets/{chunk-RHFEMEQ7-yyGpsz4n.js → chunk-RHFEMEQ7-DpqMx-ux.js} +1 -1
- ksadk/server/static/assets/{chunk-SVP7TREG-BLTlmMU7.js → chunk-SVP7TREG-C6t0SypQ.js} +1 -1
- ksadk/server/static/assets/{chunk-XXDRQBXY-C_32ArgP.js → chunk-XXDRQBXY-DVaeafZk.js} +1 -1
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-Cz81acRQ.js +1 -0
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Cz81acRQ.js +1 -0
- ksadk/server/static/assets/{cose-bilkent-JH36ORCC-9YQYwdl0.js → cose-bilkent-JH36ORCC-Bf9D3tzJ.js} +1 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-DVWs8a2t.js +1 -0
- ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-ErLF5N13.js → cynefinDiagram-5FMLGOSQ-B9cY3iTz.js} +1 -1
- ksadk/server/static/assets/{dagre-3AP2YEHR-DFiQF-6f.js → dagre-3AP2YEHR-CSwlx3CB.js} +1 -1
- ksadk/server/static/assets/{dagre-BuhGnRI1.js → dagre-UBpgon5q.js} +1 -1
- ksadk/server/static/assets/{diagram-S7CK7UJ4-Bt1v8-GC.js → diagram-S7CK7UJ4-C9akhN9a.js} +1 -1
- ksadk/server/static/assets/{diagram-UQ7AKVKN-DSCxJdBK.js → diagram-UQ7AKVKN-CgedhTPI.js} +1 -1
- ksadk/server/static/assets/{diagram-VSXAHHWV-DHfYwp_9.js → diagram-VSXAHHWV-Cjucz5BY.js} +1 -1
- ksadk/server/static/assets/{diagram-VX7I27RA-DdzD-4Le.js → diagram-VX7I27RA-Dd4Vleyn.js} +1 -1
- ksadk/server/static/assets/{diagram-Z3DM3KII-Du-nAJ9F.js → diagram-Z3DM3KII-CZ2jGtYW.js} +1 -1
- ksadk/server/static/assets/{dist-B7seoj3d.js → dist-B2_CVgKv.js} +1 -1
- ksadk/server/static/assets/{dist-CSh_DE14.js → dist-B3FR1SKK.js} +1 -1
- ksadk/server/static/assets/{dist-DUX-id_F.js → dist-BIr4DSRq.js} +1 -1
- ksadk/server/static/assets/{dist-C_wsv-Qd.js → dist-BgV_owcB.js} +1 -1
- ksadk/server/static/assets/{dist-W-TIVntx.js → dist-Bj730Ib4.js} +1 -1
- ksadk/server/static/assets/{dist-BytlxIDT.js → dist-BnaTiyzN.js} +1 -1
- ksadk/server/static/assets/{dist-CXYYBw3_.js → dist-C1NMAY5a.js} +1 -1
- ksadk/server/static/assets/{dist-dDdADKFA.js → dist-C5_ZAZsG.js} +1 -1
- ksadk/server/static/assets/{dist-BVDffZ0U.js → dist-CB9iJrvg.js} +1 -1
- ksadk/server/static/assets/{dist-Bf2M8m3N.js → dist-CFzsn6BG.js} +1 -1
- ksadk/server/static/assets/{dist-ngtN0DJB.js → dist-Cf125P_m.js} +1 -1
- ksadk/server/static/assets/{dist-BE7bu-DL.js → dist-ClYUxfeK.js} +1 -1
- ksadk/server/static/assets/{dist-DNp6rLRA.js → dist-DFD6Qa6T.js} +1 -1
- ksadk/server/static/assets/{dist-BX8z72IC.js → dist-DVCOWtha.js} +1 -1
- ksadk/server/static/assets/{dist-dydu68Fl.js → dist-D_ctSS2i.js} +1 -1
- ksadk/server/static/assets/{dist-ClxGviKw.js → dist-DiixqL0J.js} +1 -1
- ksadk/server/static/assets/{dist-BjU6y-A2.js → dist-DoVSwoDb.js} +1 -1
- ksadk/server/static/assets/{dist-Dq9gLD7L.js → dist-DvFK7p5S.js} +1 -1
- ksadk/server/static/assets/{dist-8hqcx0sU.js → dist-QfkEHOlb.js} +1 -1
- ksadk/server/static/assets/{dist-CttYUqzS.js → dist-btbmmX5O.js} +1 -1
- ksadk/server/static/assets/{dist-DmldrHd_.js → dist-fBO2v5Kt.js} +1 -1
- ksadk/server/static/assets/{dist-DnfXs8Vn.js → dist-ufY3F5p6.js} +1 -1
- ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-Da9C9NO1.js → ebnfDiagram-PWID7BFC-Ci8NqqZu.js} +1 -1
- ksadk/server/static/assets/{erDiagram-SSCWMZ5O-EAGqqR79.js → erDiagram-SSCWMZ5O-CCIOhLZG.js} +1 -1
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-CQqR2hg3.js +1 -0
- ksadk/server/static/assets/flowDiagram-A5DVABFB-DDRRbGPm.js +1 -0
- ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-DqJsKb59.js → ganttDiagram-EL5Y4UJY-Cp_r9Hb6.js} +1 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-fgWEf7UD.js +1 -0
- ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-B6g4dtDi.js → gitGraphDiagram-WWUBYQGX-Dlhc8Wr8.js} +1 -1
- ksadk/server/static/assets/index-DcTML1Up.css +2 -0
- ksadk/server/static/assets/index-Dh2XHqPK.js +244 -0
- ksadk/server/static/assets/info-A6RAGUB7-BUecLTdt.js +1 -0
- ksadk/server/static/assets/{infoDiagram-RXCK75RN-Djm_nbd5.js → infoDiagram-RXCK75RN-CO0rRTRA.js} +1 -1
- ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-DWya9SG2.js → ishikawaDiagram-5VMMS53U-CHiaedSS.js} +1 -1
- ksadk/server/static/assets/{journeyDiagram-EYS64GPL-DutxhSNI.js → journeyDiagram-EYS64GPL-CHcCIB09.js} +1 -1
- ksadk/server/static/assets/{kanban-definition-3QL26DDD-DJdOF8Fm.js → kanban-definition-3QL26DDD-CJ_ebBZf.js} +1 -1
- ksadk/server/static/assets/{katex-vFWytM5c.js → katex-B4weu383.js} +1 -1
- ksadk/server/static/assets/{linear-BHjG8b-J.js → linear-V-MgYHW1.js} +1 -1
- ksadk/server/static/assets/{mermaid-parser.core-KGSy4jWT.js → mermaid-parser.core-CBijEX_c.js} +2 -2
- ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-9-HC88D4.js → mindmap-definition-FBJOCRG2-Bc-pQvpp.js} +1 -1
- ksadk/server/static/assets/packet-AYTQ26CC-BeW-btFv.js +1 -0
- ksadk/server/static/assets/{pegDiagram-XKGWAZYB-DrEZd4fD.js → pegDiagram-XKGWAZYB-D7genGLl.js} +1 -1
- ksadk/server/static/assets/pie-WAS4IAKB-X0xh4SaT.js +1 -0
- ksadk/server/static/assets/{pieDiagram-E7YTZNPT-DpjqOFFp.js → pieDiagram-E7YTZNPT-Bxj32zwD.js} +1 -1
- ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-BiNhgOXX.js → quadrantDiagram-AXDQQJYC-BURv2mGh.js} +1 -1
- ksadk/server/static/assets/radar-RG4KPBEZ-DzRMSqjd.js +1 -0
- ksadk/server/static/assets/railroad-74A4TZTK-Cc44icX-.js +1 -0
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-D6S4BdV-.js +1 -0
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-vD3aVE2o.js +1 -0
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-CYbW_b4T.js +1 -0
- ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-_Y3Ojg6G.js → railroadDiagram-O6MQD6OU-CCsh3avW.js} +1 -1
- ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-DeCFdg9K.js → requirementDiagram-EFPCY7ZU-_FRRBKEd.js} +1 -1
- ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-CPH75rhw.js → sankeyDiagram-P5KCCOFB-C-gr2o9M.js} +1 -1
- ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-OEpQQdr4.js → sequenceDiagram-WJ2MYXX4-D97NmfKg.js} +1 -1
- ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-heUErzhI.js → sizeCapture-X5ZJPWSS-DjrPC5FX.js} +1 -1
- ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-DvA3jSMB.js → stateDiagram-HBIQ2CUA-DzMNg1hh.js} +1 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BIcjKFhF.js +1 -0
- ksadk/server/static/assets/{swimlanes-XN3QIQJK-CR-dfN_t.js → swimlanes-XN3QIQJK-Cssf_CsU.js} +1 -1
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-tq3K3Ybl.js +8 -0
- ksadk/server/static/assets/{timeline-definition-24CTP7MA-DAVJf1TX.js → timeline-definition-24CTP7MA-BWTHzyS1.js} +1 -1
- ksadk/server/static/assets/treeView-Q6P3EWNA-DBXt3GdU.js +1 -0
- ksadk/server/static/assets/treemap-WGGIJYW6-DrCy4E_l.js +1 -0
- ksadk/server/static/assets/{vennDiagram-4TSXK5OY-DwM8eDkh.js → vennDiagram-4TSXK5OY-BSKgJsmR.js} +1 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-CefhOliM.js +1 -0
- ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-DZL-Zz2t.js → wardleyDiagram-VM6X3IG4-eflHNoaZ.js} +1 -1
- ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js → xychartDiagram-S5SC5T6Z-eYqrQ-v4.js} +1 -1
- ksadk/server/static/index.html +2 -2
- ksadk/session_context.py +66 -0
- ksadk/sessions/__init__.py +11 -21
- ksadk/sessions/_local_service_sync.py +263 -1
- ksadk/sessions/base.py +176 -0
- ksadk/sessions/errors.py +4 -0
- ksadk/sessions/in_memory.py +309 -19
- ksadk/sessions/local_service.py +83 -1
- ksadk/sessions/persistence.py +275 -0
- ksadk/sessions/postgres_service.py +358 -0
- ksadk/sessions/resilience.py +8 -0
- ksadk/sessions/resilient.py +362 -4
- ksadk/sessions/topology.py +135 -0
- ksadk/skills/models.py +26 -4
- ksadk/skills/package_store.py +186 -38
- ksadk/skills/runtime/agent.py +31 -6
- ksadk/skills/runtime/artifact_delivery.py +139 -0
- ksadk/skills/runtime/backends/e2b.py +98 -6
- ksadk/skills/runtime/backends/local.py +73 -8
- ksadk/skills/runtime/base.py +3 -0
- ksadk/skills/runtime/executor.py +2 -0
- ksadk/skills/runtime/loader.py +10 -2
- ksadk/skills/runtime/pinned.py +114 -0
- ksadk/skills/runtime/request.py +31 -0
- ksadk/skills/service_client.py +211 -24
- ksadk/studio/agent_lifecycle.py +26 -20
- ksadk/studio/api.py +714 -90
- ksadk/studio/api_catalog_routes.py +23 -0
- ksadk/studio/api_contracts.py +34 -1
- ksadk/studio/api_plugin_routes.py +911 -0
- ksadk/studio/api_resource_connections.py +183 -0
- ksadk/studio/attachment_store.py +187 -0
- ksadk/studio/authoring.py +10 -4
- ksadk/studio/authoring_coordinator.py +31 -16
- ksadk/studio/builder.py +199 -43
- ksadk/studio/cloud.py +346 -104
- ksadk/studio/cloud_shared_web.py +565 -0
- ksadk/studio/codex_agent_service.py +140 -27
- ksadk/studio/codex_builder.py +294 -16
- ksadk/studio/codex_credentials.py +90 -0
- ksadk/studio/codex_manifest.py +51 -4
- ksadk/studio/codex_plugin_store.py +746 -0
- ksadk/studio/codex_provider_build.py +231 -0
- ksadk/studio/codex_run.py +200 -29
- ksadk/studio/compatibility_report.py +456 -0
- ksadk/studio/compiler.py +84 -15
- ksadk/studio/contracts.py +249 -4
- ksadk/studio/dsh_application.py +137 -0
- ksadk/studio/dsh_capability_service.py +1107 -0
- ksadk/studio/dsh_models.py +59 -0
- ksadk/studio/dsh_provider_registration.py +1075 -0
- ksadk/studio/event_store.py +54 -6
- ksadk/studio/framework_run.py +37 -4
- ksadk/studio/hosted_kernel.py +89 -14
- ksadk/studio/mcp_runtime.py +11 -3
- ksadk/studio/model_client.py +2 -2
- ksadk/studio/operations.py +12 -2
- ksadk/studio/plugin_composition.py +468 -0
- ksadk/studio/plugin_kernel_adapter.py +28 -0
- ksadk/studio/plugin_runtime.py +831 -0
- ksadk/studio/resource_authority.py +637 -0
- ksadk/studio/resource_binding_validation.py +77 -0
- ksadk/studio/resource_build_admission.py +196 -0
- ksadk/studio/resource_build_materializer.py +149 -0
- ksadk/studio/resource_catalog.py +149 -3
- ksadk/studio/resource_connections.py +220 -0
- ksadk/studio/run_service.py +1144 -96
- ksadk/studio/runtime_source.py +24 -8
- ksadk/studio/scheduler_assistant.py +317 -0
- ksadk/studio/scheduler_runtime.py +383 -0
- ksadk/studio/scheduler_service.py +214 -0
- ksadk/studio/service.py +1131 -95
- ksadk/studio/shared_web.py +610 -87
- ksadk/studio/soul.py +52 -0
- ksadk/studio/static/assets/CodeBlock-DCUUY0PL-BLjA7kbS.js +41 -0
- ksadk/studio/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- ksadk/studio/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--BEOyPC3w.css +1 -0
- ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--CUYIXwgI.js +8 -0
- ksadk/studio/static/assets/MermaidBlock-DBFTztfQ-BTYKWEbD.js +44 -0
- ksadk/studio/static/assets/PrismRenderer-wiXRHURw.js +3 -0
- ksadk/studio/static/assets/abnfDiagram-VCTEODGH-CLETGjKq.js +1 -0
- ksadk/studio/static/assets/arc-Pry-7G1_.js +1 -0
- ksadk/studio/static/assets/architecture-7GRP2DOG-hXMiO_AU.js +1 -0
- ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-B5EQysk6.js +36 -0
- ksadk/studio/static/assets/array-BifhSqXX.js +1 -0
- ksadk/studio/static/assets/blockDiagram-I7D4REHJ-CFmPl1de.js +129 -0
- ksadk/studio/static/assets/c4Diagram-7LVT6UL2-BRrGu8qt.js +38 -0
- ksadk/studio/static/assets/channel-BqO-gtEw.js +1 -0
- ksadk/studio/static/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
- ksadk/studio/static/assets/chunk-4HAMMTFA-D220vUtq.js +62 -0
- ksadk/studio/static/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
- ksadk/studio/static/assets/chunk-75Z2AOVW-C8lLv_qc.js +2 -0
- ksadk/studio/static/assets/chunk-DU6HZSFF-C4DtVpCu.js +128 -0
- ksadk/studio/static/assets/chunk-F27PBJKO-Cpw14SNG.js +1 -0
- ksadk/studio/static/assets/chunk-FOHPRMQF-DHwB1DNv.js +161 -0
- ksadk/studio/static/assets/chunk-GMAD6QVW-DiQA-u2N.js +72 -0
- ksadk/studio/static/assets/chunk-GVQU2GXP-DUdNBUCi.js +1 -0
- ksadk/studio/static/assets/chunk-IMKFNOWR-BSlbjT_b.js +231 -0
- ksadk/studio/static/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
- ksadk/studio/static/assets/chunk-L3NEJ4N5-Db8Ab22W.js +1 -0
- ksadk/studio/static/assets/chunk-OSK3NFVY-M2m6G3j4.js +10 -0
- ksadk/studio/static/assets/chunk-P2QGCYS3-DezaQxiK.js +1 -0
- ksadk/studio/static/assets/chunk-POPQ4Y6H-DOpufJ3t.js +1 -0
- ksadk/studio/static/assets/chunk-PWAF6VOD-CfLb1gSc.js +1 -0
- ksadk/studio/static/assets/chunk-SHT3W25Y-DAyIVp5H.js +168 -0
- ksadk/studio/static/assets/chunk-SVP7TREG-DulomOrS.js +88 -0
- ksadk/studio/static/assets/chunk-TICWLB2K-bHJYoflj.js +206 -0
- ksadk/studio/static/assets/chunk-XXDRQBXY-7PcdR2B1.js +1 -0
- ksadk/studio/static/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
- ksadk/studio/static/assets/classDiagram-ZZMXUADV-D_bW8JjA.js +1 -0
- ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-D_bW8JjA.js +1 -0
- ksadk/studio/static/assets/cose-bilkent-JH36ORCC-snL88wkX.js +1 -0
- ksadk/studio/static/assets/cynefin-OW5HDTMX-Bd1YhRo1.js +1 -0
- ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-BBrIG_mI.js +62 -0
- ksadk/studio/static/assets/cytoscape.esm-CGd-uY3x.js +321 -0
- ksadk/studio/static/assets/dagre-GXQ25YYZ-DtF1nGdY.js +4 -0
- ksadk/studio/static/assets/dagre-PrKaheQc.js +1 -0
- ksadk/studio/static/assets/defaultLocale-BFoDCU3G.js +1 -0
- ksadk/studio/static/assets/diagram-S7CK7UJ4-0BZ98mya.js +30 -0
- ksadk/studio/static/assets/diagram-UQ7AKVKN-6mLKEo6L.js +41 -0
- ksadk/studio/static/assets/diagram-VSXAHHWV-CJBIaiZ2.js +3 -0
- ksadk/studio/static/assets/diagram-VX7I27RA-BohLEE1C.js +24 -0
- ksadk/studio/static/assets/diagram-Z3DM3KII-D8KIGonG.js +24 -0
- ksadk/studio/static/assets/dist-v5Q1xZ2K.js +1 -0
- ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-C99HU61t.js +1 -0
- ksadk/studio/static/assets/erDiagram-RLTQ6QDP-DLGry2Ap.js +99 -0
- ksadk/studio/static/assets/eventmodeling-NTZA5JFV-B1_5Ac8j.js +1 -0
- ksadk/studio/static/assets/flowDiagram-HODETNUW-DD5hmicn.js +1 -0
- ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BPJrVLSG.js +292 -0
- ksadk/studio/static/assets/gitGraph-4MIJSDKK-Cy_ZQBGi.js +1 -0
- ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-CZCUz4MT.js +106 -0
- ksadk/studio/static/assets/graphlib-DS17s2tU.js +1 -0
- ksadk/studio/static/assets/index-CeHL9ARV.css +2 -0
- ksadk/studio/static/assets/index-D9QEcVpL.js +320 -0
- ksadk/studio/static/assets/info-A6RAGUB7-DBzDQB_I.js +1 -0
- ksadk/studio/static/assets/infoDiagram-27XIBGKW-B-sq07Hi.js +2 -0
- ksadk/studio/static/assets/init-C-OQMol4.js +1 -0
- ksadk/studio/static/assets/ishikawaDiagram-5VMMS53U-CljI2wyf.js +70 -0
- ksadk/studio/static/assets/journeyDiagram-3NMN7TZE-D50Fo2sL.js +139 -0
- ksadk/studio/static/assets/kanban-definition-UXKFOSKX-DimfOTam.js +89 -0
- ksadk/studio/static/assets/katex-DhON-x74.js +257 -0
- ksadk/studio/static/assets/line-CX5BOOUP.js +1 -0
- ksadk/studio/static/assets/linear-BCxN9JLv.js +1 -0
- ksadk/studio/static/assets/mermaid-parser.core-BdCz8fkS.js +7 -0
- ksadk/studio/static/assets/mindmap-definition-YA3MSWOX-Bizzqy5R.js +96 -0
- ksadk/studio/static/assets/ordinal-BDEzSJ7C.js +1 -0
- ksadk/studio/static/assets/packet-AYTQ26CC-gPln-_kG.js +1 -0
- ksadk/studio/static/assets/path-fybaL0A-.js +1 -0
- ksadk/studio/static/assets/pegDiagram-XKGWAZYB-Dy3fB-gW.js +1 -0
- ksadk/studio/static/assets/pie-WAS4IAKB-qZdHMr7B.js +1 -0
- ksadk/studio/static/assets/pieDiagram-E7YTZNPT-B9mrFSDF.js +39 -0
- ksadk/studio/static/assets/quadrantDiagram-AXDQQJYC-NzUfCbMR.js +7 -0
- ksadk/studio/static/assets/radar-RG4KPBEZ-BZlnaea9.js +1 -0
- ksadk/studio/static/assets/railroad-74A4TZTK-Ce3__H9c.js +1 -0
- ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-DqQn7EzD.js +1 -0
- ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-B55kCA8F.js +1 -0
- ksadk/studio/static/assets/railroad-peg-WCYAUIDC-DfQnvkHd.js +1 -0
- ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-DnhMjZCk.js +1 -0
- ksadk/studio/static/assets/requirementDiagram-BXWQKSXE-BF3d103U.js +84 -0
- ksadk/studio/static/assets/rolldown-runtime-Dy4uBu1J-DK3Fl9T5.js +1 -0
- ksadk/studio/static/assets/rough.esm-Dy-Kn_BL.js +1 -0
- ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-Bo-JTwt0.js +40 -0
- ksadk/studio/static/assets/sequenceDiagram-WJ2MYXX4-Dh4wZtUm.js +162 -0
- ksadk/studio/static/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
- ksadk/studio/static/assets/src-SFn9St9H.js +1 -0
- ksadk/studio/static/assets/stateDiagram-D77RDMKH-DH774G6d.js +1 -0
- ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-DZvVWPBo.js +1 -0
- ksadk/studio/static/assets/swimlanes-42K2YHIH-Bl13OvTX.js +1 -0
- ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-BnFOTALJ.js +8 -0
- ksadk/studio/static/assets/timeline-definition-24CTP7MA-DxmSSjRB.js +120 -0
- ksadk/studio/static/assets/treeView-Q6P3EWNA-D5Nn9Swz.js +1 -0
- ksadk/studio/static/assets/treemap-WGGIJYW6-CgHgnQhE.js +1 -0
- ksadk/studio/static/assets/vennDiagram-4TSXK5OY-B9QEXcJq.js +34 -0
- ksadk/studio/static/assets/wardley-WFR3VGLG-DXrK2RRY.js +1 -0
- ksadk/studio/static/assets/wardleyDiagram-VM6X3IG4-Ba1AOWoe.js +78 -0
- ksadk/studio/static/assets/xychartDiagram-S5SC5T6Z-Cr5pt5Y-.js +7 -0
- ksadk/studio/static/index.html +2 -2
- ksadk/studio/validator.py +1 -1
- ksadk/studio/workspace.py +1 -0
- ksadk/version.py +1 -1
- ksadk_runtime_common/workspace_files/path_utils.py +41 -0
- agentengine_sdk_python-0.8.2.dist-info/RECORD +0 -778
- ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +0 -1
- ksadk/server/static/assets/channel-4cQHKtx1.js +0 -1
- ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +0 -1
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +0 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +0 -1
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +0 -1
- ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +0 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +0 -1
- ksadk/server/static/assets/index-8ipRcQ-M.js +0 -240
- ksadk/server/static/assets/index-ByFCqjlh.css +0 -2
- ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +0 -1
- ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +0 -1
- ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +0 -1
- ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +0 -1
- ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +0 -1
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +0 -1
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +0 -1
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +0 -1
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +0 -8
- ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +0 -1
- ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +0 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +0 -1
- ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +0 -3
- ksadk/studio/static/assets/index-BLpcdrgW.css +0 -1
- ksadk/studio/static/assets/index-CYekR2Xv.js +0 -260
- {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/WHEEL +0 -0
- {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
"""Bound structured AICP MemoryProvider; asynchronous writes use a separate receipt path."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
import json
|
|
7
|
+
import math
|
|
8
|
+
import threading
|
|
9
|
+
import time
|
|
10
|
+
from contextlib import contextmanager
|
|
11
|
+
|
|
12
|
+
from pydantic import Field
|
|
13
|
+
|
|
14
|
+
from ksadk.memory.adk.backends.sdk_ltm_backend import SdkLTMBackend
|
|
15
|
+
from ksadk.memory.models import (
|
|
16
|
+
CoreMemoryRequest,
|
|
17
|
+
MemoryCapabilities,
|
|
18
|
+
MemoryDeleteRequest,
|
|
19
|
+
MemoryDeleteResult,
|
|
20
|
+
MemoryRecord,
|
|
21
|
+
MemorySearchRequest,
|
|
22
|
+
MemorySearchResult,
|
|
23
|
+
UnsupportedMemoryOperation,
|
|
24
|
+
)
|
|
25
|
+
from ksadk.plugins.contracts import PluginContractModel
|
|
26
|
+
from ksadk.resource_runtime.contracts import InvocationIdentity, ResourceConfig
|
|
27
|
+
from ksadk.resource_runtime.errors import ResourceUpstreamAuthorizationError
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class MemoryQuery(PluginContractModel):
|
|
31
|
+
query: str = Field(strict=True, max_length=16000)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class MemoryWrite(PluginContractModel):
|
|
35
|
+
content: str = Field(strict=True, min_length=1, max_length=8192)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class MemoryStatusQuery(PluginContractModel):
|
|
39
|
+
operation_id: str = Field(strict=True, pattern=r"^[0-9a-f]{64}$")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class MemoryRecordSelector(PluginContractModel):
|
|
43
|
+
memory_id: str = Field(strict=True, min_length=1, max_length=256)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class MemoryUpdate(MemoryRecordSelector, MemoryWrite):
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class AicpMemoryProvider:
|
|
51
|
+
"""An explicit activation instance. Never resolves credentials or user IDs from env.
|
|
52
|
+
|
|
53
|
+
The caller supplies an admitted backend and identity. This search adapter does
|
|
54
|
+
not turn an asynchronous submission into the synchronous upsert contract.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
def __init__(
|
|
58
|
+
self, config: ResourceConfig, identity: InvocationIdentity, backend: SdkLTMBackend
|
|
59
|
+
):
|
|
60
|
+
if config.binding.resource.kind != "memory-instance":
|
|
61
|
+
raise ValueError("MemoryProvider requires a memory-instance binding")
|
|
62
|
+
if not backend.access_key or not backend.secret_key:
|
|
63
|
+
raise ValueError("MemoryProvider requires explicit signing credentials")
|
|
64
|
+
if (
|
|
65
|
+
backend._effective_memory_collection_id() != config.binding.resource.id
|
|
66
|
+
or backend.region != config.binding.resource.region
|
|
67
|
+
):
|
|
68
|
+
raise ValueError("Memory backend does not match the resource binding")
|
|
69
|
+
self.config = config
|
|
70
|
+
self.identity = identity
|
|
71
|
+
self.partition = identity.memory_partition(config.binding.resource)
|
|
72
|
+
self._backend = backend
|
|
73
|
+
self._lock = threading.Lock()
|
|
74
|
+
self._observed_ids: dict[str, None] = {}
|
|
75
|
+
self._upstream_forbidden = False
|
|
76
|
+
|
|
77
|
+
@contextmanager
|
|
78
|
+
def _backend_call(self):
|
|
79
|
+
"""Keep observed authorization failures sticky for this activation."""
|
|
80
|
+
with self._lock:
|
|
81
|
+
if self._upstream_forbidden:
|
|
82
|
+
raise ResourceUpstreamAuthorizationError()
|
|
83
|
+
self._backend.last_http_status = None
|
|
84
|
+
try:
|
|
85
|
+
yield
|
|
86
|
+
finally:
|
|
87
|
+
if self._backend.last_http_status in {401, 403}:
|
|
88
|
+
self._upstream_forbidden = True
|
|
89
|
+
self._observed_ids.clear()
|
|
90
|
+
raise ResourceUpstreamAuthorizationError() from None
|
|
91
|
+
|
|
92
|
+
def capabilities(self) -> MemoryCapabilities:
|
|
93
|
+
# The SDK exposes a query operation but no advertised search-mode or CAS
|
|
94
|
+
# guarantee. Do not invent capabilities from the presence of a method.
|
|
95
|
+
return MemoryCapabilities(
|
|
96
|
+
semantic_search=False,
|
|
97
|
+
keyword_search=False,
|
|
98
|
+
metadata_filter=False,
|
|
99
|
+
versioned_update=False,
|
|
100
|
+
hard_delete=False,
|
|
101
|
+
ttl=False,
|
|
102
|
+
max_record_chars=8192,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
def search(self, request: MemorySearchRequest) -> MemorySearchResult:
|
|
106
|
+
started = time.monotonic()
|
|
107
|
+
|
|
108
|
+
def result(status, records=None, error=None, truncated=False):
|
|
109
|
+
return MemorySearchResult(
|
|
110
|
+
status=status,
|
|
111
|
+
records=records or [],
|
|
112
|
+
error_code=error,
|
|
113
|
+
provider="aicp",
|
|
114
|
+
latency_ms=int((time.monotonic() - started) * 1000),
|
|
115
|
+
accounting_accuracy="estimated",
|
|
116
|
+
truncated_by_budget=truncated,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
if request.scopes != [("user", self.partition)]:
|
|
120
|
+
return result("unauthorized", error="MEMORY_SCOPE_MISMATCH")
|
|
121
|
+
if request.filters or request.as_of or request.memory_types or request.min_score != 0:
|
|
122
|
+
return result("failed", error="MEMORY_SEARCH_POLICY_UNSUPPORTED")
|
|
123
|
+
if (
|
|
124
|
+
type(request.top_k) is not int
|
|
125
|
+
or not 1 <= request.top_k <= 64
|
|
126
|
+
or type(request.max_tokens) is not int
|
|
127
|
+
or not 0 <= request.max_tokens <= 100000
|
|
128
|
+
or not isinstance(request.query, str)
|
|
129
|
+
or len(request.query) > 16000
|
|
130
|
+
):
|
|
131
|
+
return result("failed", error="MEMORY_SEARCH_ARGUMENTS_INVALID")
|
|
132
|
+
if request.max_tokens == 0:
|
|
133
|
+
return result("ok", truncated=True)
|
|
134
|
+
try:
|
|
135
|
+
with self._backend_call():
|
|
136
|
+
records = self._backend.search_records(
|
|
137
|
+
self.partition, request.query, request.top_k, strict=True
|
|
138
|
+
)
|
|
139
|
+
projected = []
|
|
140
|
+
remaining = request.max_tokens
|
|
141
|
+
truncated = len(records) > request.top_k
|
|
142
|
+
for item in records[: request.top_k]:
|
|
143
|
+
if (
|
|
144
|
+
item.user_id != self.partition
|
|
145
|
+
or item.metadata.get("AgentUserId", self.partition) != self.partition
|
|
146
|
+
or not item.memory_id
|
|
147
|
+
or item.score is not None
|
|
148
|
+
and not math.isfinite(item.score)
|
|
149
|
+
):
|
|
150
|
+
return result("failed", error="MEMORY_SEARCH_RESPONSE_INVALID")
|
|
151
|
+
content = item.content[:8192]
|
|
152
|
+
# Byte accounting is conservative for ordinary text tokenizers;
|
|
153
|
+
# accuracy remains explicitly estimated in the public result.
|
|
154
|
+
cost = len(content.encode("utf-8"))
|
|
155
|
+
if cost > remaining:
|
|
156
|
+
truncated = True
|
|
157
|
+
break
|
|
158
|
+
remaining -= cost
|
|
159
|
+
truncated |= len(content) != len(item.content)
|
|
160
|
+
projected.append(
|
|
161
|
+
MemoryRecord(
|
|
162
|
+
memory_id=item.memory_id,
|
|
163
|
+
tenant_id=self.identity.tenant_ref,
|
|
164
|
+
workspace_id="",
|
|
165
|
+
scope="user",
|
|
166
|
+
scope_id=self.partition,
|
|
167
|
+
memory_type="unknown",
|
|
168
|
+
content=content,
|
|
169
|
+
summary=content,
|
|
170
|
+
status="active",
|
|
171
|
+
confidence=None,
|
|
172
|
+
importance=None,
|
|
173
|
+
valid_from="",
|
|
174
|
+
valid_to="",
|
|
175
|
+
expires_at="",
|
|
176
|
+
source_session_id=item.session_id,
|
|
177
|
+
source_event_ids=[],
|
|
178
|
+
source_seq_range=None,
|
|
179
|
+
content_hash="sha256:" + hashlib.sha256(content.encode()).hexdigest(),
|
|
180
|
+
version=None,
|
|
181
|
+
metadata={"bindingId": self.config.binding.id, "score": item.score},
|
|
182
|
+
created_at=item.created_at or "",
|
|
183
|
+
updated_at=item.updated_at or "",
|
|
184
|
+
)
|
|
185
|
+
)
|
|
186
|
+
with self._lock:
|
|
187
|
+
for record in projected:
|
|
188
|
+
self._observed_ids[record.memory_id] = None
|
|
189
|
+
while len(self._observed_ids) > 256:
|
|
190
|
+
del self._observed_ids[next(iter(self._observed_ids))]
|
|
191
|
+
return result("ok", projected, truncated=truncated)
|
|
192
|
+
except ResourceUpstreamAuthorizationError:
|
|
193
|
+
return result("unauthorized", error="RESOURCE_FORBIDDEN")
|
|
194
|
+
except Exception:
|
|
195
|
+
return result("failed", error="MEMORY_SEARCH_FAILED")
|
|
196
|
+
|
|
197
|
+
def get(self, memory_id: str) -> MemoryRecord | None:
|
|
198
|
+
raise UnsupportedMemoryOperation("AICP does not expose a bound get-by-ID contract")
|
|
199
|
+
|
|
200
|
+
def submit(self, arguments: dict, *, operation_id: str) -> dict:
|
|
201
|
+
"""Host-approved submission; each operation has a separate extraction session.
|
|
202
|
+
|
|
203
|
+
The broker supplies the durable operation ID, never a model parameter.
|
|
204
|
+
A transport acknowledgment proves acceptance only, not indexing or IDs.
|
|
205
|
+
"""
|
|
206
|
+
request = MemoryWrite.model_validate(arguments)
|
|
207
|
+
if (
|
|
208
|
+
not request.content.strip()
|
|
209
|
+
or len(operation_id) != 64
|
|
210
|
+
or any(char not in "0123456789abcdef" for char in operation_id)
|
|
211
|
+
):
|
|
212
|
+
raise ValueError("MEMORY_WRITE_ARGUMENTS_INVALID")
|
|
213
|
+
# AICP limits SessionId to 64 characters. The broker operation ID is
|
|
214
|
+
# already a 64-character lowercase hex digest, so use it directly.
|
|
215
|
+
# Prefixing it made every real submission 73 characters long and the
|
|
216
|
+
# service rejected the write before extraction could start.
|
|
217
|
+
session_id = operation_id
|
|
218
|
+
event = json.dumps({"role": "user", "parts": [{"text": request.content}]})
|
|
219
|
+
with self._backend_call():
|
|
220
|
+
try:
|
|
221
|
+
accepted = self._backend.save_memory(
|
|
222
|
+
self.partition, [event], session_id=session_id, flush=True, strict=True
|
|
223
|
+
)
|
|
224
|
+
except Exception:
|
|
225
|
+
accepted = False
|
|
226
|
+
return {
|
|
227
|
+
"status": "accepted_pending" if accepted else "unknown",
|
|
228
|
+
"operationId": operation_id,
|
|
229
|
+
"searchable": False,
|
|
230
|
+
"errorCode": None if accepted else "MEMORY_WRITE_UNKNOWN",
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
def extraction_status(self, arguments: dict) -> dict:
|
|
234
|
+
query = MemoryStatusQuery.model_validate(arguments)
|
|
235
|
+
with self._backend_call():
|
|
236
|
+
result = self._backend.get_extraction_status(
|
|
237
|
+
user_id=self.partition,
|
|
238
|
+
session_id=query.operation_id,
|
|
239
|
+
)
|
|
240
|
+
return {
|
|
241
|
+
"operationId": query.operation_id,
|
|
242
|
+
"extractionStatus": result.status,
|
|
243
|
+
"searchable": False,
|
|
244
|
+
"errorCode": result.error_code or None,
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
def mutate(self, operation: str, arguments: dict, *, operation_id: str) -> dict:
|
|
248
|
+
"""Post-approval management of IDs observed in this bound user partition.
|
|
249
|
+
|
|
250
|
+
IDs are not authorization tokens: upstream receives the bound user on every
|
|
251
|
+
request. Restart requires fresh search. No CAS, hard deletion, or retry is
|
|
252
|
+
implied, and an ambiguous response permanently consumes the observed ID.
|
|
253
|
+
"""
|
|
254
|
+
MemoryStatusQuery(operation_id=operation_id)
|
|
255
|
+
if operation == "update_memory":
|
|
256
|
+
query = MemoryUpdate.model_validate(arguments)
|
|
257
|
+
if not query.content.strip():
|
|
258
|
+
raise ValueError("MEMORY_WRITE_ARGUMENTS_INVALID")
|
|
259
|
+
elif operation == "delete_memory":
|
|
260
|
+
query = MemoryRecordSelector.model_validate(arguments)
|
|
261
|
+
else:
|
|
262
|
+
raise ValueError("Unsupported memory mutation")
|
|
263
|
+
reply = {
|
|
264
|
+
"operationId": operation_id,
|
|
265
|
+
"memoryId": query.memory_id,
|
|
266
|
+
"newMemoryId": "",
|
|
267
|
+
"status": "unknown",
|
|
268
|
+
"errorCode": "MEMORY_MUTATION_UNKNOWN",
|
|
269
|
+
}
|
|
270
|
+
with self._backend_call():
|
|
271
|
+
if query.memory_id not in self._observed_ids:
|
|
272
|
+
return {**reply, "status": "failed", "errorCode": "MEMORY_RECORD_NOT_OBSERVED"}
|
|
273
|
+
del self._observed_ids[query.memory_id]
|
|
274
|
+
try:
|
|
275
|
+
if operation == "update_memory":
|
|
276
|
+
outcome = self._backend.update_memory(
|
|
277
|
+
user_id=self.partition,
|
|
278
|
+
memory_id=query.memory_id,
|
|
279
|
+
content=query.content,
|
|
280
|
+
strict=True,
|
|
281
|
+
)
|
|
282
|
+
else:
|
|
283
|
+
outcome = self._backend.delete_memory(
|
|
284
|
+
user_id=self.partition,
|
|
285
|
+
memory_id=query.memory_id,
|
|
286
|
+
strict=True,
|
|
287
|
+
)
|
|
288
|
+
expected = (
|
|
289
|
+
{"updated"} if operation == "update_memory" else {"deleted", "already_absent"}
|
|
290
|
+
)
|
|
291
|
+
if outcome.ok and outcome.status in expected:
|
|
292
|
+
new_id = outcome.new_memory_id if operation == "update_memory" else ""
|
|
293
|
+
if not isinstance(new_id, str) or len(new_id) > 256:
|
|
294
|
+
return reply
|
|
295
|
+
if new_id:
|
|
296
|
+
self._observed_ids[new_id] = None
|
|
297
|
+
return {
|
|
298
|
+
**reply,
|
|
299
|
+
"status": "succeeded",
|
|
300
|
+
"newMemoryId": new_id,
|
|
301
|
+
"errorCode": None,
|
|
302
|
+
}
|
|
303
|
+
if outcome.status == "not_found":
|
|
304
|
+
return {**reply, "status": "failed", "errorCode": "MEMORY_RECORD_NOT_FOUND"}
|
|
305
|
+
except Exception:
|
|
306
|
+
pass
|
|
307
|
+
return reply
|
|
308
|
+
|
|
309
|
+
def upsert(self, record: MemoryRecord, *, expected_version: int | None) -> MemoryRecord:
|
|
310
|
+
raise UnsupportedMemoryOperation(
|
|
311
|
+
"AICP writes require an approved asynchronous operation receipt"
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
def delete(self, request: MemoryDeleteRequest) -> MemoryDeleteResult:
|
|
315
|
+
raise UnsupportedMemoryOperation("AICP deletion requires an approved operation receipt")
|
|
316
|
+
|
|
317
|
+
def list_core(self, request: CoreMemoryRequest) -> list[MemoryRecord]:
|
|
318
|
+
raise UnsupportedMemoryOperation("AICP does not expose core-memory blocks")
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Bounded memory mutation metadata; never includes the stored memory body."""
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
from pydantic import Field, model_validator
|
|
6
|
+
|
|
7
|
+
from ksadk.plugins.contracts import PluginContractModel
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MemoryMutationReceipt(PluginContractModel):
|
|
11
|
+
operation_id: str = Field(strict=True, pattern=r"^[0-9a-f]{64}$")
|
|
12
|
+
memory_id: str = Field(strict=True, min_length=1, max_length=256)
|
|
13
|
+
new_memory_id: str = Field(default="", strict=True, max_length=256)
|
|
14
|
+
status: Literal["succeeded", "failed", "unknown"]
|
|
15
|
+
error_code: (
|
|
16
|
+
Literal["MEMORY_MUTATION_UNKNOWN", "MEMORY_RECORD_NOT_OBSERVED", "MEMORY_RECORD_NOT_FOUND"]
|
|
17
|
+
| None
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
@model_validator(mode="after")
|
|
21
|
+
def consistent_result(self):
|
|
22
|
+
if self.status == "succeeded":
|
|
23
|
+
if self.error_code is not None:
|
|
24
|
+
raise ValueError("Successful mutation cannot carry an error")
|
|
25
|
+
elif self.new_memory_id:
|
|
26
|
+
raise ValueError("Unconfirmed mutation cannot grant a new record ID")
|
|
27
|
+
elif self.status == "unknown" and self.error_code != "MEMORY_MUTATION_UNKNOWN":
|
|
28
|
+
raise ValueError("Unknown mutation requires an unknown result code")
|
|
29
|
+
elif self.status == "failed" and self.error_code not in {
|
|
30
|
+
"MEMORY_RECORD_NOT_OBSERVED",
|
|
31
|
+
"MEMORY_RECORD_NOT_FOUND",
|
|
32
|
+
}:
|
|
33
|
+
raise ValueError("Failed mutation requires a confirmed rejection")
|
|
34
|
+
return self
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"""Durable duplicate suppression for host-authorized resource writes.
|
|
2
|
+
|
|
3
|
+
This ledger is not an approval authority. The host supplies a stable event ID
|
|
4
|
+
across checkpoint recovery and an identity/binding digest after admission.
|
|
5
|
+
Claiming commits before dispatch. A lost claimant leaves an unknown operation;
|
|
6
|
+
opening the database never grants permission to resend it.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import hashlib
|
|
12
|
+
import json
|
|
13
|
+
import sqlite3
|
|
14
|
+
from contextlib import contextmanager
|
|
15
|
+
from dataclasses import dataclass
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
from typing import Literal
|
|
18
|
+
|
|
19
|
+
from ksadk.resource_runtime.memory_receipts import MemoryMutationReceipt
|
|
20
|
+
|
|
21
|
+
OperationState = Literal["unknown", "accepted_pending", "searchable", "succeeded", "failed"]
|
|
22
|
+
_TRANSITIONS = {
|
|
23
|
+
"unknown": {"accepted_pending", "searchable", "succeeded", "failed"},
|
|
24
|
+
"accepted_pending": {"searchable", "failed"},
|
|
25
|
+
"searchable": set(),
|
|
26
|
+
"succeeded": set(),
|
|
27
|
+
"failed": set(),
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass(frozen=True)
|
|
32
|
+
class OperationReceipt:
|
|
33
|
+
operation_id: str
|
|
34
|
+
state: OperationState
|
|
35
|
+
claimed: bool
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class OperationConflict(ValueError):
|
|
39
|
+
"""The same event was reused with different arguments or an invalid transition."""
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class OperationLedger:
|
|
43
|
+
"""SQLite ledger in a host-owned private directory; no request bodies stored.
|
|
44
|
+
|
|
45
|
+
Each method uses its own transaction so independent runtime processes share
|
|
46
|
+
duplicate suppression. Retention must cover all recoverable checkpoints.
|
|
47
|
+
Callers may record failed only after authoritative failure, never timeout.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
def __init__(self, directory: Path):
|
|
51
|
+
directory = Path(directory)
|
|
52
|
+
directory.mkdir(mode=0o700, parents=True, exist_ok=True)
|
|
53
|
+
if directory.is_symlink() or directory.stat().st_mode & 0o077:
|
|
54
|
+
raise ValueError("Operation ledger requires a private directory")
|
|
55
|
+
self.path = directory / "resource-operations.sqlite3"
|
|
56
|
+
if self.path.is_symlink():
|
|
57
|
+
raise ValueError("Operation ledger cannot be a symbolic link")
|
|
58
|
+
with self._connect() as connection:
|
|
59
|
+
connection.execute(
|
|
60
|
+
"CREATE TABLE IF NOT EXISTS operations ("
|
|
61
|
+
"id TEXT PRIMARY KEY, request_digest TEXT NOT NULL, state TEXT NOT NULL)"
|
|
62
|
+
)
|
|
63
|
+
connection.execute(
|
|
64
|
+
"CREATE TABLE IF NOT EXISTS operation_owners ("
|
|
65
|
+
"id TEXT PRIMARY KEY, authority_digest TEXT NOT NULL, operation TEXT NOT NULL)"
|
|
66
|
+
)
|
|
67
|
+
connection.execute(
|
|
68
|
+
"CREATE TABLE IF NOT EXISTS memory_mutation_results ("
|
|
69
|
+
"id TEXT PRIMARY KEY, payload TEXT NOT NULL)"
|
|
70
|
+
)
|
|
71
|
+
self.path.chmod(0o600)
|
|
72
|
+
|
|
73
|
+
@contextmanager
|
|
74
|
+
def _connect(self):
|
|
75
|
+
connection = sqlite3.connect(self.path, timeout=10)
|
|
76
|
+
try:
|
|
77
|
+
with connection:
|
|
78
|
+
yield connection
|
|
79
|
+
finally:
|
|
80
|
+
connection.close()
|
|
81
|
+
|
|
82
|
+
@staticmethod
|
|
83
|
+
def _key(authority_digest: str, event_id: str, operation: str) -> str:
|
|
84
|
+
if not all(
|
|
85
|
+
isinstance(v, str) and 0 < len(v) <= 1024
|
|
86
|
+
for v in (authority_digest, event_id, operation)
|
|
87
|
+
):
|
|
88
|
+
raise ValueError("Invalid operation identity")
|
|
89
|
+
payload = json.dumps(
|
|
90
|
+
["resource-operation-v1", authority_digest, event_id, operation],
|
|
91
|
+
separators=(",", ":"),
|
|
92
|
+
ensure_ascii=True,
|
|
93
|
+
)
|
|
94
|
+
return hashlib.sha256(payload.encode()).hexdigest()
|
|
95
|
+
|
|
96
|
+
def claim(
|
|
97
|
+
self, *, authority_digest: str, event_id: str, operation: str, arguments: dict
|
|
98
|
+
) -> OperationReceipt:
|
|
99
|
+
operation_id = self._key(authority_digest, event_id, operation)
|
|
100
|
+
encoded = json.dumps(arguments, sort_keys=True, separators=(",", ":"), allow_nan=False)
|
|
101
|
+
request_digest = hashlib.sha256(encoded.encode()).hexdigest()
|
|
102
|
+
with self._connect() as connection:
|
|
103
|
+
connection.execute("BEGIN IMMEDIATE")
|
|
104
|
+
row = connection.execute(
|
|
105
|
+
"SELECT request_digest, state FROM operations WHERE id = ?", (operation_id,)
|
|
106
|
+
).fetchone()
|
|
107
|
+
if row is not None:
|
|
108
|
+
if row[0] != request_digest:
|
|
109
|
+
raise OperationConflict("RESOURCE_OPERATION_ARGUMENTS_CHANGED")
|
|
110
|
+
connection.execute(
|
|
111
|
+
"INSERT OR IGNORE INTO operation_owners VALUES (?, ?, ?)",
|
|
112
|
+
(operation_id, authority_digest, operation),
|
|
113
|
+
)
|
|
114
|
+
return OperationReceipt(operation_id, row[1], False)
|
|
115
|
+
connection.execute(
|
|
116
|
+
"INSERT INTO operations VALUES (?, ?, 'unknown')", (operation_id, request_digest)
|
|
117
|
+
)
|
|
118
|
+
connection.execute(
|
|
119
|
+
"INSERT INTO operation_owners VALUES (?, ?, ?)",
|
|
120
|
+
(operation_id, authority_digest, operation),
|
|
121
|
+
)
|
|
122
|
+
return OperationReceipt(operation_id, "unknown", True)
|
|
123
|
+
|
|
124
|
+
def lookup(
|
|
125
|
+
self, operation_id: str, *, authority_digest: str, operation: str
|
|
126
|
+
) -> OperationReceipt | None:
|
|
127
|
+
"""Opaque IDs alone grant no access. Legacy rows without owners stay hidden."""
|
|
128
|
+
with self._connect() as connection:
|
|
129
|
+
row = connection.execute(
|
|
130
|
+
"SELECT o.state FROM operations o JOIN operation_owners p ON o.id=p.id "
|
|
131
|
+
"WHERE o.id=? AND p.authority_digest=? AND p.operation=?",
|
|
132
|
+
(operation_id, authority_digest, operation),
|
|
133
|
+
).fetchone()
|
|
134
|
+
return None if row is None else OperationReceipt(operation_id, row[0], False)
|
|
135
|
+
|
|
136
|
+
def record(self, operation_id: str, state: OperationState) -> OperationReceipt:
|
|
137
|
+
with self._connect() as connection:
|
|
138
|
+
connection.execute("BEGIN IMMEDIATE")
|
|
139
|
+
row = connection.execute(
|
|
140
|
+
"SELECT state FROM operations WHERE id = ?", (operation_id,)
|
|
141
|
+
).fetchone()
|
|
142
|
+
if row is None or state not in _TRANSITIONS:
|
|
143
|
+
raise OperationConflict("RESOURCE_OPERATION_UNKNOWN")
|
|
144
|
+
if state != row[0] and state not in _TRANSITIONS[row[0]]:
|
|
145
|
+
raise OperationConflict("RESOURCE_OPERATION_STATE_CONFLICT")
|
|
146
|
+
connection.execute(
|
|
147
|
+
"UPDATE operations SET state = ? WHERE id = ?", (state, operation_id)
|
|
148
|
+
)
|
|
149
|
+
return OperationReceipt(operation_id, state, False)
|
|
150
|
+
|
|
151
|
+
def record_memory_mutation(
|
|
152
|
+
self,
|
|
153
|
+
result: MemoryMutationReceipt,
|
|
154
|
+
*,
|
|
155
|
+
authority_digest: str,
|
|
156
|
+
operation: str,
|
|
157
|
+
) -> OperationReceipt:
|
|
158
|
+
"""Commit terminal state and returned record IDs in one transaction."""
|
|
159
|
+
result = MemoryMutationReceipt.model_validate(result.model_dump())
|
|
160
|
+
if operation not in {"update_memory", "delete_memory"} or result.status == "unknown":
|
|
161
|
+
raise OperationConflict("RESOURCE_OPERATION_RESULT_INVALID")
|
|
162
|
+
if operation == "delete_memory" and result.new_memory_id:
|
|
163
|
+
raise OperationConflict("RESOURCE_OPERATION_RESULT_INVALID")
|
|
164
|
+
payload = result.model_dump_json(by_alias=True)
|
|
165
|
+
with self._connect() as connection:
|
|
166
|
+
connection.execute("BEGIN IMMEDIATE")
|
|
167
|
+
row = connection.execute(
|
|
168
|
+
"SELECT o.state FROM operations o JOIN operation_owners p ON o.id=p.id "
|
|
169
|
+
"WHERE o.id=? AND p.authority_digest=? AND p.operation=?",
|
|
170
|
+
(result.operation_id, authority_digest, operation),
|
|
171
|
+
).fetchone()
|
|
172
|
+
if row is None:
|
|
173
|
+
raise OperationConflict("RESOURCE_OPERATION_UNKNOWN")
|
|
174
|
+
if result.status != row[0] and result.status not in _TRANSITIONS[row[0]]:
|
|
175
|
+
raise OperationConflict("RESOURCE_OPERATION_STATE_CONFLICT")
|
|
176
|
+
previous = connection.execute(
|
|
177
|
+
"SELECT payload FROM memory_mutation_results WHERE id=?",
|
|
178
|
+
(result.operation_id,),
|
|
179
|
+
).fetchone()
|
|
180
|
+
if previous is not None and previous[0] != payload:
|
|
181
|
+
raise OperationConflict("RESOURCE_OPERATION_RESULT_CONFLICT")
|
|
182
|
+
connection.execute(
|
|
183
|
+
"INSERT OR IGNORE INTO memory_mutation_results VALUES (?, ?)",
|
|
184
|
+
(result.operation_id, payload),
|
|
185
|
+
)
|
|
186
|
+
connection.execute(
|
|
187
|
+
"UPDATE operations SET state=? WHERE id=?",
|
|
188
|
+
(result.status, result.operation_id),
|
|
189
|
+
)
|
|
190
|
+
return OperationReceipt(result.operation_id, result.status, False)
|
|
191
|
+
|
|
192
|
+
def memory_mutation_result(
|
|
193
|
+
self,
|
|
194
|
+
operation_id: str,
|
|
195
|
+
*,
|
|
196
|
+
authority_digest: str,
|
|
197
|
+
operation: str,
|
|
198
|
+
) -> dict | None:
|
|
199
|
+
with self._connect() as connection:
|
|
200
|
+
row = connection.execute(
|
|
201
|
+
"SELECT r.payload, o.state FROM memory_mutation_results r "
|
|
202
|
+
"JOIN operations o ON o.id=r.id JOIN operation_owners p ON p.id=r.id "
|
|
203
|
+
"WHERE r.id=? AND p.authority_digest=? AND p.operation=?",
|
|
204
|
+
(operation_id, authority_digest, operation),
|
|
205
|
+
).fetchone()
|
|
206
|
+
if row is None:
|
|
207
|
+
return None
|
|
208
|
+
result = MemoryMutationReceipt.model_validate_json(row[0])
|
|
209
|
+
if result.operation_id != operation_id or result.status != row[1]:
|
|
210
|
+
raise OperationConflict("RESOURCE_OPERATION_RESULT_CONFLICT")
|
|
211
|
+
return result.model_dump(by_alias=True, mode="json")
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""Data-only configuration contracts for the three official resource bundles.
|
|
2
|
+
|
|
3
|
+
These reserved plugin IDs map to scoped npm packages; recognizing an ID validates
|
|
4
|
+
configuration only. Installation identity and authorization still require Build
|
|
5
|
+
receipts and trusted activation admission.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from collections.abc import Mapping, Sequence
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
from ksadk.resource_runtime.contracts import ResourceConfig, validate_resource_bindings
|
|
14
|
+
|
|
15
|
+
OFFICIAL_RESOURCE_PLUGINS = {
|
|
16
|
+
"kingsoftcloud.dsh-knowledge": "knowledge-base",
|
|
17
|
+
"kingsoftcloud.dsh-memory": "memory-instance",
|
|
18
|
+
"kingsoftcloud.dsh-skill-center": "skill-space",
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def resource_plugin_config(
|
|
23
|
+
plugin_ref: str, ecosystem: str, config: Mapping[str, Any], *, enabled: bool
|
|
24
|
+
) -> ResourceConfig | None:
|
|
25
|
+
plugin_id = plugin_ref.removeprefix("plugin://").rsplit("@", 1)[0]
|
|
26
|
+
kind = OFFICIAL_RESOURCE_PLUGINS.get(plugin_id)
|
|
27
|
+
if kind is None:
|
|
28
|
+
return None
|
|
29
|
+
if ecosystem != "dsh":
|
|
30
|
+
raise ValueError("Official platform resource plugins require the DSH ecosystem")
|
|
31
|
+
if not config and not enabled:
|
|
32
|
+
return None
|
|
33
|
+
parsed = ResourceConfig.model_validate(config)
|
|
34
|
+
if parsed.binding.resource.kind != kind:
|
|
35
|
+
raise ValueError("Resource kind does not match the official plugin")
|
|
36
|
+
return parsed
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def validate_resource_plugin_bindings(bindings: Sequence[Any]) -> None:
|
|
40
|
+
resources = []
|
|
41
|
+
for binding in bindings:
|
|
42
|
+
if binding.enabled:
|
|
43
|
+
resource = resource_plugin_config(
|
|
44
|
+
binding.plugin_ref, binding.ecosystem, binding.config, enabled=True
|
|
45
|
+
)
|
|
46
|
+
if resource is not None:
|
|
47
|
+
resources.append(resource)
|
|
48
|
+
validate_resource_bindings(tuple(resources))
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""Request-scoped host authorization for resource writes."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
import json
|
|
7
|
+
|
|
8
|
+
from ksadk.resource_runtime.ipc import ResourceRequest
|
|
9
|
+
from ksadk.resource_runtime.leases import ResourceScope
|
|
10
|
+
|
|
11
|
+
_WRITES = frozenset({"save_memory", "update_memory", "delete_memory", "execute_skills"})
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class FullAccessResourceWriteAuthorizer:
|
|
15
|
+
"""Authorize exact writes covered by a trusted full-access invocation.
|
|
16
|
+
|
|
17
|
+
The Studio/API ingress chooses the approval profile. Capability plugins only
|
|
18
|
+
receive this authorizer after the trusted host has resolved that profile for
|
|
19
|
+
the current activation. The returned event reference binds the decision to
|
|
20
|
+
the exact scope and arguments so OperationLedger can fence retries.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, *, activation_key: str) -> None:
|
|
24
|
+
if not activation_key or any(character.isspace() for character in activation_key):
|
|
25
|
+
raise ValueError("RESOURCE_APPROVAL_ACTIVATION_INVALID")
|
|
26
|
+
self._activation_key = activation_key
|
|
27
|
+
|
|
28
|
+
async def authorize(self, request: ResourceRequest, scope: ResourceScope) -> str | None:
|
|
29
|
+
if request.operation not in _WRITES or request.operation not in scope.allowed_operations:
|
|
30
|
+
return None
|
|
31
|
+
payload = {
|
|
32
|
+
"version": 1,
|
|
33
|
+
"approvalProfile": "full",
|
|
34
|
+
"activationKey": self._activation_key,
|
|
35
|
+
"identity": scope.identity.model_dump(mode="json"),
|
|
36
|
+
"build": scope.build_digest,
|
|
37
|
+
"binding": scope.binding_id,
|
|
38
|
+
"snapshot": scope.binding_snapshot_digest,
|
|
39
|
+
"operation": request.operation,
|
|
40
|
+
"arguments": request.arguments,
|
|
41
|
+
}
|
|
42
|
+
digest = hashlib.sha256(
|
|
43
|
+
json.dumps(
|
|
44
|
+
payload,
|
|
45
|
+
ensure_ascii=False,
|
|
46
|
+
sort_keys=True,
|
|
47
|
+
separators=(",", ":"),
|
|
48
|
+
allow_nan=False,
|
|
49
|
+
).encode()
|
|
50
|
+
).hexdigest()
|
|
51
|
+
return f"studio-full-access:{digest}"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
__all__ = ["FullAccessResourceWriteAuthorizer"]
|