agentengine-sdk-python 0.8.3__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.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/METADATA +9 -8
- {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/RECORD +482 -245
- ksadk/_build_provenance.json +1 -1
- ksadk/api/client.py +105 -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 +1 -0
- ksadk/cli/__init__.py +32 -3
- ksadk/cli/cmd_managed_runtime.py +13 -1
- ksadk/cli/cmd_plugin.py +6 -1
- 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 +56 -298
- ksadk/common/auth.py +16 -10
- ksadk/configs/env_registry.py +29 -1
- ksadk/conversations/message_projection.py +135 -14
- ksadk/conversations/projector.py +4 -6
- 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/adapters/_codex_validators.py +18 -7
- ksadk/events/adapters/langgraph.py +15 -1
- ksadk/events/canonical_store.py +3 -1
- ksadk/events/projections.py +1 -1
- ksadk/harness/config.py +2 -2
- ksadk/harness/runtime.py +27 -27
- 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/ingress.py +15 -2
- ksadk/kernel/sqlite_store.py +27 -0
- ksadk/kernel/store.py +3 -0
- ksadk/kernel/worker.py +65 -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/model_proxy/server.py +10 -5
- ksadk/plugins/__init__.py +4 -0
- ksadk/plugins/artifacts.py +275 -0
- ksadk/plugins/bridges/__init__.py +4 -2
- ksadk/plugins/bridges/codex.py +120 -13
- ksadk/plugins/bridges/dsh.py +340 -156
- ksadk/plugins/builtins.py +35 -36
- ksadk/plugins/bundle_security.py +28 -4
- ksadk/plugins/codex_manifest.py +983 -0
- ksadk/plugins/composition.py +8 -0
- ksadk/plugins/contracts.py +118 -0
- ksadk/plugins/delivery.py +153 -0
- ksadk/plugins/dsh_installation_digest.py +71 -0
- ksadk/plugins/dsh_toolchain.py +110 -21
- ksadk/plugins/ecosystem_probe.py +6 -6
- ksadk/plugins/host.py +102 -39
- ksadk/plugins/kernel_adapter.py +205 -0
- ksadk/plugins/providers/__init__.py +23 -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-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/codex.py +335 -69
- ksadk/plugins/providers/codex_native.py +368 -0
- ksadk/plugins/providers/codex_turn.py +301 -0
- ksadk/plugins/providers/dsh_capabilities.py +1389 -0
- ksadk/plugins/providers/dsh_mcp.py +467 -0
- ksadk/plugins/providers/harness.py +118 -113
- ksadk/plugins/providers/mcp_projection.py +150 -0
- ksadk/plugins/providers/platform_resources.py +657 -0
- ksadk/plugins/resolver.py +8 -1
- 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 +142 -18
- ksadk/runtime/adapter.py +2 -0
- ksadk/runtime/conversation_execution.py +92 -16
- ksadk/runtime/executor.py +78 -2
- ksadk/runtime/factory.py +29 -273
- ksadk/runtime/framework_adapters.py +23 -0
- ksadk/runtime/preprocessing.py +10 -2
- ksadk/runtime/runner_adapter.py +73 -14
- ksadk/runtime_context.py +40 -2
- 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/scheduler/sqlite_store.py +18 -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-10GPXIJ6.js → ArtifactsPanel-CGbWlMNh.js} +1 -1
- ksadk/server/static/assets/{CodeBlock-BXk1l-G1.js → CodeBlock-b4C7upmO.js} +3 -3
- ksadk/server/static/assets/{MathMessageMarkdown-D9uB55Oh.js → MathMessageMarkdown-DbdW5A4_.js} +4 -4
- ksadk/server/static/assets/{MermaidBlock--OEYoXIJ.js → MermaidBlock-BEBN4Ksz.js} +6 -6
- ksadk/server/static/assets/{NativeTerminalPanel-DrEe1syq.js → NativeTerminalPanel-zvL-WpAn.js} +1 -1
- ksadk/server/static/assets/{abnfDiagram-VCTEODGH-eeTFJLvo.js → abnfDiagram-VCTEODGH-BYafW7Za.js} +1 -1
- ksadk/server/static/assets/{arc-S3ZNbIAd.js → arc-bTohInsS.js} +1 -1
- ksadk/server/static/assets/architecture-7GRP2DOG-BW5UtSnx.js +1 -0
- ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-CRjgEJDX.js → architectureDiagram-5GKGNRK7-Ch5Lbzsi.js} +1 -1
- ksadk/server/static/assets/{blockDiagram-NRAW4CY4-C7bsBoNH.js → blockDiagram-NRAW4CY4-kqF4MDOG.js} +1 -1
- ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-BX3c33Ob.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-bZ7ws-8m.js → chunk-5VM5RSS4-DkhehZDr.js} +1 -1
- ksadk/server/static/assets/{chunk-F27PBJKO-D2r0pvhY.js → chunk-F27PBJKO-BdXhtPe9.js} +1 -1
- ksadk/server/static/assets/{chunk-G27WJ6UU-CZwF3oUP.js → chunk-G27WJ6UU-DPTpvpwi.js} +1 -1
- ksadk/server/static/assets/{chunk-JWPE2WC7-DigFYCML.js → chunk-JWPE2WC7-Pqoh38el.js} +1 -1
- ksadk/server/static/assets/{chunk-LCL6LL3I-CnorGV5q.js → chunk-LCL6LL3I-DeU00qC-.js} +1 -1
- ksadk/server/static/assets/{chunk-POPQ4Y6H-CexntQA-.js → chunk-POPQ4Y6H-CzxScFkr.js} +1 -1
- ksadk/server/static/assets/{chunk-RHFEMEQ7-CHTC7UxA.js → chunk-RHFEMEQ7-DpqMx-ux.js} +1 -1
- ksadk/server/static/assets/{chunk-SVP7TREG-BC1EWt_-.js → chunk-SVP7TREG-C6t0SypQ.js} +1 -1
- ksadk/server/static/assets/{chunk-XXDRQBXY-BTG24xN0.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-CkonRdAS.js → cose-bilkent-JH36ORCC-Bf9D3tzJ.js} +1 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-DVWs8a2t.js +1 -0
- ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-DEOCBe15.js → cynefinDiagram-5FMLGOSQ-B9cY3iTz.js} +1 -1
- ksadk/server/static/assets/{dagre-3AP2YEHR-DBThPuLa.js → dagre-3AP2YEHR-CSwlx3CB.js} +1 -1
- ksadk/server/static/assets/{dagre-ClTPrTht.js → dagre-UBpgon5q.js} +1 -1
- ksadk/server/static/assets/{diagram-S7CK7UJ4-DsZHrnpJ.js → diagram-S7CK7UJ4-C9akhN9a.js} +1 -1
- ksadk/server/static/assets/{diagram-UQ7AKVKN-BJR4nhVr.js → diagram-UQ7AKVKN-CgedhTPI.js} +1 -1
- ksadk/server/static/assets/{diagram-VSXAHHWV-xzcERX0a.js → diagram-VSXAHHWV-Cjucz5BY.js} +1 -1
- ksadk/server/static/assets/{diagram-VX7I27RA-tn2xM1xu.js → diagram-VX7I27RA-Dd4Vleyn.js} +1 -1
- ksadk/server/static/assets/{diagram-Z3DM3KII-BZPGBkw5.js → diagram-Z3DM3KII-CZ2jGtYW.js} +1 -1
- ksadk/server/static/assets/{dist-DdRBIceA.js → dist-B2_CVgKv.js} +1 -1
- ksadk/server/static/assets/{dist-Cq4OL6nO.js → dist-B3FR1SKK.js} +1 -1
- ksadk/server/static/assets/{dist-M67Hwu0n.js → dist-BIr4DSRq.js} +1 -1
- ksadk/server/static/assets/{dist-B1oWRmrH.js → dist-BgV_owcB.js} +1 -1
- ksadk/server/static/assets/{dist-DyqV4fL4.js → dist-Bj730Ib4.js} +1 -1
- ksadk/server/static/assets/{dist-DfGFrb0v.js → dist-BnaTiyzN.js} +1 -1
- ksadk/server/static/assets/{dist-C71CsujO.js → dist-C1NMAY5a.js} +1 -1
- ksadk/server/static/assets/{dist-CXpH_Rdd.js → dist-C5_ZAZsG.js} +1 -1
- ksadk/server/static/assets/{dist-DJmCPRVB.js → dist-CB9iJrvg.js} +1 -1
- ksadk/server/static/assets/{dist-DjhwGUgZ.js → dist-CFzsn6BG.js} +1 -1
- ksadk/server/static/assets/{dist-BI1qQH4n.js → dist-Cf125P_m.js} +1 -1
- ksadk/server/static/assets/{dist-8VWI-2bZ.js → dist-ClYUxfeK.js} +1 -1
- ksadk/server/static/assets/{dist-DUwKa_l6.js → dist-DFD6Qa6T.js} +1 -1
- ksadk/server/static/assets/{dist-B-46q3Hk.js → dist-DVCOWtha.js} +1 -1
- ksadk/server/static/assets/{dist-BJLUwH6W.js → dist-D_ctSS2i.js} +1 -1
- ksadk/server/static/assets/{dist-4zN1_tq5.js → dist-DiixqL0J.js} +1 -1
- ksadk/server/static/assets/{dist-B0gdk4rl.js → dist-DoVSwoDb.js} +1 -1
- ksadk/server/static/assets/{dist-Bbwqa8TG.js → dist-DvFK7p5S.js} +1 -1
- ksadk/server/static/assets/{dist-D1V3f1B4.js → dist-QfkEHOlb.js} +1 -1
- ksadk/server/static/assets/{dist-Btyo4vX4.js → dist-btbmmX5O.js} +1 -1
- ksadk/server/static/assets/{dist-u8tVH5Ak.js → dist-fBO2v5Kt.js} +1 -1
- ksadk/server/static/assets/{dist-DQAB0qn_.js → dist-ufY3F5p6.js} +1 -1
- ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-DVfMsLge.js → ebnfDiagram-PWID7BFC-Ci8NqqZu.js} +1 -1
- ksadk/server/static/assets/{erDiagram-SSCWMZ5O-CWEZSYaw.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-TWIxoyYL.js → ganttDiagram-EL5Y4UJY-Cp_r9Hb6.js} +1 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-fgWEf7UD.js +1 -0
- ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-DDh2hd2S.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-CgoyWiDR.js → infoDiagram-RXCK75RN-CO0rRTRA.js} +1 -1
- ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-CyRIu_om.js → ishikawaDiagram-5VMMS53U-CHiaedSS.js} +1 -1
- ksadk/server/static/assets/{journeyDiagram-EYS64GPL-DN5JXHzN.js → journeyDiagram-EYS64GPL-CHcCIB09.js} +1 -1
- ksadk/server/static/assets/{kanban-definition-3QL26DDD-CNP3ui66.js → kanban-definition-3QL26DDD-CJ_ebBZf.js} +1 -1
- ksadk/server/static/assets/{katex-DWEzQy1d.js → katex-B4weu383.js} +1 -1
- ksadk/server/static/assets/{linear-C-qHp7d2.js → linear-V-MgYHW1.js} +1 -1
- ksadk/server/static/assets/{mermaid-parser.core-Cl-K943T.js → mermaid-parser.core-CBijEX_c.js} +2 -2
- ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-D5DB5mYm.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-BQVc9ia_.js → pegDiagram-XKGWAZYB-D7genGLl.js} +1 -1
- ksadk/server/static/assets/pie-WAS4IAKB-X0xh4SaT.js +1 -0
- ksadk/server/static/assets/{pieDiagram-E7YTZNPT-B6UCAvtY.js → pieDiagram-E7YTZNPT-Bxj32zwD.js} +1 -1
- ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-mIr2d3eb.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-Dt3FFDmK.js → railroadDiagram-O6MQD6OU-CCsh3avW.js} +1 -1
- ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-Cz_vQtgF.js → requirementDiagram-EFPCY7ZU-_FRRBKEd.js} +1 -1
- ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-wlO1TsH5.js → sankeyDiagram-P5KCCOFB-C-gr2o9M.js} +1 -1
- ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-CHRbElYq.js → sequenceDiagram-WJ2MYXX4-D97NmfKg.js} +1 -1
- ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-DXX54iyO.js → sizeCapture-X5ZJPWSS-DjrPC5FX.js} +1 -1
- ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-Dp_lw9II.js → stateDiagram-HBIQ2CUA-DzMNg1hh.js} +1 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BIcjKFhF.js +1 -0
- ksadk/server/static/assets/{swimlanes-XN3QIQJK-D8O5UlLG.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-8mfKcxvG.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-EnNl0DE7.js → vennDiagram-4TSXK5OY-BSKgJsmR.js} +1 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-CefhOliM.js +1 -0
- ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-DBu5fbYr.js → wardleyDiagram-VM6X3IG4-eflHNoaZ.js} +1 -1
- ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-BSVXs4IY.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 +167 -28
- ksadk/studio/api.py +224 -42
- ksadk/studio/api_catalog_routes.py +18 -0
- ksadk/studio/api_plugin_routes.py +526 -95
- ksadk/studio/api_resource_connections.py +183 -0
- ksadk/studio/authoring_coordinator.py +19 -14
- ksadk/studio/builder.py +76 -0
- ksadk/studio/cloud.py +342 -104
- ksadk/studio/cloud_shared_web.py +565 -0
- ksadk/studio/codex_agent_service.py +128 -26
- ksadk/studio/codex_builder.py +241 -2
- ksadk/studio/codex_credentials.py +90 -0
- ksadk/studio/codex_manifest.py +31 -4
- ksadk/studio/codex_plugin_store.py +746 -0
- ksadk/studio/codex_provider_build.py +231 -0
- ksadk/studio/codex_run.py +184 -25
- ksadk/studio/compatibility_report.py +12 -1
- ksadk/studio/compiler.py +78 -14
- ksadk/studio/contracts.py +132 -6
- 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 +320 -13
- ksadk/studio/hosted_kernel.py +88 -13
- ksadk/studio/mcp_runtime.py +11 -3
- ksadk/studio/model_client.py +2 -2
- ksadk/studio/plugin_composition.py +190 -23
- ksadk/studio/plugin_kernel_adapter.py +12 -112
- ksadk/studio/plugin_runtime.py +224 -45
- 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 +143 -2
- ksadk/studio/resource_connections.py +220 -0
- ksadk/studio/run_service.py +462 -52
- ksadk/studio/runtime_source.py +15 -7
- ksadk/studio/scheduler_assistant.py +317 -0
- ksadk/studio/scheduler_runtime.py +9 -0
- ksadk/studio/scheduler_service.py +3 -0
- ksadk/studio/service.py +490 -44
- ksadk/studio/shared_web.py +446 -62
- 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/version.py +1 -1
- ksadk/server/static/assets/architecture-7GRP2DOG-Dk9nRQ6-.js +0 -1
- ksadk/server/static/assets/channel-s354Yo6o.js +0 -1
- ksadk/server/static/assets/chunk-2Q5K7J3B-CDpPpKR5.js +0 -1
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-Dd0nucl9.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Dd0nucl9.js +0 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-BBlT4uMf.js +0 -1
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-Dr5okd8V.js +0 -1
- ksadk/server/static/assets/flowDiagram-A5DVABFB-VEO-cVcO.js +0 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-CKiKY9Cf.js +0 -1
- ksadk/server/static/assets/index-B2k_urY8.js +0 -241
- ksadk/server/static/assets/index-ILPt6IWF.css +0 -2
- ksadk/server/static/assets/info-A6RAGUB7-ubA4Nm_p.js +0 -1
- ksadk/server/static/assets/packet-AYTQ26CC-C7R3NUlK.js +0 -1
- ksadk/server/static/assets/pie-WAS4IAKB-BIT6qjr3.js +0 -1
- ksadk/server/static/assets/radar-RG4KPBEZ-l5noef9X.js +0 -1
- ksadk/server/static/assets/railroad-74A4TZTK-Baea6ZvM.js +0 -1
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-OKn8zZnU.js +0 -1
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-DdKAKC4l.js +0 -1
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-Bds8udlG.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-5b-8o2iS.js +0 -1
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uf6WPRA4.js +0 -8
- ksadk/server/static/assets/treeView-Q6P3EWNA-CK5CSrSO.js +0 -1
- ksadk/server/static/assets/treemap-WGGIJYW6-Ch2BKgAM.js +0 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-YW3Q0ml_.js +0 -1
- ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +0 -3
- ksadk/studio/static/assets/index-DXs1Eq4M.css +0 -1
- ksadk/studio/static/assets/index-DeDqwTsD.js +0 -283
- {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/WHEEL +0 -0
- {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/top_level.txt +0 -0
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
|
-
import
|
|
6
|
+
import base64
|
|
7
7
|
import os
|
|
8
|
+
import re
|
|
8
9
|
from pathlib import Path
|
|
9
10
|
from typing import Any, Callable
|
|
10
|
-
from urllib.parse import
|
|
11
|
+
from urllib.parse import urlparse
|
|
11
12
|
from uuid import uuid4
|
|
12
13
|
|
|
13
14
|
from fastapi import FastAPI, Query, Response
|
|
@@ -29,8 +30,21 @@ from ksadk.plugins.bridges.dsh import (
|
|
|
29
30
|
DshPluginMutationError,
|
|
30
31
|
DshPluginNotFoundError,
|
|
31
32
|
DshProfilePluginBridge,
|
|
33
|
+
DshProfileRecoveryError,
|
|
34
|
+
validate_dsh_registry_request,
|
|
35
|
+
)
|
|
36
|
+
from ksadk.plugins.codex_manifest import (
|
|
37
|
+
CodexInstalledPluginSnapshot,
|
|
38
|
+
CodexPluginSourceCoordinate,
|
|
39
|
+
snapshot_installed_codex_plugin,
|
|
32
40
|
)
|
|
33
41
|
from ksadk.plugins.dsh_toolchain import DshToolchainError, DshToolchainManager
|
|
42
|
+
from ksadk.plugins.host import PluginHostError
|
|
43
|
+
from ksadk.studio.codex_plugin_store import (
|
|
44
|
+
CodexWorkspacePluginSnapshot,
|
|
45
|
+
component_selector,
|
|
46
|
+
find_installed_codex_plugin_root,
|
|
47
|
+
)
|
|
34
48
|
from ksadk.studio.errors import StudioError
|
|
35
49
|
from ksadk.studio.service import StudioService
|
|
36
50
|
|
|
@@ -43,6 +57,13 @@ class CodexPluginInstallRequest(BaseModel):
|
|
|
43
57
|
accept_undeclared_permissions: bool = Field(default=False, alias="acceptUndeclaredPermissions")
|
|
44
58
|
|
|
45
59
|
|
|
60
|
+
class CodexPluginSnapshotRequest(BaseModel):
|
|
61
|
+
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
62
|
+
marketplace_name: str | None = Field(
|
|
63
|
+
default=None, alias="marketplaceName", min_length=1, max_length=256
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
46
67
|
class DshPluginInstallRequest(BaseModel):
|
|
47
68
|
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
48
69
|
source: str = Field(min_length=1, max_length=2048)
|
|
@@ -53,8 +74,16 @@ class DshPluginInstallRequest(BaseModel):
|
|
|
53
74
|
def validate_source(cls, value: str) -> str:
|
|
54
75
|
normalized = value.strip()
|
|
55
76
|
if not normalized or any(character in value for character in ("\x00", "\r", "\n")):
|
|
56
|
-
raise ValueError("source must be one
|
|
57
|
-
|
|
77
|
+
raise ValueError("source must be one exact registry package")
|
|
78
|
+
# The authenticated Studio API is a production-facing package install
|
|
79
|
+
# boundary. Local paths remain available to the CLI/developer bridge,
|
|
80
|
+
# where they are packed into the immutable store; exposing arbitrary
|
|
81
|
+
# host paths to a browser request would turn the API into a file reader.
|
|
82
|
+
if Path(normalized).expanduser().is_absolute():
|
|
83
|
+
raise ValueError(
|
|
84
|
+
"Studio only accepts registry packages; use the local CLI for development"
|
|
85
|
+
)
|
|
86
|
+
return validate_dsh_registry_request(normalized)
|
|
58
87
|
|
|
59
88
|
|
|
60
89
|
class DshPluginUpdateRequest(BaseModel):
|
|
@@ -86,7 +115,7 @@ def _studio_dsh_options(studio: StudioService) -> tuple[Path, str, tuple[str, ..
|
|
|
86
115
|
# Keep the bridge's established PATH lookup when the optional
|
|
87
116
|
# pinned toolchain has not been installed or is unusable.
|
|
88
117
|
command = None
|
|
89
|
-
profile = os.environ.get("KSADK_DSH_PROFILE", "").strip() or "
|
|
118
|
+
profile = os.environ.get("KSADK_DSH_PROFILE", "").strip() or "web"
|
|
90
119
|
return home, profile, command, "explicit" if configured_home else "workspace-isolated"
|
|
91
120
|
|
|
92
121
|
|
|
@@ -123,13 +152,20 @@ def _public_codex_source(source: BaseModel) -> dict[str, Any]:
|
|
|
123
152
|
def _public_codex_inventory(
|
|
124
153
|
inventory: CodexPluginInventory, *, host: CodexBridgeHost, home_mode: str
|
|
125
154
|
) -> dict[str, Any]:
|
|
155
|
+
presentation = _public_plugin_interface(inventory.interface)
|
|
156
|
+
if not presentation.get("logoUrl"):
|
|
157
|
+
artwork = _local_plugin_artwork(inventory)
|
|
158
|
+
if artwork:
|
|
159
|
+
presentation["logoUrl"] = artwork
|
|
126
160
|
return {
|
|
127
161
|
"ecosystem": "codex",
|
|
128
162
|
"integrationMode": "bridged",
|
|
129
163
|
"pluginId": inventory.plugin_id,
|
|
130
164
|
"resolvedVersion": inventory.version,
|
|
131
165
|
"distributionName": inventory.name,
|
|
132
|
-
"displayName": inventory.name,
|
|
166
|
+
"displayName": inventory.interface.get("displayName") or inventory.name,
|
|
167
|
+
"description": inventory.interface.get("shortDescription"),
|
|
168
|
+
"interface": presentation,
|
|
133
169
|
"marketplaceName": inventory.marketplace_name,
|
|
134
170
|
"source": _public_codex_source(inventory.source),
|
|
135
171
|
"installed": inventory.installed,
|
|
@@ -145,10 +181,81 @@ def _public_codex_inventory(
|
|
|
145
181
|
}
|
|
146
182
|
|
|
147
183
|
|
|
184
|
+
def _local_plugin_artwork(inventory: CodexPluginInventory) -> str | None:
|
|
185
|
+
"""Read only bounded image assets inside the host-reported local plugin.
|
|
186
|
+
|
|
187
|
+
Never expose host paths, accept browser-supplied filenames, or fetch URLs.
|
|
188
|
+
SVGs remain image data (not executable same-origin HTML documents).
|
|
189
|
+
"""
|
|
190
|
+
if inventory.source.type != "local":
|
|
191
|
+
return None
|
|
192
|
+
root = Path(inventory.source.path)
|
|
193
|
+
if not root.is_absolute():
|
|
194
|
+
if not inventory.marketplace_path:
|
|
195
|
+
return None
|
|
196
|
+
root = Path(inventory.marketplace_path) / root
|
|
197
|
+
root = root.resolve()
|
|
198
|
+
if not (root / ".codex-plugin" / "plugin.json").is_file():
|
|
199
|
+
return None
|
|
200
|
+
for key in ("logo", "composerIcon"):
|
|
201
|
+
raw = inventory.interface.get(key)
|
|
202
|
+
if not isinstance(raw, str):
|
|
203
|
+
continue
|
|
204
|
+
path = Path(raw)
|
|
205
|
+
path = (path if path.is_absolute() else root / path).resolve()
|
|
206
|
+
if not path.is_relative_to(root):
|
|
207
|
+
continue
|
|
208
|
+
try:
|
|
209
|
+
with path.open("rb") as stream:
|
|
210
|
+
data = stream.read(256 * 1024 + 1)
|
|
211
|
+
except OSError:
|
|
212
|
+
continue
|
|
213
|
+
if len(data) > 256 * 1024:
|
|
214
|
+
continue
|
|
215
|
+
mime = None
|
|
216
|
+
if data.startswith(b"\x89PNG\r\n\x1a\n"):
|
|
217
|
+
mime = "image/png"
|
|
218
|
+
elif data.startswith(b"\xff\xd8\xff"):
|
|
219
|
+
mime = "image/jpeg"
|
|
220
|
+
elif data.startswith((b"GIF87a", b"GIF89a")):
|
|
221
|
+
mime = "image/gif"
|
|
222
|
+
elif data.startswith(b"RIFF") and data[8:12] == b"WEBP":
|
|
223
|
+
mime = "image/webp"
|
|
224
|
+
elif path.suffix.lower() == ".svg" and b"<svg" in data[:1024]:
|
|
225
|
+
mime = "image/svg+xml"
|
|
226
|
+
if mime:
|
|
227
|
+
return f"data:{mime};base64,{base64.b64encode(data).decode('ascii')}"
|
|
228
|
+
return None
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def _public_plugin_interface(value: dict[str, Any]) -> dict[str, Any]:
|
|
232
|
+
"""Project marketplace display data, never filesystem paths or host state."""
|
|
233
|
+
result = {
|
|
234
|
+
key: value[key] for key in (
|
|
235
|
+
"displayName", "shortDescription", "longDescription", "developerName", "category",
|
|
236
|
+
) if isinstance(value.get(key), str)
|
|
237
|
+
}
|
|
238
|
+
for key in ("defaultPrompt", "capabilities"):
|
|
239
|
+
if isinstance(value.get(key), list):
|
|
240
|
+
result[key] = [item for item in value[key] if isinstance(item, str)]
|
|
241
|
+
for key in (
|
|
242
|
+
"logoUrl", "logoUrlDark", "composerIconUrl", "websiteUrl",
|
|
243
|
+
"privacyPolicyUrl", "termsOfServiceUrl",
|
|
244
|
+
):
|
|
245
|
+
raw = value.get(key)
|
|
246
|
+
if isinstance(raw, str) and urlparse(raw).scheme == "https" and not urlparse(raw).username:
|
|
247
|
+
result[key] = raw
|
|
248
|
+
return result
|
|
249
|
+
|
|
250
|
+
|
|
148
251
|
def _public_codex_detail(
|
|
149
|
-
detail: CodexPluginDetail,
|
|
252
|
+
detail: CodexPluginDetail,
|
|
253
|
+
*,
|
|
254
|
+
host: CodexBridgeHost,
|
|
255
|
+
home_mode: str,
|
|
256
|
+
snapshot: CodexWorkspacePluginSnapshot | None = None,
|
|
150
257
|
) -> dict[str, Any]:
|
|
151
|
-
|
|
258
|
+
payload = {
|
|
152
259
|
"item": _public_codex_inventory(detail.inventory, host=host, home_mode=home_mode),
|
|
153
260
|
"description": detail.description,
|
|
154
261
|
"capabilities": {
|
|
@@ -158,6 +265,189 @@ def _public_codex_detail(
|
|
|
158
265
|
"apps": list(detail.apps),
|
|
159
266
|
"scheduledTasks": list(detail.scheduled_tasks),
|
|
160
267
|
},
|
|
268
|
+
"snapshot": None,
|
|
269
|
+
"snapshotRequired": detail.inventory.installed,
|
|
270
|
+
}
|
|
271
|
+
if snapshot is not None:
|
|
272
|
+
projection = _public_codex_snapshot(snapshot)
|
|
273
|
+
payload["snapshot"] = projection
|
|
274
|
+
payload["snapshotRequired"] = False
|
|
275
|
+
payload["item"].update(
|
|
276
|
+
snapshotDigest=projection["snapshotDigest"],
|
|
277
|
+
pluginRef=projection["pluginRef"],
|
|
278
|
+
components=projection["components"],
|
|
279
|
+
)
|
|
280
|
+
return payload
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
_EXACT_SEMVER = re.compile(
|
|
284
|
+
r"^(0|[1-9]\d*)\."
|
|
285
|
+
r"(0|[1-9]\d*)\."
|
|
286
|
+
r"(0|[1-9]\d*)"
|
|
287
|
+
r"(?:-(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\."
|
|
288
|
+
r"(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*)?"
|
|
289
|
+
r"(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$"
|
|
290
|
+
)
|
|
291
|
+
_FULL_GIT_COMMIT = re.compile(r"^(?:[0-9a-fA-F]{40}|[0-9a-fA-F]{64})$")
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def _require_exact_codex_version(inventory: CodexPluginInventory) -> str:
|
|
295
|
+
version = str(inventory.version or "")
|
|
296
|
+
if _EXACT_SEMVER.fullmatch(version) is None:
|
|
297
|
+
raise StudioError(
|
|
298
|
+
"CODEX_PLUGIN_SOURCE_NOT_IMMUTABLE",
|
|
299
|
+
"Codex 插件缺少可锁定的精确语义版本",
|
|
300
|
+
status_code=422,
|
|
301
|
+
details={
|
|
302
|
+
"pluginId": inventory.plugin_id,
|
|
303
|
+
"sourceType": inventory.source.type,
|
|
304
|
+
"version": inventory.version,
|
|
305
|
+
},
|
|
306
|
+
)
|
|
307
|
+
return version
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def _codex_source_coordinate(inventory: CodexPluginInventory) -> CodexPluginSourceCoordinate:
|
|
311
|
+
raw = inventory.source.model_dump(by_alias=True, exclude_none=True, mode="json")
|
|
312
|
+
source_type = str(raw.get("type") or "remote")
|
|
313
|
+
marketplace = inventory.marketplace_name
|
|
314
|
+
version = _require_exact_codex_version(inventory)
|
|
315
|
+
integrity: str | None = None
|
|
316
|
+
if source_type == "local":
|
|
317
|
+
requested = str(raw.get("path") or inventory.name)
|
|
318
|
+
resolved = f"codex-marketplace://{marketplace}/{inventory.name}@{version}"
|
|
319
|
+
elif source_type == "git":
|
|
320
|
+
requested = str(raw.get("url") or inventory.name)
|
|
321
|
+
revision = str(raw.get("sha") or "")
|
|
322
|
+
if _FULL_GIT_COMMIT.fullmatch(revision) is None:
|
|
323
|
+
raise StudioError(
|
|
324
|
+
"CODEX_PLUGIN_SOURCE_NOT_IMMUTABLE",
|
|
325
|
+
"Git Codex 插件必须由宿主解析为完整 commit SHA 后才能提交快照",
|
|
326
|
+
status_code=422,
|
|
327
|
+
details={
|
|
328
|
+
"pluginId": inventory.plugin_id,
|
|
329
|
+
"refName": raw.get("refName"),
|
|
330
|
+
"sha": raw.get("sha"),
|
|
331
|
+
},
|
|
332
|
+
)
|
|
333
|
+
resolved = f"{requested.rstrip('/')}@{revision.lower()}"
|
|
334
|
+
elif source_type == "npm":
|
|
335
|
+
package = str(raw.get("package") or inventory.name)
|
|
336
|
+
source_version = str(raw.get("version") or "")
|
|
337
|
+
if _EXACT_SEMVER.fullmatch(source_version) is None or source_version != version:
|
|
338
|
+
raise StudioError(
|
|
339
|
+
"CODEX_PLUGIN_SOURCE_NOT_IMMUTABLE",
|
|
340
|
+
"npm Codex 插件必须由宿主解析为一致的精确版本后才能提交快照",
|
|
341
|
+
status_code=422,
|
|
342
|
+
details={
|
|
343
|
+
"pluginId": inventory.plugin_id,
|
|
344
|
+
"requestedVersion": raw.get("version"),
|
|
345
|
+
"resolvedVersion": inventory.version,
|
|
346
|
+
},
|
|
347
|
+
)
|
|
348
|
+
requested = f"{package}@{source_version}"
|
|
349
|
+
resolved = requested
|
|
350
|
+
raw_integrity = raw.get("integrity")
|
|
351
|
+
integrity = str(raw_integrity) if raw_integrity else None
|
|
352
|
+
else:
|
|
353
|
+
requested = inventory.plugin_id
|
|
354
|
+
resolved = f"codex-marketplace://{marketplace}/{inventory.name}@{version}"
|
|
355
|
+
return CodexPluginSourceCoordinate(
|
|
356
|
+
type=source_type,
|
|
357
|
+
requested=requested,
|
|
358
|
+
resolved=resolved,
|
|
359
|
+
marketplace_name=marketplace,
|
|
360
|
+
registry=raw.get("registry"),
|
|
361
|
+
integrity=integrity,
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
def _observe_codex_snapshot(
|
|
366
|
+
codex_home: Path,
|
|
367
|
+
inventory: CodexPluginInventory,
|
|
368
|
+
) -> CodexInstalledPluginSnapshot:
|
|
369
|
+
if not inventory.installed:
|
|
370
|
+
raise StudioError(
|
|
371
|
+
"CODEX_PLUGIN_NOT_INSTALLED",
|
|
372
|
+
"Codex 插件尚未安装,无法提交不可变快照",
|
|
373
|
+
status_code=409,
|
|
374
|
+
details={"pluginId": inventory.plugin_id},
|
|
375
|
+
)
|
|
376
|
+
installed_root = find_installed_codex_plugin_root(
|
|
377
|
+
codex_home,
|
|
378
|
+
marketplace_name=inventory.marketplace_name,
|
|
379
|
+
plugin_name=inventory.name,
|
|
380
|
+
version=inventory.version,
|
|
381
|
+
)
|
|
382
|
+
observed = snapshot_installed_codex_plugin(
|
|
383
|
+
installed_root,
|
|
384
|
+
source=_codex_source_coordinate(inventory),
|
|
385
|
+
)
|
|
386
|
+
if observed.manifest.version != inventory.version:
|
|
387
|
+
raise StudioError(
|
|
388
|
+
"CODEX_PLUGIN_VERSION_MISMATCH",
|
|
389
|
+
"Codex 宿主清单版本与已安装插件清单不一致",
|
|
390
|
+
status_code=409,
|
|
391
|
+
details={
|
|
392
|
+
"pluginId": inventory.plugin_id,
|
|
393
|
+
"hostVersion": inventory.version,
|
|
394
|
+
"manifestVersion": observed.manifest.version,
|
|
395
|
+
},
|
|
396
|
+
)
|
|
397
|
+
return observed
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
def _lookup_codex_snapshot(
|
|
401
|
+
studio: StudioService,
|
|
402
|
+
codex_home: Path,
|
|
403
|
+
inventory: CodexPluginInventory,
|
|
404
|
+
) -> CodexWorkspacePluginSnapshot | None:
|
|
405
|
+
if not inventory.installed:
|
|
406
|
+
return None
|
|
407
|
+
try:
|
|
408
|
+
observed = _observe_codex_snapshot(codex_home, inventory)
|
|
409
|
+
except (StudioError, OSError, ValueError):
|
|
410
|
+
# GET is an inventory operation. Invalid/unpinned host bytes remain
|
|
411
|
+
# visible but require the explicit admission POST, which reports the
|
|
412
|
+
# actionable validation failure.
|
|
413
|
+
return None
|
|
414
|
+
return studio.codex_plugin_snapshots.lookup(observed)
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
def _commit_codex_snapshot(
|
|
418
|
+
studio: StudioService,
|
|
419
|
+
codex_home: Path,
|
|
420
|
+
inventory: CodexPluginInventory,
|
|
421
|
+
) -> CodexWorkspacePluginSnapshot:
|
|
422
|
+
return studio.codex_plugin_snapshots.commit(_observe_codex_snapshot(codex_home, inventory))
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
def _snapshot_failure_details(error: Exception) -> dict[str, Any]:
|
|
426
|
+
if isinstance(error, StudioError):
|
|
427
|
+
return {
|
|
428
|
+
"code": error.code,
|
|
429
|
+
"message": error.message,
|
|
430
|
+
"details": error.details,
|
|
431
|
+
}
|
|
432
|
+
return {"code": type(error).__name__, "message": str(error)}
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
def _public_codex_snapshot(snapshot: CodexWorkspacePluginSnapshot) -> dict[str, Any]:
|
|
436
|
+
return {
|
|
437
|
+
"snapshotDigest": snapshot.snapshot_digest,
|
|
438
|
+
"pluginRef": snapshot.plugin_ref,
|
|
439
|
+
"artifactDigest": snapshot.artifact_digest,
|
|
440
|
+
"manifestDigest": snapshot.manifest_digest,
|
|
441
|
+
"components": [
|
|
442
|
+
{
|
|
443
|
+
"id": component_selector(component),
|
|
444
|
+
"kind": component.kind,
|
|
445
|
+
"name": component.name,
|
|
446
|
+
"path": component.path,
|
|
447
|
+
"digest": component.content_digest,
|
|
448
|
+
}
|
|
449
|
+
for component in snapshot.components
|
|
450
|
+
],
|
|
161
451
|
}
|
|
162
452
|
|
|
163
453
|
|
|
@@ -168,7 +458,20 @@ def _public_dsh_inventory(
|
|
|
168
458
|
home_mode: str,
|
|
169
459
|
runtime_state: dict[str, Any] | None = None,
|
|
170
460
|
) -> dict[str, Any]:
|
|
171
|
-
|
|
461
|
+
if inventory.source_digest is not None:
|
|
462
|
+
source = {
|
|
463
|
+
"type": "local-immutable",
|
|
464
|
+
"name": inventory.name,
|
|
465
|
+
"kind": inventory.source_kind,
|
|
466
|
+
"integrity": inventory.source_digest,
|
|
467
|
+
}
|
|
468
|
+
else:
|
|
469
|
+
source = {
|
|
470
|
+
"type": "registry",
|
|
471
|
+
"package": inventory.name,
|
|
472
|
+
"requested": inventory.requested_spec,
|
|
473
|
+
"resolvedVersion": inventory.version,
|
|
474
|
+
}
|
|
172
475
|
return {
|
|
173
476
|
"ecosystem": "dsh",
|
|
174
477
|
"integrationMode": "bridged",
|
|
@@ -177,8 +480,10 @@ def _public_dsh_inventory(
|
|
|
177
480
|
"distributionName": inventory.name,
|
|
178
481
|
"displayName": inventory.display_name,
|
|
179
482
|
"description": inventory.description,
|
|
483
|
+
"clientExtension": inventory.client_extension,
|
|
484
|
+
"settingsIntegration": inventory.settings_integration,
|
|
180
485
|
"profile": inventory.profile,
|
|
181
|
-
"source":
|
|
486
|
+
"source": source,
|
|
182
487
|
"installed": True,
|
|
183
488
|
"state": "enabled" if inventory.enabled else "disabled",
|
|
184
489
|
"enabled": inventory.enabled,
|
|
@@ -187,42 +492,13 @@ def _public_dsh_inventory(
|
|
|
187
492
|
"riskDisclosures": list(inventory.risk_disclosures),
|
|
188
493
|
"isolation": "host-managed",
|
|
189
494
|
"runtimeState": runtime_state,
|
|
190
|
-
"clientBundle": (
|
|
191
|
-
{
|
|
192
|
-
"platform": client.platform,
|
|
193
|
-
"digest": client.digest,
|
|
194
|
-
"contentBytes": client.content_bytes,
|
|
195
|
-
"external": list(client.external),
|
|
196
|
-
"inject": list(client.inject),
|
|
197
|
-
"compatible": client.compatible,
|
|
198
|
-
"incompatibilityReason": client.incompatibility_reason or None,
|
|
199
|
-
}
|
|
200
|
-
if client is not None
|
|
201
|
-
else None
|
|
202
|
-
),
|
|
203
495
|
"host": _public_host("dsh", host, home_mode=home_mode),
|
|
204
496
|
}
|
|
205
497
|
|
|
206
498
|
|
|
207
|
-
def _public_dsh_client_bundle(inventory: DshPluginInventory) -> dict[str, Any] | None:
|
|
208
|
-
client = inventory.client_bundle
|
|
209
|
-
if client is None:
|
|
210
|
-
return None
|
|
211
|
-
query = urlencode({"pluginName": inventory.name, "digest": client.digest})
|
|
212
|
-
return {
|
|
213
|
-
"pluginId": inventory.name,
|
|
214
|
-
"enabled": inventory.enabled,
|
|
215
|
-
"compatible": client.compatible,
|
|
216
|
-
"digest": client.digest,
|
|
217
|
-
"contentBytes": client.content_bytes,
|
|
218
|
-
"external": list(client.external),
|
|
219
|
-
"inject": list(client.inject),
|
|
220
|
-
"incompatibilityReason": client.incompatibility_reason or None,
|
|
221
|
-
"url": f"/api/v1/plugin-ecosystems/dsh/client-bundle?{query}",
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
|
|
225
499
|
def _codex_error(error: Exception) -> StudioError:
|
|
500
|
+
if isinstance(error, StudioError):
|
|
501
|
+
return error
|
|
226
502
|
if isinstance(error, CodexPluginNotFoundError):
|
|
227
503
|
return StudioError(
|
|
228
504
|
"CODEX_PLUGIN_NOT_FOUND", "Codex 插件不存在或来源不唯一", status_code=404
|
|
@@ -245,6 +521,12 @@ def _dsh_error(error: Exception) -> StudioError:
|
|
|
245
521
|
"安装或升级 DSH 插件前必须确认宿主权限风险",
|
|
246
522
|
status_code=422,
|
|
247
523
|
)
|
|
524
|
+
if isinstance(error, DshProfileRecoveryError):
|
|
525
|
+
return StudioError(
|
|
526
|
+
"DSH_PROFILE_RECOVERY_REQUIRED",
|
|
527
|
+
"Profile 迁移恢复失败,已保留恢复备份并暂停运行准入",
|
|
528
|
+
status_code=503,
|
|
529
|
+
)
|
|
248
530
|
if isinstance(error, DshPluginMutationError):
|
|
249
531
|
return StudioError(
|
|
250
532
|
"DSH_PLUGIN_MUTATION_FAILED", "DSH 插件操作失败,原 Profile 已保留", status_code=409
|
|
@@ -277,6 +559,34 @@ def register_plugin_routes(app: FastAPI, studio: StudioService) -> None:
|
|
|
277
559
|
except Exception as error:
|
|
278
560
|
raise _dsh_error(error) from None
|
|
279
561
|
|
|
562
|
+
@app.post("/api/v1/plugin-ecosystems/dsh/core/session")
|
|
563
|
+
async def start_dsh_core_session(response: Response):
|
|
564
|
+
"""Start the official full Core DSH Web profile on demand.
|
|
565
|
+
|
|
566
|
+
The token-bearing URL is returned only from this authenticated,
|
|
567
|
+
CSRF-protected local POST and must never be persisted in Studio state.
|
|
568
|
+
"""
|
|
569
|
+
|
|
570
|
+
try:
|
|
571
|
+
lease = await studio.dsh_capabilities.connector_lease()
|
|
572
|
+
descriptor = await studio.dsh_capabilities.describe()
|
|
573
|
+
browser_url = lease.browser_url()
|
|
574
|
+
except PluginHostError as error:
|
|
575
|
+
raise StudioError(
|
|
576
|
+
"DSH_CORE_RUNTIME_UNAVAILABLE",
|
|
577
|
+
"完整 DSH Core 当前无法启动",
|
|
578
|
+
status_code=503,
|
|
579
|
+
details={"reason": error.code},
|
|
580
|
+
) from error
|
|
581
|
+
response.headers["Cache-Control"] = "no-store"
|
|
582
|
+
return {
|
|
583
|
+
"protocolVersion": "ksadk.dsh-core-runtime/v1",
|
|
584
|
+
"version": descriptor.dsh_version,
|
|
585
|
+
"profile": descriptor.profile,
|
|
586
|
+
"endpoint": browser_url.split("?", 1)[0],
|
|
587
|
+
"browserUrl": browser_url,
|
|
588
|
+
}
|
|
589
|
+
|
|
280
590
|
@app.get("/api/v1/plugin-ecosystems/codex/plugins")
|
|
281
591
|
async def list_codex_plugins(
|
|
282
592
|
installed_only: bool = Query(default=False), force_refetch: bool = Query(default=False)
|
|
@@ -313,7 +623,39 @@ def register_plugin_routes(app: FastAPI, studio: StudioService) -> None:
|
|
|
313
623
|
try:
|
|
314
624
|
async with CodexAppServerPluginBridge(codex_home=codex_home) as bridge:
|
|
315
625
|
detail = await bridge.read_plugin(plugin_id, marketplace_name=marketplace_name)
|
|
316
|
-
|
|
626
|
+
snapshot = _lookup_codex_snapshot(studio, codex_home, detail.inventory)
|
|
627
|
+
return _public_codex_detail(
|
|
628
|
+
detail,
|
|
629
|
+
host=bridge.host,
|
|
630
|
+
home_mode=codex_mode,
|
|
631
|
+
snapshot=snapshot,
|
|
632
|
+
)
|
|
633
|
+
except Exception as error:
|
|
634
|
+
raise _codex_error(error) from None
|
|
635
|
+
|
|
636
|
+
@app.post("/api/v1/plugin-ecosystems/codex/plugins/{plugin_id}:snapshot")
|
|
637
|
+
async def snapshot_codex_plugin(plugin_id: str, payload: CodexPluginSnapshotRequest):
|
|
638
|
+
"""Explicitly admit already-installed host bytes into the workspace store."""
|
|
639
|
+
|
|
640
|
+
try:
|
|
641
|
+
async with CodexAppServerPluginBridge(codex_home=codex_home) as bridge:
|
|
642
|
+
detail = await bridge.read_plugin(
|
|
643
|
+
plugin_id,
|
|
644
|
+
marketplace_name=payload.marketplace_name,
|
|
645
|
+
)
|
|
646
|
+
snapshot = _commit_codex_snapshot(studio, codex_home, detail.inventory)
|
|
647
|
+
projection = _public_codex_snapshot(snapshot)
|
|
648
|
+
item = _public_codex_inventory(
|
|
649
|
+
detail.inventory,
|
|
650
|
+
host=bridge.host,
|
|
651
|
+
home_mode=codex_mode,
|
|
652
|
+
)
|
|
653
|
+
item.update(
|
|
654
|
+
snapshotDigest=projection["snapshotDigest"],
|
|
655
|
+
pluginRef=projection["pluginRef"],
|
|
656
|
+
components=projection["components"],
|
|
657
|
+
)
|
|
658
|
+
return {"item": item, "snapshot": projection, "snapshotRequired": False}
|
|
317
659
|
except Exception as error:
|
|
318
660
|
raise _codex_error(error) from None
|
|
319
661
|
|
|
@@ -323,16 +665,78 @@ def register_plugin_routes(app: FastAPI, studio: StudioService) -> None:
|
|
|
323
665
|
raise _codex_error(CodexPluginApprovalRequired("approval required"))
|
|
324
666
|
try:
|
|
325
667
|
async with CodexAppServerPluginBridge(codex_home=codex_home) as bridge:
|
|
668
|
+
before = await bridge.read_plugin(
|
|
669
|
+
plugin_id,
|
|
670
|
+
marketplace_name=payload.marketplace_name,
|
|
671
|
+
)
|
|
326
672
|
result = await bridge.install_plugin(
|
|
327
673
|
plugin_id,
|
|
328
674
|
marketplace_name=payload.marketplace_name,
|
|
329
675
|
accept_undeclared_permissions=True,
|
|
330
676
|
install_attempt_id=f"studio-{uuid4().hex}",
|
|
331
677
|
)
|
|
678
|
+
try:
|
|
679
|
+
snapshot = _commit_codex_snapshot(studio, codex_home, result.inventory)
|
|
680
|
+
except Exception as snapshot_error:
|
|
681
|
+
failure = _snapshot_failure_details(snapshot_error)
|
|
682
|
+
inventory = _public_codex_inventory(
|
|
683
|
+
result.inventory,
|
|
684
|
+
host=bridge.host,
|
|
685
|
+
home_mode=codex_mode,
|
|
686
|
+
)
|
|
687
|
+
if before.inventory.installed:
|
|
688
|
+
raise StudioError(
|
|
689
|
+
"CODEX_PLUGIN_INSTALLED_BUT_UNADMITTED",
|
|
690
|
+
"Codex 插件仍由宿主安装,但未能提交 KsADK 不可变快照",
|
|
691
|
+
status_code=409,
|
|
692
|
+
details={
|
|
693
|
+
"inventory": inventory,
|
|
694
|
+
"snapshotFailure": failure,
|
|
695
|
+
"compensation": "not-attempted-preexisting-install",
|
|
696
|
+
},
|
|
697
|
+
) from snapshot_error
|
|
698
|
+
try:
|
|
699
|
+
await bridge.uninstall_plugin(result.inventory.plugin_id)
|
|
700
|
+
except Exception as rollback_error:
|
|
701
|
+
raise StudioError(
|
|
702
|
+
"CODEX_PLUGIN_INSTALL_RECONCILIATION_REQUIRED",
|
|
703
|
+
"Codex 插件快照提交失败,且宿主卸载补偿未能确认",
|
|
704
|
+
status_code=409,
|
|
705
|
+
details={
|
|
706
|
+
"inventory": inventory,
|
|
707
|
+
"snapshotFailure": failure,
|
|
708
|
+
"compensation": "uninstall-unconfirmed",
|
|
709
|
+
"compensationFailure": {
|
|
710
|
+
"type": type(rollback_error).__name__,
|
|
711
|
+
"message": str(rollback_error),
|
|
712
|
+
},
|
|
713
|
+
},
|
|
714
|
+
) from rollback_error
|
|
715
|
+
raise StudioError(
|
|
716
|
+
"CODEX_PLUGIN_SNAPSHOT_FAILED_ROLLED_BACK",
|
|
717
|
+
"Codex 插件快照提交失败;本次新安装已由宿主卸载补偿",
|
|
718
|
+
status_code=409,
|
|
719
|
+
details={
|
|
720
|
+
"pluginId": result.inventory.plugin_id,
|
|
721
|
+
"marketplaceName": result.inventory.marketplace_name,
|
|
722
|
+
"snapshotFailure": failure,
|
|
723
|
+
"compensation": "uninstalled",
|
|
724
|
+
},
|
|
725
|
+
) from snapshot_error
|
|
726
|
+
snapshot_projection = _public_codex_snapshot(snapshot)
|
|
727
|
+
item = _public_codex_inventory(
|
|
728
|
+
result.inventory, host=bridge.host, home_mode=codex_mode
|
|
729
|
+
)
|
|
730
|
+
if snapshot_projection is not None:
|
|
731
|
+
item.update(
|
|
732
|
+
snapshotDigest=snapshot_projection["snapshotDigest"],
|
|
733
|
+
pluginRef=snapshot_projection["pluginRef"],
|
|
734
|
+
components=snapshot_projection["components"],
|
|
735
|
+
)
|
|
332
736
|
return {
|
|
333
|
-
"item":
|
|
334
|
-
|
|
335
|
-
|
|
737
|
+
"item": item,
|
|
738
|
+
"snapshot": snapshot_projection,
|
|
739
|
+
"snapshotRequired": False,
|
|
336
740
|
"authPolicy": result.auth_policy,
|
|
337
741
|
"appsNeedingAuth": list(result.apps_needing_auth),
|
|
338
742
|
}
|
|
@@ -371,58 +775,78 @@ def register_plugin_routes(app: FastAPI, studio: StudioService) -> None:
|
|
|
371
775
|
|
|
372
776
|
@app.get("/api/v1/plugin-ecosystems/dsh/profile")
|
|
373
777
|
async def get_dsh_profile_projection():
|
|
374
|
-
host,
|
|
375
|
-
call_dsh, lambda bridge:
|
|
778
|
+
host, projection = await asyncio.to_thread(
|
|
779
|
+
call_dsh, lambda bridge: bridge.project_profile()
|
|
376
780
|
)
|
|
377
|
-
projection, items = result
|
|
378
|
-
bundles = [
|
|
379
|
-
projected
|
|
380
|
-
for item in items
|
|
381
|
-
if item.enabled
|
|
382
|
-
for projected in [_public_dsh_client_bundle(item)]
|
|
383
|
-
if projected is not None
|
|
384
|
-
]
|
|
385
|
-
graph_hash = hashlib.sha256(projection.config_digest.encode("utf-8"))
|
|
386
|
-
for bundle in bundles:
|
|
387
|
-
for value in (str(bundle["pluginId"]), str(bundle["digest"])):
|
|
388
|
-
encoded = value.encode("utf-8")
|
|
389
|
-
graph_hash.update(f"{len(encoded)}:".encode("ascii"))
|
|
390
|
-
graph_hash.update(encoded)
|
|
391
781
|
return {
|
|
392
782
|
"host": _public_host("dsh", host, home_mode=dsh_mode),
|
|
393
783
|
"profile": projection.model_dump(mode="json", by_alias=True),
|
|
394
|
-
"clientGraphDigest": f"sha256:{graph_hash.hexdigest()}",
|
|
395
|
-
"clientBundles": bundles,
|
|
396
784
|
}
|
|
397
785
|
|
|
398
|
-
@app.get("/api/v1/plugin-ecosystems/dsh/
|
|
399
|
-
async def
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
786
|
+
@app.get("/api/v1/plugin-ecosystems/dsh/capabilities")
|
|
787
|
+
async def get_dsh_capabilities():
|
|
788
|
+
snapshot, resource = await studio.dsh_capability_catalog_snapshot()
|
|
789
|
+
descriptor = snapshot.descriptor
|
|
790
|
+
tools = snapshot.tools
|
|
791
|
+
inventory = snapshot.inventory
|
|
792
|
+
return {
|
|
793
|
+
"ecosystem": "dsh",
|
|
794
|
+
"profile": descriptor.profile,
|
|
795
|
+
"profileDigest": descriptor.profile_digest,
|
|
796
|
+
"descriptorDigest": descriptor.descriptor_digest,
|
|
797
|
+
"inventoryDigest": descriptor.inventory_digest,
|
|
798
|
+
"state": inventory.model_dump(by_alias=True, mode="json"),
|
|
799
|
+
"tools": [tool.model_dump(by_alias=True, mode="json") for tool in tools],
|
|
800
|
+
"bindableResource": resource.model_dump(by_alias=True, exclude_none=True, mode="json"),
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
@app.post("/api/v1/plugin-ecosystems/dsh/profile:migrate-layout")
|
|
804
|
+
async def migrate_dsh_profile_layout(payload: DshPluginUpdateRequest):
|
|
805
|
+
if not payload.accept_host_permissions:
|
|
806
|
+
raise _dsh_error(DshPluginApprovalRequired("approval required"))
|
|
807
|
+
|
|
808
|
+
def migrate(bridge: DshProfilePluginBridge):
|
|
809
|
+
bridge.migrate_to_isolated_layout(accept_host_permissions=True)
|
|
810
|
+
return bridge.project_profile()
|
|
811
|
+
|
|
812
|
+
async def operation():
|
|
813
|
+
# Do not release Studio's admission fence while a cancelled HTTP
|
|
814
|
+
# request still has a filesystem migration running in its thread.
|
|
815
|
+
task = asyncio.create_task(asyncio.to_thread(call_dsh, migrate))
|
|
816
|
+
cancelled = False
|
|
817
|
+
while not task.done():
|
|
818
|
+
try:
|
|
819
|
+
await asyncio.shield(task)
|
|
820
|
+
except asyncio.CancelledError:
|
|
821
|
+
cancelled = True
|
|
822
|
+
if cancelled:
|
|
823
|
+
# Retrieve any exception; the reconfiguration owner will recover
|
|
824
|
+
# before allowing another run even when the requester has gone.
|
|
825
|
+
error = task.exception()
|
|
826
|
+
if error is not None:
|
|
827
|
+
raise error
|
|
828
|
+
raise asyncio.CancelledError
|
|
829
|
+
return task.result()
|
|
830
|
+
|
|
831
|
+
host, projection = await studio.reconfigure_dsh_profile(operation)
|
|
832
|
+
return {
|
|
833
|
+
"profile": projection.model_dump(mode="json", by_alias=True),
|
|
834
|
+
"nodeLinker": "isolated",
|
|
835
|
+
"host": {"id": host.host_id, "version": host.version, "available": True},
|
|
836
|
+
}
|
|
416
837
|
|
|
417
838
|
@app.post("/api/v1/plugin-ecosystems/dsh/plugins:install", status_code=201)
|
|
418
839
|
async def install_dsh_plugin(payload: DshPluginInstallRequest):
|
|
419
840
|
if not payload.accept_host_permissions:
|
|
420
841
|
raise _dsh_error(DshPluginApprovalRequired("approval required"))
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
842
|
+
|
|
843
|
+
async def install(): # type: ignore[no-untyped-def]
|
|
844
|
+
return await asyncio.to_thread(
|
|
845
|
+
call_dsh,
|
|
846
|
+
lambda bridge: bridge.install_plugin(payload.source, accept_host_permissions=True),
|
|
847
|
+
)
|
|
848
|
+
|
|
849
|
+
host, item = await studio.reconfigure_dsh_profile(install)
|
|
426
850
|
return {"item": public_dsh(item, host)}
|
|
427
851
|
|
|
428
852
|
async def mutate_dsh(plugin_name: str, operation: str):
|
|
@@ -435,29 +859,36 @@ def register_plugin_routes(app: FastAPI, studio: StudioService) -> None:
|
|
|
435
859
|
return bridge.uninstall_plugin(plugin_name)
|
|
436
860
|
return bridge.get_plugin(plugin_name)
|
|
437
861
|
|
|
438
|
-
|
|
862
|
+
if operation == "get":
|
|
863
|
+
return await asyncio.to_thread(call_dsh, action)
|
|
864
|
+
|
|
865
|
+
async def mutate(): # type: ignore[no-untyped-def]
|
|
866
|
+
return await asyncio.to_thread(call_dsh, action)
|
|
867
|
+
|
|
868
|
+
return await studio.reconfigure_dsh_profile(mutate)
|
|
439
869
|
|
|
440
870
|
@app.post("/api/v1/plugin-ecosystems/dsh/plugins/{plugin_name:path}:enable")
|
|
441
871
|
async def enable_dsh_plugin(plugin_name: str):
|
|
442
872
|
host, item = await mutate_dsh(plugin_name, "enable")
|
|
443
|
-
await studio.refresh_dsh_provider_registrations()
|
|
444
873
|
return {"item": public_dsh(item, host)}
|
|
445
874
|
|
|
446
875
|
@app.post("/api/v1/plugin-ecosystems/dsh/plugins/{plugin_name:path}:disable")
|
|
447
876
|
async def disable_dsh_plugin(plugin_name: str):
|
|
448
877
|
host, item = await mutate_dsh(plugin_name, "disable")
|
|
449
|
-
await studio.refresh_dsh_provider_registrations()
|
|
450
878
|
return {"item": public_dsh(item, host)}
|
|
451
879
|
|
|
452
880
|
@app.post("/api/v1/plugin-ecosystems/dsh/plugins/{plugin_name:path}:update")
|
|
453
881
|
async def update_dsh_plugin(plugin_name: str, payload: DshPluginUpdateRequest):
|
|
454
882
|
if not payload.accept_host_permissions:
|
|
455
883
|
raise _dsh_error(DshPluginApprovalRequired("approval required"))
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
884
|
+
|
|
885
|
+
async def update(): # type: ignore[no-untyped-def]
|
|
886
|
+
return await asyncio.to_thread(
|
|
887
|
+
call_dsh,
|
|
888
|
+
lambda bridge: bridge.update_plugin(plugin_name, accept_host_permissions=True),
|
|
889
|
+
)
|
|
890
|
+
|
|
891
|
+
host, item = await studio.reconfigure_dsh_profile(update)
|
|
461
892
|
return {"item": public_dsh(item, host)}
|
|
462
893
|
|
|
463
894
|
@app.get("/api/v1/plugin-ecosystems/dsh/plugins/{plugin_name:path}")
|
|
@@ -468,12 +899,12 @@ def register_plugin_routes(app: FastAPI, studio: StudioService) -> None:
|
|
|
468
899
|
@app.delete("/api/v1/plugin-ecosystems/dsh/plugins/{plugin_name:path}", status_code=204)
|
|
469
900
|
async def uninstall_dsh_plugin(plugin_name: str):
|
|
470
901
|
await mutate_dsh(plugin_name, "uninstall")
|
|
471
|
-
await studio.refresh_dsh_provider_registrations()
|
|
472
902
|
return Response(status_code=204)
|
|
473
903
|
|
|
474
904
|
|
|
475
905
|
__all__ = [
|
|
476
906
|
"CodexPluginInstallRequest",
|
|
907
|
+
"CodexPluginSnapshotRequest",
|
|
477
908
|
"DshPluginInstallRequest",
|
|
478
909
|
"DshPluginUpdateRequest",
|
|
479
910
|
"register_plugin_routes",
|