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
ksadk/sessions/resilient.py
CHANGED
|
@@ -2,14 +2,19 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import logging
|
|
5
|
+
from collections.abc import AsyncIterator
|
|
6
|
+
from contextvars import ContextVar
|
|
5
7
|
from typing import Any, Optional, cast
|
|
6
8
|
|
|
7
9
|
from ksadk.sessions.base import (
|
|
8
10
|
BaseSessionService,
|
|
11
|
+
CheckpointEventQuery,
|
|
9
12
|
Session,
|
|
10
13
|
SessionEvent,
|
|
14
|
+
SessionEventQuery,
|
|
11
15
|
SessionState,
|
|
12
16
|
)
|
|
17
|
+
from ksadk.sessions.errors import CheckpointScanRestartRequired
|
|
13
18
|
from ksadk.sessions.in_memory import InMemorySessionService
|
|
14
19
|
from ksadk.sessions.resilience import is_session_backend_failure
|
|
15
20
|
|
|
@@ -39,17 +44,30 @@ class ResilientSessionService(BaseSessionService):
|
|
|
39
44
|
self._hydrate_lock = asyncio.Lock()
|
|
40
45
|
self._primary_session_lock = asyncio.Lock()
|
|
41
46
|
self._primary_session_ids: set[str] = set()
|
|
47
|
+
self._dirty_session_ids: set[str] = set()
|
|
48
|
+
self._checkpoint_partition: ContextVar[
|
|
49
|
+
tuple[frozenset[str], frozenset[str]] | None
|
|
50
|
+
] = ContextVar(f"checkpoint_partition_{id(self)}", default=None)
|
|
42
51
|
self._probe_task: asyncio.Task[None] | None = None
|
|
43
52
|
|
|
53
|
+
@property
|
|
54
|
+
def canonical_event_service(self) -> BaseSessionService:
|
|
55
|
+
"""Return the single durable authority for canonical runtime facts.
|
|
56
|
+
|
|
57
|
+
Legacy session state remains live-first. Canonical event sequences cannot
|
|
58
|
+
fail over to the independently sequenced fallback without splitting one
|
|
59
|
+
logical log, so RuntimeEventStore binds directly to the primary service.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
return self.primary
|
|
63
|
+
|
|
44
64
|
@property
|
|
45
65
|
def degraded(self) -> bool:
|
|
46
66
|
return not self._primary_enabled
|
|
47
67
|
|
|
48
68
|
# This service is intentionally live-first and writes two independently
|
|
49
|
-
# sequenced stores
|
|
50
|
-
#
|
|
51
|
-
# both writes, so it inherits BaseSessionService's empty canonical storage
|
|
52
|
-
# capabilities and RuntimeEventStore fails closed before either write.
|
|
69
|
+
# sequenced stores, so the wrapper itself does not claim canonical storage
|
|
70
|
+
# capabilities.
|
|
53
71
|
|
|
54
72
|
async def _call_primary(self, method_name: str, *args: Any, **kwargs: Any) -> tuple[bool, Any]:
|
|
55
73
|
if not self._primary_enabled:
|
|
@@ -326,6 +344,346 @@ class ResilientSessionService(BaseSessionService):
|
|
|
326
344
|
await self.fallback.count_events(session_id, after_seq_id, before_seq_id),
|
|
327
345
|
)
|
|
328
346
|
|
|
347
|
+
async def get_sessions_by_ids(self, session_ids: list[str]) -> list[Session]:
|
|
348
|
+
result: dict[str, Session] = {}
|
|
349
|
+
ok, durable = await self._call_primary("get_sessions_by_ids", session_ids)
|
|
350
|
+
if ok:
|
|
351
|
+
result.update({session.id: session for session in durable or []})
|
|
352
|
+
live = await self.fallback.get_sessions_by_ids(session_ids)
|
|
353
|
+
result.update({session.id: session for session in live})
|
|
354
|
+
return [result[session_id] for session_id in session_ids if session_id in result]
|
|
355
|
+
|
|
356
|
+
async def list_session_metadata(
|
|
357
|
+
self, agent_id: Optional[str] = None, user_id: Optional[str] = None
|
|
358
|
+
) -> list[Session]:
|
|
359
|
+
result: dict[str, Session] = {}
|
|
360
|
+
ok, durable = await self._call_primary("list_session_metadata", agent_id, user_id)
|
|
361
|
+
if ok:
|
|
362
|
+
result.update({session.id: session for session in durable or []})
|
|
363
|
+
live = await self.fallback.list_session_metadata(agent_id, user_id)
|
|
364
|
+
result.update({session.id: session for session in live})
|
|
365
|
+
sessions = list(result.values())
|
|
366
|
+
sessions.sort(key=lambda item: (item.updated_at, item.created_at, item.id), reverse=True)
|
|
367
|
+
return sessions
|
|
368
|
+
|
|
369
|
+
async def _partition_query_session_ids(
|
|
370
|
+
self, session_ids: list[str] | None, agent_id: str | None
|
|
371
|
+
) -> tuple[list[str], list[str]]:
|
|
372
|
+
if session_ids is None:
|
|
373
|
+
sessions = await self.list_session_metadata(agent_id)
|
|
374
|
+
ids = [session.id for session in sessions]
|
|
375
|
+
else:
|
|
376
|
+
ids = list(dict.fromkeys(session_ids))
|
|
377
|
+
dirty = set(self._dirty_session_ids)
|
|
378
|
+
durable_ids: set[str] = set()
|
|
379
|
+
if ids:
|
|
380
|
+
ok, durable_metadata = await self._call_primary("get_sessions_by_ids", ids)
|
|
381
|
+
if ok:
|
|
382
|
+
durable_ids = {session.id for session in durable_metadata or []}
|
|
383
|
+
live_metadata = await self.fallback.get_sessions_by_ids(ids)
|
|
384
|
+
live_ids = {session.id for session in live_metadata}
|
|
385
|
+
clean_ids = [
|
|
386
|
+
session_id
|
|
387
|
+
for session_id in ids
|
|
388
|
+
if session_id not in dirty and session_id in durable_ids
|
|
389
|
+
]
|
|
390
|
+
fallback_ids = [
|
|
391
|
+
session_id for session_id in ids if session_id in dirty or session_id in live_ids
|
|
392
|
+
]
|
|
393
|
+
return clean_ids, fallback_ids
|
|
394
|
+
|
|
395
|
+
async def query_events(self, query: SessionEventQuery) -> list[SessionEvent]:
|
|
396
|
+
clean_ids, live_ids = await self._partition_query_session_ids(
|
|
397
|
+
query.session_ids, query.agent_id
|
|
398
|
+
)
|
|
399
|
+
window = query.offset + query.limit
|
|
400
|
+
durable_events: list[SessionEvent] = []
|
|
401
|
+
if clean_ids:
|
|
402
|
+
ok, result = await self._call_primary(
|
|
403
|
+
"query_events",
|
|
404
|
+
SessionEventQuery(
|
|
405
|
+
**{**query.__dict__, "session_ids": clean_ids, "offset": 0, "limit": window}
|
|
406
|
+
),
|
|
407
|
+
)
|
|
408
|
+
if ok:
|
|
409
|
+
durable_events = cast(list[SessionEvent], result or [])
|
|
410
|
+
else:
|
|
411
|
+
return await self.fallback.query_events(query)
|
|
412
|
+
live_events = (
|
|
413
|
+
await self.fallback.query_events(
|
|
414
|
+
SessionEventQuery(
|
|
415
|
+
**{**query.__dict__, "session_ids": live_ids, "offset": 0, "limit": window}
|
|
416
|
+
)
|
|
417
|
+
)
|
|
418
|
+
if live_ids
|
|
419
|
+
else []
|
|
420
|
+
)
|
|
421
|
+
merged_by_id = {event.id: event for event in [*durable_events, *live_events]}
|
|
422
|
+
merged = list(merged_by_id.values())
|
|
423
|
+
if query.order_by_seq:
|
|
424
|
+
merged.sort(key=lambda event: (event.session_id, event.seq_id, event.id))
|
|
425
|
+
else:
|
|
426
|
+
merged.sort(
|
|
427
|
+
key=lambda event: (event.timestamp, event.session_id, event.seq_id, event.id)
|
|
428
|
+
)
|
|
429
|
+
if query.from_start:
|
|
430
|
+
return merged[query.offset : query.offset + query.limit]
|
|
431
|
+
end = max(len(merged) - query.offset, 0)
|
|
432
|
+
return merged[max(end - query.limit, 0) : end]
|
|
433
|
+
|
|
434
|
+
async def count_event_query(self, query: SessionEventQuery) -> int:
|
|
435
|
+
# Deduplicate by physical event id because a hydrated clean session may
|
|
436
|
+
# be present in both children during recovery.
|
|
437
|
+
events = await self.query_events(
|
|
438
|
+
SessionEventQuery(
|
|
439
|
+
**{
|
|
440
|
+
**query.__dict__,
|
|
441
|
+
"offset": 0,
|
|
442
|
+
"limit": 2**31 - 1,
|
|
443
|
+
"from_start": True,
|
|
444
|
+
}
|
|
445
|
+
)
|
|
446
|
+
)
|
|
447
|
+
return len(events)
|
|
448
|
+
|
|
449
|
+
async def get_checkpoint_lookup_stats(
|
|
450
|
+
self, session_id: str, run_id: str, checkpoint_id: str
|
|
451
|
+
) -> dict[str, object]:
|
|
452
|
+
if session_id not in self._dirty_session_ids:
|
|
453
|
+
ok, stats = await self._call_primary(
|
|
454
|
+
"get_checkpoint_lookup_stats", session_id, run_id, checkpoint_id
|
|
455
|
+
)
|
|
456
|
+
if ok:
|
|
457
|
+
return cast(dict[str, object], stats)
|
|
458
|
+
return await self.fallback.get_checkpoint_lookup_stats(
|
|
459
|
+
session_id, run_id, checkpoint_id
|
|
460
|
+
)
|
|
461
|
+
|
|
462
|
+
async def scan_checkpoint_events(
|
|
463
|
+
self, query: CheckpointEventQuery
|
|
464
|
+
) -> list[SessionEvent]:
|
|
465
|
+
if query.limit < 1 or query.limit > 50:
|
|
466
|
+
raise ValueError("checkpoint scan limit must be between 1 and 50")
|
|
467
|
+
clean_ids, live_ids = await self._partition_query_session_ids(
|
|
468
|
+
query.session_ids, query.agent_id
|
|
469
|
+
)
|
|
470
|
+
if clean_ids and not live_ids:
|
|
471
|
+
ok, result = await self._call_primary(
|
|
472
|
+
"scan_checkpoint_events",
|
|
473
|
+
CheckpointEventQuery(**{**query.__dict__, "session_ids": clean_ids}),
|
|
474
|
+
)
|
|
475
|
+
if ok:
|
|
476
|
+
return cast(list[SessionEvent], result or [])
|
|
477
|
+
return await self.fallback.scan_checkpoint_events(query)
|
|
478
|
+
if live_ids and not clean_ids:
|
|
479
|
+
return await self.fallback.scan_checkpoint_events(
|
|
480
|
+
CheckpointEventQuery(**{**query.__dict__, "session_ids": live_ids})
|
|
481
|
+
)
|
|
482
|
+
window = query.offset + query.limit
|
|
483
|
+
durable: list[SessionEvent] = []
|
|
484
|
+
if clean_ids:
|
|
485
|
+
ok, result = await self._call_primary(
|
|
486
|
+
"scan_checkpoint_events",
|
|
487
|
+
CheckpointEventQuery(
|
|
488
|
+
**{
|
|
489
|
+
**query.__dict__,
|
|
490
|
+
"session_ids": clean_ids,
|
|
491
|
+
"offset": 0,
|
|
492
|
+
"limit": min(window, 50),
|
|
493
|
+
}
|
|
494
|
+
),
|
|
495
|
+
)
|
|
496
|
+
if ok:
|
|
497
|
+
durable = cast(list[SessionEvent], result or [])
|
|
498
|
+
else:
|
|
499
|
+
return await self.fallback.scan_checkpoint_events(query)
|
|
500
|
+
live = (
|
|
501
|
+
await self.fallback.scan_checkpoint_events(
|
|
502
|
+
CheckpointEventQuery(
|
|
503
|
+
**{
|
|
504
|
+
**query.__dict__,
|
|
505
|
+
"session_ids": live_ids,
|
|
506
|
+
"offset": 0,
|
|
507
|
+
"limit": min(window, 50),
|
|
508
|
+
}
|
|
509
|
+
)
|
|
510
|
+
)
|
|
511
|
+
if live_ids
|
|
512
|
+
else []
|
|
513
|
+
)
|
|
514
|
+
merged = list({event.id: event for event in [*durable, *live]}.values())
|
|
515
|
+
merged.sort(key=lambda event: (event.timestamp, event.session_id, event.seq_id, event.id))
|
|
516
|
+
return merged[query.offset : query.offset + query.limit]
|
|
517
|
+
|
|
518
|
+
async def iter_checkpoint_event_chunks(
|
|
519
|
+
self, query: CheckpointEventQuery
|
|
520
|
+
) -> AsyncIterator[list[SessionEvent]]:
|
|
521
|
+
if query.limit < 1 or query.limit > 50:
|
|
522
|
+
raise ValueError("checkpoint scan limit must be between 1 and 50")
|
|
523
|
+
clean_ids, live_ids = await self._partition_query_session_ids(
|
|
524
|
+
query.session_ids, query.agent_id
|
|
525
|
+
)
|
|
526
|
+
token = self._checkpoint_partition.set(
|
|
527
|
+
(frozenset(clean_ids), frozenset(live_ids))
|
|
528
|
+
)
|
|
529
|
+
batches = self._iter_checkpoint_event_chunks_partitioned(
|
|
530
|
+
query, clean_ids, live_ids
|
|
531
|
+
).__aiter__()
|
|
532
|
+
try:
|
|
533
|
+
async for batch in batches:
|
|
534
|
+
yield batch
|
|
535
|
+
finally:
|
|
536
|
+
close = getattr(batches, "aclose", None)
|
|
537
|
+
if callable(close):
|
|
538
|
+
await close()
|
|
539
|
+
self._checkpoint_partition.reset(token)
|
|
540
|
+
|
|
541
|
+
async def _iter_checkpoint_event_chunks_partitioned(
|
|
542
|
+
self,
|
|
543
|
+
query: CheckpointEventQuery,
|
|
544
|
+
clean_ids: list[str],
|
|
545
|
+
live_ids: list[str],
|
|
546
|
+
) -> AsyncIterator[list[SessionEvent]]:
|
|
547
|
+
if query.limit < 1 or query.limit > 50:
|
|
548
|
+
raise ValueError("checkpoint scan limit must be between 1 and 50")
|
|
549
|
+
if not clean_ids:
|
|
550
|
+
batches = self.fallback.iter_checkpoint_event_chunks(
|
|
551
|
+
CheckpointEventQuery(**{**query.__dict__, "session_ids": live_ids})
|
|
552
|
+
).__aiter__()
|
|
553
|
+
try:
|
|
554
|
+
async for batch in batches:
|
|
555
|
+
yield batch
|
|
556
|
+
finally:
|
|
557
|
+
close = getattr(batches, "aclose", None)
|
|
558
|
+
if callable(close):
|
|
559
|
+
await close()
|
|
560
|
+
return
|
|
561
|
+
if not live_ids:
|
|
562
|
+
batches = self.primary.iter_checkpoint_event_chunks(
|
|
563
|
+
CheckpointEventQuery(**{**query.__dict__, "session_ids": clean_ids})
|
|
564
|
+
).__aiter__()
|
|
565
|
+
try:
|
|
566
|
+
async for batch in batches:
|
|
567
|
+
yield batch
|
|
568
|
+
except Exception as exc:
|
|
569
|
+
if not is_session_backend_failure(exc):
|
|
570
|
+
raise
|
|
571
|
+
self._disable_primary(exc)
|
|
572
|
+
raise CheckpointScanRestartRequired(
|
|
573
|
+
"primary failed during clean checkpoint scan"
|
|
574
|
+
) from exc
|
|
575
|
+
finally:
|
|
576
|
+
close = getattr(batches, "aclose", None)
|
|
577
|
+
if callable(close):
|
|
578
|
+
await close()
|
|
579
|
+
return
|
|
580
|
+
|
|
581
|
+
iterators = {
|
|
582
|
+
"clean": self.primary.iter_checkpoint_event_chunks(
|
|
583
|
+
CheckpointEventQuery(
|
|
584
|
+
**{**query.__dict__, "session_ids": clean_ids, "offset": 0, "limit": 50}
|
|
585
|
+
)
|
|
586
|
+
).__aiter__(),
|
|
587
|
+
"live": self.fallback.iter_checkpoint_event_chunks(
|
|
588
|
+
CheckpointEventQuery(
|
|
589
|
+
**{**query.__dict__, "session_ids": live_ids, "offset": 0, "limit": 50}
|
|
590
|
+
)
|
|
591
|
+
).__aiter__(),
|
|
592
|
+
}
|
|
593
|
+
pages: dict[str, list[SessionEvent]] = {"clean": [], "live": []}
|
|
594
|
+
indexes = {"clean": 0, "live": 0}
|
|
595
|
+
exhausted = {"clean": False, "live": False}
|
|
596
|
+
skipped = 0
|
|
597
|
+
|
|
598
|
+
async def load(kind: str) -> None:
|
|
599
|
+
try:
|
|
600
|
+
pages[kind] = await anext(iterators[kind])
|
|
601
|
+
except StopAsyncIteration:
|
|
602
|
+
pages[kind] = []
|
|
603
|
+
exhausted[kind] = True
|
|
604
|
+
except Exception as exc:
|
|
605
|
+
if kind != "clean" or not is_session_backend_failure(exc):
|
|
606
|
+
raise
|
|
607
|
+
self._disable_primary(exc)
|
|
608
|
+
raise CheckpointScanRestartRequired(
|
|
609
|
+
"primary failed during mixed checkpoint scan"
|
|
610
|
+
) from exc
|
|
611
|
+
indexes[kind] = 0
|
|
612
|
+
if len(pages[kind]) < 50:
|
|
613
|
+
exhausted[kind] = True
|
|
614
|
+
|
|
615
|
+
try:
|
|
616
|
+
await load("clean")
|
|
617
|
+
await load("live")
|
|
618
|
+
output: list[SessionEvent] = []
|
|
619
|
+
while True:
|
|
620
|
+
for kind in ("clean", "live"):
|
|
621
|
+
if indexes[kind] >= len(pages[kind]) and not exhausted[kind]:
|
|
622
|
+
await load(kind)
|
|
623
|
+
candidates = [
|
|
624
|
+
(event.timestamp, event.session_id, event.seq_id, event.id, kind, event)
|
|
625
|
+
for kind in ("clean", "live")
|
|
626
|
+
for event in pages[kind][indexes[kind] : indexes[kind] + 1]
|
|
627
|
+
]
|
|
628
|
+
if not candidates:
|
|
629
|
+
if output:
|
|
630
|
+
yield output
|
|
631
|
+
break
|
|
632
|
+
*_, kind, event = min(candidates)
|
|
633
|
+
indexes[kind] += 1
|
|
634
|
+
if skipped < query.offset:
|
|
635
|
+
skipped += 1
|
|
636
|
+
continue
|
|
637
|
+
output.append(event)
|
|
638
|
+
if len(output) == query.limit:
|
|
639
|
+
yield output
|
|
640
|
+
output = []
|
|
641
|
+
finally:
|
|
642
|
+
for iterator in iterators.values():
|
|
643
|
+
close = getattr(iterator, "aclose", None)
|
|
644
|
+
if callable(close):
|
|
645
|
+
await close()
|
|
646
|
+
|
|
647
|
+
async def get_checkpoint_stats(
|
|
648
|
+
self, keys: list[tuple[str, str, str]]
|
|
649
|
+
) -> dict[str, object]:
|
|
650
|
+
if len(keys) > 50:
|
|
651
|
+
raise ValueError("checkpoint stats batch cannot exceed 50 keys")
|
|
652
|
+
unique_keys = list(dict.fromkeys(keys))
|
|
653
|
+
active = self._checkpoint_partition.get()
|
|
654
|
+
if active is None:
|
|
655
|
+
clean_ids, live_ids = await self._partition_query_session_ids(
|
|
656
|
+
list(dict.fromkeys(key[0] for key in unique_keys)), None
|
|
657
|
+
)
|
|
658
|
+
clean_set, live_set = set(clean_ids), set(live_ids)
|
|
659
|
+
else:
|
|
660
|
+
clean_set, live_set = map(set, active)
|
|
661
|
+
clean_keys = [key for key in unique_keys if key[0] in clean_set]
|
|
662
|
+
live_keys = [key for key in unique_keys if key[0] in live_set]
|
|
663
|
+
durable: dict[str, object] = {"audits": {}, "latest_seq_ids": {}}
|
|
664
|
+
if clean_keys:
|
|
665
|
+
ok, value = await self._call_primary("get_checkpoint_stats", clean_keys)
|
|
666
|
+
if not ok:
|
|
667
|
+
raise CheckpointScanRestartRequired(
|
|
668
|
+
"primary failed while reading checkpoint stats"
|
|
669
|
+
)
|
|
670
|
+
durable = cast(dict[str, object], value or durable)
|
|
671
|
+
live = (
|
|
672
|
+
await self.fallback.get_checkpoint_stats(live_keys)
|
|
673
|
+
if live_keys
|
|
674
|
+
else {"audits": {}, "latest_seq_ids": {}}
|
|
675
|
+
)
|
|
676
|
+
return {
|
|
677
|
+
"audits": {
|
|
678
|
+
**cast(dict, durable["audits"]),
|
|
679
|
+
**cast(dict, live["audits"]),
|
|
680
|
+
},
|
|
681
|
+
"latest_seq_ids": {
|
|
682
|
+
**cast(dict, durable["latest_seq_ids"]),
|
|
683
|
+
**cast(dict, live["latest_seq_ids"]),
|
|
684
|
+
},
|
|
685
|
+
}
|
|
686
|
+
|
|
329
687
|
async def get_events_for_agent(
|
|
330
688
|
self,
|
|
331
689
|
agent_id: str,
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"""Resolve the non-secret Session and framework checkpoint storage topology."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from typing import Literal
|
|
8
|
+
|
|
9
|
+
StorageSource = Literal[
|
|
10
|
+
"none",
|
|
11
|
+
"explicit",
|
|
12
|
+
"session_fallback",
|
|
13
|
+
"checkpoint_fallback",
|
|
14
|
+
"framework_override",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass(frozen=True)
|
|
19
|
+
class StorageTarget:
|
|
20
|
+
"""A logical persistent-storage target without connection diagnostics."""
|
|
21
|
+
|
|
22
|
+
backend: str
|
|
23
|
+
dsn: str = ""
|
|
24
|
+
source: StorageSource = "none"
|
|
25
|
+
explicit_local: bool = False
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass(frozen=True)
|
|
29
|
+
class PersistenceTopology:
|
|
30
|
+
"""Effective Session and framework-native checkpoint storage targets."""
|
|
31
|
+
|
|
32
|
+
session: StorageTarget
|
|
33
|
+
checkpoint: StorageTarget
|
|
34
|
+
framework: str
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _first_configured(*names: str) -> str:
|
|
38
|
+
for name in names:
|
|
39
|
+
value = os.getenv(name, "").strip()
|
|
40
|
+
if value:
|
|
41
|
+
return value
|
|
42
|
+
return ""
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _session_backend(*, override: str | None = None) -> tuple[str, bool, bool]:
|
|
46
|
+
raw = (
|
|
47
|
+
override
|
|
48
|
+
if override is not None
|
|
49
|
+
else _first_configured(
|
|
50
|
+
"KSADK_SESSION_BACKEND",
|
|
51
|
+
"AGENTENGINE_SESSION_BACKEND",
|
|
52
|
+
"KSADK_STM_BACKEND",
|
|
53
|
+
)
|
|
54
|
+
)
|
|
55
|
+
normalized = raw.strip().lower()
|
|
56
|
+
if normalized == "sqlite":
|
|
57
|
+
normalized = "local"
|
|
58
|
+
return (
|
|
59
|
+
normalized or "local",
|
|
60
|
+
normalized in {"local", "memory"},
|
|
61
|
+
bool(normalized),
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _framework_checkpoint_dsn(framework: str) -> str:
|
|
66
|
+
if framework == "adk":
|
|
67
|
+
return _first_configured("KSADK_ADK_SESSION_URL")
|
|
68
|
+
if framework in {"langgraph", "langchain", "deepagents"}:
|
|
69
|
+
return _first_configured("KSADK_LANGGRAPH_CHECKPOINT_DSN")
|
|
70
|
+
return ""
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def resolve_persistence_topology(
|
|
74
|
+
*,
|
|
75
|
+
framework: str | None = None,
|
|
76
|
+
session_backend: str | None = None,
|
|
77
|
+
) -> PersistenceTopology:
|
|
78
|
+
"""Resolve dual persistence with documented Session/Checkpoint fallbacks.
|
|
79
|
+
|
|
80
|
+
``session_backend`` is an internal compatibility input for the legacy
|
|
81
|
+
session resolver. A caller explicitly selecting ``local``, ``sqlite`` or
|
|
82
|
+
``memory`` keeps that local choice even when a checkpoint DSN is present.
|
|
83
|
+
"""
|
|
84
|
+
normalized_framework = (framework or "").strip().lower()
|
|
85
|
+
backend, explicit_local, explicit_backend = _session_backend(override=session_backend)
|
|
86
|
+
session_dsn = _first_configured(
|
|
87
|
+
"KSADK_SESSION_DSN",
|
|
88
|
+
"KSADK_STM_URL",
|
|
89
|
+
"KSADK_STM_DB_URL",
|
|
90
|
+
)
|
|
91
|
+
checkpoint_dsn = _first_configured("KSADK_CHECKPOINT_DSN")
|
|
92
|
+
framework_dsn = _framework_checkpoint_dsn(normalized_framework)
|
|
93
|
+
|
|
94
|
+
if explicit_local:
|
|
95
|
+
session = StorageTarget(backend=backend, explicit_local=True)
|
|
96
|
+
elif session_dsn:
|
|
97
|
+
session = StorageTarget(
|
|
98
|
+
backend=backend if explicit_backend else "postgres",
|
|
99
|
+
dsn=session_dsn,
|
|
100
|
+
source="explicit",
|
|
101
|
+
)
|
|
102
|
+
elif checkpoint_dsn:
|
|
103
|
+
session = StorageTarget(
|
|
104
|
+
backend="postgres",
|
|
105
|
+
dsn=checkpoint_dsn,
|
|
106
|
+
source="checkpoint_fallback",
|
|
107
|
+
)
|
|
108
|
+
else:
|
|
109
|
+
session = StorageTarget(backend=backend)
|
|
110
|
+
|
|
111
|
+
if framework_dsn:
|
|
112
|
+
checkpoint = StorageTarget(
|
|
113
|
+
backend="postgres",
|
|
114
|
+
dsn=framework_dsn,
|
|
115
|
+
source="framework_override",
|
|
116
|
+
)
|
|
117
|
+
elif checkpoint_dsn:
|
|
118
|
+
checkpoint = StorageTarget(backend="postgres", dsn=checkpoint_dsn, source="explicit")
|
|
119
|
+
elif session.backend == "postgres" and session.dsn:
|
|
120
|
+
checkpoint = StorageTarget(
|
|
121
|
+
backend="postgres",
|
|
122
|
+
dsn=session.dsn,
|
|
123
|
+
source="session_fallback",
|
|
124
|
+
)
|
|
125
|
+
else:
|
|
126
|
+
checkpoint = StorageTarget(backend="none")
|
|
127
|
+
|
|
128
|
+
return PersistenceTopology(
|
|
129
|
+
session=session,
|
|
130
|
+
checkpoint=checkpoint,
|
|
131
|
+
framework=normalized_framework,
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
__all__ = ["PersistenceTopology", "StorageTarget", "resolve_persistence_topology"]
|
ksadk/skills/models.py
CHANGED
|
@@ -85,6 +85,10 @@ class SkillListResponse:
|
|
|
85
85
|
skills: list[SkillRef]
|
|
86
86
|
code: int = 0
|
|
87
87
|
message: str = ""
|
|
88
|
+
total_count: int | None = None
|
|
89
|
+
truncated: bool = False
|
|
90
|
+
next_page: int | None = None
|
|
91
|
+
pagination_warning: str = ""
|
|
88
92
|
|
|
89
93
|
@classmethod
|
|
90
94
|
def from_payload(
|
|
@@ -94,10 +98,24 @@ class SkillListResponse:
|
|
|
94
98
|
space_id: str = "",
|
|
95
99
|
space_name: str = "",
|
|
96
100
|
) -> "SkillListResponse":
|
|
97
|
-
data = payload.get("Data"
|
|
98
|
-
|
|
99
|
-
|
|
101
|
+
data = payload.get("Data", payload.get("data", {}))
|
|
102
|
+
if not isinstance(data, dict):
|
|
103
|
+
raise ValueError("Skill directory response must contain an object")
|
|
104
|
+
skills_payload = next(
|
|
105
|
+
(data[key] for key in ("Skills", "skills", "Items", "items") if key in data), []
|
|
100
106
|
)
|
|
107
|
+
if skills_payload is None:
|
|
108
|
+
skills_payload = []
|
|
109
|
+
if not isinstance(skills_payload, list) or any(
|
|
110
|
+
not isinstance(item, dict) for item in skills_payload
|
|
111
|
+
):
|
|
112
|
+
raise ValueError("Skill directory items must be objects")
|
|
113
|
+
total = data.get("TotalCount", data.get("total_count", payload.get("TotalCount")))
|
|
114
|
+
if total is not None:
|
|
115
|
+
if isinstance(total, str) and total.isdigit():
|
|
116
|
+
total = int(total)
|
|
117
|
+
if type(total) is not int or total < 0:
|
|
118
|
+
raise ValueError("Skill directory total count is invalid")
|
|
101
119
|
return cls(
|
|
102
120
|
code=int(payload.get("Code") or payload.get("code") or 0),
|
|
103
121
|
message=str(payload.get("Message") or payload.get("message") or ""),
|
|
@@ -109,9 +127,13 @@ class SkillListResponse:
|
|
|
109
127
|
skills=[
|
|
110
128
|
SkillRef.from_payload(item) for item in skills_payload if isinstance(item, dict)
|
|
111
129
|
],
|
|
130
|
+
total_count=total,
|
|
112
131
|
)
|
|
113
132
|
|
|
114
|
-
def active_skills(self) -> list[SkillRef]:
|
|
133
|
+
def active_skills(self, *, allow_partial: bool = False) -> list[SkillRef]:
|
|
134
|
+
"""Require callers consuming a partial directory to acknowledge it."""
|
|
135
|
+
if self.truncated and not allow_partial:
|
|
136
|
+
raise ValueError("Skill directory is incomplete; refresh or continue pagination")
|
|
115
137
|
return [skill for skill in self.skills if skill.is_active]
|
|
116
138
|
|
|
117
139
|
|