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
ksadk/studio/compiler.py
CHANGED
|
@@ -6,6 +6,8 @@ from dataclasses import dataclass
|
|
|
6
6
|
from typing import Any
|
|
7
7
|
from urllib.parse import urlparse
|
|
8
8
|
|
|
9
|
+
from ksadk.plugins.providers.legacy_catalog import CODEX_AGENT_PROVIDER_PLUGIN_ID
|
|
10
|
+
from ksadk.resource_runtime.plugin_config import resource_plugin_config
|
|
9
11
|
from ksadk.studio.capabilities import (
|
|
10
12
|
CapabilityResolver,
|
|
11
13
|
LocalCapabilityResolver,
|
|
@@ -46,6 +48,39 @@ class AgentCompiler:
|
|
|
46
48
|
self.catalog = catalog or LocalResourceCatalog(workspace)
|
|
47
49
|
|
|
48
50
|
def compile(self, draft: AgentDraft) -> CompileResult:
|
|
51
|
+
unsupported_plugins = [
|
|
52
|
+
binding.plugin_ref
|
|
53
|
+
for binding in draft.spec.bindings.plugins
|
|
54
|
+
if binding.enabled
|
|
55
|
+
and resource_plugin_config(
|
|
56
|
+
binding.plugin_ref,
|
|
57
|
+
binding.ecosystem,
|
|
58
|
+
binding.config,
|
|
59
|
+
enabled=True,
|
|
60
|
+
)
|
|
61
|
+
is None
|
|
62
|
+
]
|
|
63
|
+
if unsupported_plugins:
|
|
64
|
+
raise StudioError(
|
|
65
|
+
"NATIVE_PLUGIN_RUNTIME_INCOMPATIBLE",
|
|
66
|
+
"Framework Agent 不能直接绑定未物化的原生插件快照",
|
|
67
|
+
status_code=422,
|
|
68
|
+
field="spec.bindings.plugins",
|
|
69
|
+
details={"pluginRefs": sorted(unsupported_plugins)},
|
|
70
|
+
)
|
|
71
|
+
direct_dynamic = [
|
|
72
|
+
server.name
|
|
73
|
+
for server in draft.spec.capabilities.mcp_servers
|
|
74
|
+
if server.enabled and server.materialization == "dsh-profile"
|
|
75
|
+
]
|
|
76
|
+
if direct_dynamic:
|
|
77
|
+
raise StudioError(
|
|
78
|
+
"DSH_MCP_MANAGED_BINDING_REQUIRED",
|
|
79
|
+
"DSH Profile MCP 必须从当前 Catalog Resource 显式绑定,不能直接写入 AgentSpec",
|
|
80
|
+
status_code=422,
|
|
81
|
+
field="spec.capabilities.mcpServers",
|
|
82
|
+
details={"servers": sorted(direct_dynamic)},
|
|
83
|
+
)
|
|
49
84
|
source_payload = draft.model_dump(by_alias=True, exclude_none=True, mode="json")
|
|
50
85
|
source_digest = sha256_digest(canonical_json(source_payload))
|
|
51
86
|
materialized = self._materialize_bindings(draft)
|
|
@@ -62,10 +97,7 @@ class AgentCompiler:
|
|
|
62
97
|
for ref in materialized.spec.capabilities.mcp_servers
|
|
63
98
|
if ref.enabled
|
|
64
99
|
]
|
|
65
|
-
tools = [
|
|
66
|
-
self.resolver.resolve_tool(tool)
|
|
67
|
-
for tool in materialized.spec.capabilities.tools
|
|
68
|
-
]
|
|
100
|
+
tools = [self.resolver.resolve_tool(tool) for tool in materialized.spec.capabilities.tools]
|
|
69
101
|
skills.sort(key=lambda item: (item["name"], item["version"], item["digest"]))
|
|
70
102
|
mcp_servers.sort(key=lambda item: (item["name"], item["version"], item["digest"]))
|
|
71
103
|
tools.sort(key=lambda item: (item.name, item.version, item.digest or ""))
|
|
@@ -111,21 +143,53 @@ class AgentCompiler:
|
|
|
111
143
|
"skills": skills,
|
|
112
144
|
"mcpServers": mcp_servers,
|
|
113
145
|
"tools": [
|
|
114
|
-
tool.model_dump(by_alias=True, exclude_none=True, mode="json")
|
|
115
|
-
for tool in tools
|
|
146
|
+
tool.model_dump(by_alias=True, exclude_none=True, mode="json") for tool in tools
|
|
116
147
|
],
|
|
117
148
|
}
|
|
118
149
|
return CompileResult(resolved=resolved, dependency_lock=dependency_lock)
|
|
119
150
|
|
|
120
151
|
def _materialize_bindings(self, draft: AgentDraft) -> AgentDraft:
|
|
152
|
+
runtime = draft.spec.runtime
|
|
153
|
+
uses_codex_native_tools = bool(
|
|
154
|
+
runtime
|
|
155
|
+
and (
|
|
156
|
+
runtime.type == "codex"
|
|
157
|
+
or (
|
|
158
|
+
runtime.type == "plugin"
|
|
159
|
+
and runtime.provider_ref
|
|
160
|
+
and runtime.provider_ref.startswith(
|
|
161
|
+
f"plugin://{CODEX_AGENT_PROVIDER_PLUGIN_ID}@"
|
|
162
|
+
)
|
|
163
|
+
)
|
|
164
|
+
)
|
|
165
|
+
)
|
|
121
166
|
bindings = draft.spec.bindings
|
|
167
|
+
if uses_codex_native_tools and bindings.tools:
|
|
168
|
+
bindings = bindings.model_copy(update={"tools": []})
|
|
122
169
|
if (
|
|
123
|
-
not
|
|
170
|
+
not uses_codex_native_tools
|
|
171
|
+
and not bindings.model_profile_id
|
|
124
172
|
and not bindings.tools
|
|
125
173
|
and not bindings.mcp_servers
|
|
126
174
|
and not bindings.skills
|
|
127
175
|
):
|
|
128
176
|
return draft
|
|
177
|
+
runtime_type = draft.spec.runtime.type if draft.spec.runtime is not None else None
|
|
178
|
+
for binding in bindings.mcp_servers:
|
|
179
|
+
if not binding.enabled:
|
|
180
|
+
continue
|
|
181
|
+
descriptor = self.catalog.get(binding.resource_id)
|
|
182
|
+
if (
|
|
183
|
+
descriptor.contract.get("materialization") == "dsh-profile"
|
|
184
|
+
and runtime_type != "harness"
|
|
185
|
+
):
|
|
186
|
+
raise StudioError(
|
|
187
|
+
"DSH_MCP_RUNTIME_INCOMPATIBLE",
|
|
188
|
+
"DSH Profile MCP 当前只支持 Harness Runtime",
|
|
189
|
+
status_code=422,
|
|
190
|
+
field="spec.runtime.type",
|
|
191
|
+
details={"runtimeType": runtime_type},
|
|
192
|
+
)
|
|
129
193
|
materialized = draft.model_copy(deep=True)
|
|
130
194
|
model = self.catalog.resolve_model(bindings) or materialized.spec.model
|
|
131
195
|
if model is None:
|
|
@@ -147,9 +211,13 @@ class AgentCompiler:
|
|
|
147
211
|
*self.catalog.resolve_mcp_servers(bindings),
|
|
148
212
|
],
|
|
149
213
|
tools=[
|
|
150
|
-
*materialized.spec.capabilities.tools,
|
|
214
|
+
*([] if uses_codex_native_tools else materialized.spec.capabilities.tools),
|
|
151
215
|
*bound_tools,
|
|
152
|
-
|
|
216
|
+
# Non-Codex runtimes consume the probed MCP contracts through
|
|
217
|
+
# the generic Tool execution path. Codex connects to the MCP
|
|
218
|
+
# server natively, so expanding those contracts here turns a
|
|
219
|
+
# valid MCP binding into unsupported third-party tools.
|
|
220
|
+
*([] if uses_codex_native_tools else bound_mcp_tools),
|
|
153
221
|
],
|
|
154
222
|
)
|
|
155
223
|
self._require_unique(
|
|
@@ -169,11 +237,7 @@ class AgentCompiler:
|
|
|
169
237
|
materialized.spec.security.allowed_permissions = sorted(
|
|
170
238
|
set(materialized.spec.security.allowed_permissions)
|
|
171
239
|
| set(permissions)
|
|
172
|
-
| {
|
|
173
|
-
permission
|
|
174
|
-
for tool in bound_mcp_tools
|
|
175
|
-
for permission in tool.permissions
|
|
176
|
-
}
|
|
240
|
+
| {permission for tool in bound_mcp_tools for permission in tool.permissions}
|
|
177
241
|
)
|
|
178
242
|
endpoint = model.endpoint_url or model.base_url or ""
|
|
179
243
|
hostname = (urlparse(endpoint).hostname or "").lower().rstrip(".")
|
ksadk/studio/contracts.py
CHANGED
|
@@ -107,9 +107,40 @@ class MCPServerRef(CapabilityRef):
|
|
|
107
107
|
args: list[str] = Field(default_factory=list)
|
|
108
108
|
endpoint_url: str | None = None
|
|
109
109
|
env_refs: dict[str, str] = Field(default_factory=dict)
|
|
110
|
+
# ``dsh-profile`` is resolved at PluginHost activation time. Only the
|
|
111
|
+
# immutable profile/inventory identity is allowed into an Agent Build;
|
|
112
|
+
# the loopback endpoint and bearer token remain process-scoped lease data.
|
|
113
|
+
materialization: Literal["dsh-profile"] | None = None
|
|
114
|
+
profile: str | None = None
|
|
115
|
+
profile_digest: str | None = None
|
|
116
|
+
descriptor_digest: str | None = None
|
|
117
|
+
inventory_digest: str | None = None
|
|
110
118
|
|
|
111
119
|
@model_validator(mode="after")
|
|
112
120
|
def validate_transport(self) -> "MCPServerRef":
|
|
121
|
+
dynamic_fields = (
|
|
122
|
+
self.profile,
|
|
123
|
+
self.profile_digest,
|
|
124
|
+
self.descriptor_digest,
|
|
125
|
+
self.inventory_digest,
|
|
126
|
+
)
|
|
127
|
+
if self.materialization == "dsh-profile":
|
|
128
|
+
if self.transport != "http":
|
|
129
|
+
raise ValueError("DSH Profile MCP 必须使用运行时 HTTP 租约")
|
|
130
|
+
if self.endpoint_url or self.command or self.args or self.env_refs:
|
|
131
|
+
raise ValueError("DSH Profile MCP 不能持久化 endpoint、命令或环境变量")
|
|
132
|
+
if not all(dynamic_fields):
|
|
133
|
+
raise ValueError("DSH Profile MCP 必须锁定 Profile 与能力摘要")
|
|
134
|
+
if not re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9._-]{0,63}", self.profile or ""):
|
|
135
|
+
raise ValueError("DSH Profile 名称无效")
|
|
136
|
+
if any(
|
|
137
|
+
not re.fullmatch(r"sha256:[0-9a-f]{64}", value or "")
|
|
138
|
+
for value in dynamic_fields[1:]
|
|
139
|
+
):
|
|
140
|
+
raise ValueError("DSH Profile MCP 摘要无效")
|
|
141
|
+
return self
|
|
142
|
+
if any(value is not None for value in dynamic_fields):
|
|
143
|
+
raise ValueError("静态 MCP 不能声明 DSH Profile 运行时字段")
|
|
113
144
|
if self.transport == "stdio" and not self.command:
|
|
114
145
|
raise ValueError("stdio MCP 必须配置 command")
|
|
115
146
|
if self.transport in {"http", "sse"} and not self.endpoint_url:
|
|
@@ -198,6 +229,53 @@ class CapabilityBinding(ContractModel):
|
|
|
198
229
|
config: dict[str, Any] = Field(default_factory=dict)
|
|
199
230
|
|
|
200
231
|
|
|
232
|
+
class NativePluginBinding(ContractModel):
|
|
233
|
+
"""Immutable component selection from a host-managed native plugin."""
|
|
234
|
+
|
|
235
|
+
ecosystem: Literal["codex", "dsh"]
|
|
236
|
+
plugin_ref: str = Field(min_length=12, max_length=256)
|
|
237
|
+
snapshot_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$")
|
|
238
|
+
components: list[str] = Field(min_length=1, max_length=128)
|
|
239
|
+
enabled: bool = True
|
|
240
|
+
config: dict[str, Any] = Field(default_factory=dict)
|
|
241
|
+
|
|
242
|
+
@field_validator("plugin_ref")
|
|
243
|
+
@classmethod
|
|
244
|
+
def validate_plugin_ref(cls, value: str) -> str:
|
|
245
|
+
if not re.fullmatch(
|
|
246
|
+
r"plugin://[a-z0-9]+(?:[._-][a-z0-9]+)*@"
|
|
247
|
+
r"\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?",
|
|
248
|
+
value,
|
|
249
|
+
):
|
|
250
|
+
raise ValueError("插件绑定必须使用 plugin://<id>@<exact-version>")
|
|
251
|
+
return value
|
|
252
|
+
|
|
253
|
+
@field_validator("components")
|
|
254
|
+
@classmethod
|
|
255
|
+
def validate_components(cls, value: list[str]) -> list[str]:
|
|
256
|
+
if len(value) != len(set(value)):
|
|
257
|
+
raise ValueError("插件组件不能重复")
|
|
258
|
+
if any(
|
|
259
|
+
not re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}", component)
|
|
260
|
+
for component in value
|
|
261
|
+
):
|
|
262
|
+
raise ValueError("插件组件 ID 无效")
|
|
263
|
+
return value
|
|
264
|
+
|
|
265
|
+
@field_validator("config")
|
|
266
|
+
@classmethod
|
|
267
|
+
def validate_config(cls, value: dict[str, Any]) -> dict[str, Any]:
|
|
268
|
+
_reject_clear_runtime_secrets(value, path="pluginBinding.config")
|
|
269
|
+
return value
|
|
270
|
+
|
|
271
|
+
@model_validator(mode="after")
|
|
272
|
+
def validate_platform_resource_config(self) -> "NativePluginBinding":
|
|
273
|
+
from ksadk.resource_runtime.plugin_config import resource_plugin_config
|
|
274
|
+
|
|
275
|
+
resource_plugin_config(self.plugin_ref, self.ecosystem, self.config, enabled=self.enabled)
|
|
276
|
+
return self
|
|
277
|
+
|
|
278
|
+
|
|
201
279
|
class AgentBindings(ContractModel):
|
|
202
280
|
model_profile_id: str | None = None
|
|
203
281
|
model_profile_ids: list[str] = Field(default_factory=list)
|
|
@@ -206,6 +284,7 @@ class AgentBindings(ContractModel):
|
|
|
206
284
|
tools: list[CapabilityBinding] = Field(default_factory=list)
|
|
207
285
|
mcp_servers: list[CapabilityBinding] = Field(default_factory=list)
|
|
208
286
|
skills: list[CapabilityBinding] = Field(default_factory=list)
|
|
287
|
+
plugins: list[NativePluginBinding] = Field(default_factory=list)
|
|
209
288
|
|
|
210
289
|
@model_validator(mode="after")
|
|
211
290
|
def validate_model_profiles(self) -> "AgentBindings":
|
|
@@ -219,6 +298,12 @@ class AgentBindings(ContractModel):
|
|
|
219
298
|
and self.model_profile_id not in self.model_profile_ids
|
|
220
299
|
):
|
|
221
300
|
raise ValueError("默认 modelProfileId 必须包含在 modelProfileIds 中")
|
|
301
|
+
plugin_refs = [binding.plugin_ref for binding in self.plugins if binding.enabled]
|
|
302
|
+
if len(plugin_refs) != len(set(plugin_refs)):
|
|
303
|
+
raise ValueError("启用的插件绑定不能重复 pluginRef")
|
|
304
|
+
from ksadk.resource_runtime.plugin_config import validate_resource_plugin_bindings
|
|
305
|
+
|
|
306
|
+
validate_resource_plugin_bindings(self.plugins)
|
|
222
307
|
return self
|
|
223
308
|
|
|
224
309
|
|
|
@@ -418,9 +503,7 @@ class RuntimeRef(ContractModel):
|
|
|
418
503
|
return self
|
|
419
504
|
|
|
420
505
|
|
|
421
|
-
_RUNTIME_SECRET_KEY = re.compile(
|
|
422
|
-
r"(?:secret|password|token|api[_-]?key)", re.IGNORECASE
|
|
423
|
-
)
|
|
506
|
+
_RUNTIME_SECRET_KEY = re.compile(r"(?:secret|password|token|api[_-]?key)", re.IGNORECASE)
|
|
424
507
|
_RUNTIME_SECRET_REF_PREFIXES = (
|
|
425
508
|
"secret://",
|
|
426
509
|
"env://",
|
|
@@ -436,9 +519,7 @@ def _reject_clear_runtime_secrets(value: Any, *, path: str = "providerConfig") -
|
|
|
436
519
|
for key, child in value.items():
|
|
437
520
|
child_path = f"{path}.{key}"
|
|
438
521
|
if _RUNTIME_SECRET_KEY.search(str(key)) and child is not None:
|
|
439
|
-
if not isinstance(child, str) or not child.startswith(
|
|
440
|
-
_RUNTIME_SECRET_REF_PREFIXES
|
|
441
|
-
):
|
|
522
|
+
if not isinstance(child, str) or not child.startswith(_RUNTIME_SECRET_REF_PREFIXES):
|
|
442
523
|
raise ValueError(f"{child_path} 必须保存 Secret 引用,不能保存明文")
|
|
443
524
|
_reject_clear_runtime_secrets(child, path=child_path)
|
|
444
525
|
elif isinstance(value, list):
|
|
@@ -460,6 +541,27 @@ class AgentSpec(ContractModel):
|
|
|
460
541
|
security: SecuritySpec = Field(default_factory=SecuritySpec)
|
|
461
542
|
evaluation: EvaluationSpec = Field(default_factory=EvaluationSpec)
|
|
462
543
|
|
|
544
|
+
@model_validator(mode="after")
|
|
545
|
+
def validate_memory_resource_reference(self) -> "AgentSpec":
|
|
546
|
+
if not self.memory.enabled or not self.memory.provider_ref.startswith("binding://"):
|
|
547
|
+
return self
|
|
548
|
+
from ksadk.resource_runtime.plugin_config import resource_plugin_config
|
|
549
|
+
|
|
550
|
+
binding_id = self.memory.provider_ref.removeprefix("binding://")
|
|
551
|
+
for binding in self.bindings.plugins:
|
|
552
|
+
if not binding.enabled:
|
|
553
|
+
continue
|
|
554
|
+
resource = resource_plugin_config(
|
|
555
|
+
binding.plugin_ref, binding.ecosystem, binding.config, enabled=True
|
|
556
|
+
)
|
|
557
|
+
if resource is not None and resource.binding.id == binding_id:
|
|
558
|
+
if resource.binding.resource.kind != "memory-instance":
|
|
559
|
+
raise ValueError("Memory providerRef must reference a memory-instance binding")
|
|
560
|
+
if self.memory.scopes != ["user"]:
|
|
561
|
+
raise ValueError("Platform memory requires explicit scopes: [user]")
|
|
562
|
+
return self
|
|
563
|
+
raise ValueError("Memory providerRef references a missing or disabled resource binding")
|
|
564
|
+
|
|
463
565
|
|
|
464
566
|
_AGENT_ID_PATTERN = re.compile(r"^[a-z][a-z0-9-]{2,62}$")
|
|
465
567
|
_AGENT_AVATAR_URL_PATTERN = re.compile(r"^/api/v1/assets/agent-avatars/[0-9a-f]{64}\.(?:png|webp)$")
|
|
@@ -638,6 +740,14 @@ class BundleManifest(ContractModel):
|
|
|
638
740
|
composition_mode: Literal["legacy", "composed"] | None = None
|
|
639
741
|
composition_profile_digest: str | None = None
|
|
640
742
|
hosted_kernel_requirement_digest: str = ""
|
|
743
|
+
resource_build_digest: str | None = Field(
|
|
744
|
+
default=None,
|
|
745
|
+
pattern=r"^sha256:[0-9a-f]{64}$",
|
|
746
|
+
)
|
|
747
|
+
resource_snapshot_digest: str | None = Field(
|
|
748
|
+
default=None,
|
|
749
|
+
pattern=r"^sha256:[0-9a-f]{64}$",
|
|
750
|
+
)
|
|
641
751
|
files: list[FileEntry]
|
|
642
752
|
created_at: str = "1970-01-01T00:00:00Z"
|
|
643
753
|
bundle_digest: str = ""
|
|
@@ -648,6 +758,10 @@ class BundleManifest(ContractModel):
|
|
|
648
758
|
raise ValueError("composed Bundle v2 requires compositionProfileDigest")
|
|
649
759
|
if self.composition_mode == "legacy" and self.composition_profile_digest:
|
|
650
760
|
raise ValueError("legacy Bundle v2 cannot declare compositionProfileDigest")
|
|
761
|
+
if bool(self.resource_build_digest) != bool(self.resource_snapshot_digest):
|
|
762
|
+
raise ValueError(
|
|
763
|
+
"resourceBuildDigest and resourceSnapshotDigest must be declared together"
|
|
764
|
+
)
|
|
651
765
|
return self
|
|
652
766
|
|
|
653
767
|
@property
|
|
@@ -680,6 +794,14 @@ class BuildRecord(ContractModel):
|
|
|
680
794
|
source_digest: str = ""
|
|
681
795
|
runtime_lock: dict[str, Any] = Field(default_factory=dict)
|
|
682
796
|
bundle_digest: str = ""
|
|
797
|
+
resource_build_digest: str | None = Field(
|
|
798
|
+
default=None,
|
|
799
|
+
pattern=r"^sha256:[0-9a-f]{64}$",
|
|
800
|
+
)
|
|
801
|
+
resource_snapshot_digest: str | None = Field(
|
|
802
|
+
default=None,
|
|
803
|
+
pattern=r"^sha256:[0-9a-f]{64}$",
|
|
804
|
+
)
|
|
683
805
|
artifact_path: str | None = None
|
|
684
806
|
diagnostics: list[Diagnostic] = Field(default_factory=list)
|
|
685
807
|
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
|
|
@@ -854,6 +976,10 @@ class DeploymentRequest(ContractModel):
|
|
|
854
976
|
|
|
855
977
|
|
|
856
978
|
class DeploymentRecord(ContractModel):
|
|
979
|
+
# Identity observed when the cloud Agent was created, never inferred from
|
|
980
|
+
# whichever credentials happen to be configured when history is read.
|
|
981
|
+
created_by_name: str | None = None
|
|
982
|
+
created_by_user_id: str | None = None
|
|
857
983
|
id: str
|
|
858
984
|
build_id: str
|
|
859
985
|
bundle_digest: str
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"""Same-origin transport for the official Core client under the Studio shell.
|
|
2
|
+
|
|
3
|
+
This forwards bytes to the one supervised Core. It implements no DSH services,
|
|
4
|
+
plugin protocol, settings store, or module loader.
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import hmac
|
|
10
|
+
from http.cookiejar import CookieJar
|
|
11
|
+
from urllib.request import HTTPCookieProcessor, ProxyHandler, build_opener
|
|
12
|
+
from urllib.parse import urlsplit
|
|
13
|
+
from urllib.error import URLError
|
|
14
|
+
|
|
15
|
+
import httpx
|
|
16
|
+
from fastapi import FastAPI, Request, WebSocket
|
|
17
|
+
from starlette.background import BackgroundTask
|
|
18
|
+
from starlette.responses import Response, StreamingResponse
|
|
19
|
+
|
|
20
|
+
from ksadk.studio.errors import StudioError
|
|
21
|
+
from ksadk.plugins.host import PluginHostError
|
|
22
|
+
|
|
23
|
+
_HOP_HEADERS = {"host", "connection", "transfer-encoding", "content-length"}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def register_dsh_application(app: FastAPI, studio, *, session_secret: str, security_enabled: bool):
|
|
27
|
+
def authorized(cookies):
|
|
28
|
+
token = cookies.get("agentkit_studio_session", "")
|
|
29
|
+
return not security_enabled or hmac.compare_digest(token, session_secret)
|
|
30
|
+
|
|
31
|
+
@app.api_route("/studio-core/", methods=["GET"])
|
|
32
|
+
async def application(request: Request):
|
|
33
|
+
if not authorized(request.cookies):
|
|
34
|
+
raise StudioError("LOCAL_SESSION_REQUIRED", "请从 Studio 启动链接进入", status_code=401)
|
|
35
|
+
try:
|
|
36
|
+
lease = await studio.dsh_capabilities.connector_lease()
|
|
37
|
+
except PluginHostError:
|
|
38
|
+
raise StudioError("DSH_CORE_UNAVAILABLE", "插件服务暂时不可用,请返回 Studio 重试", status_code=503) from None
|
|
39
|
+
def bootstrap():
|
|
40
|
+
# urllib does not log the process-token URL at INFO like httpx.
|
|
41
|
+
jar = CookieJar()
|
|
42
|
+
opener = build_opener(ProxyHandler({}), HTTPCookieProcessor(jar))
|
|
43
|
+
with opener.open(lease.browser_url(), timeout=30) as response:
|
|
44
|
+
return response.read(), tuple(jar)
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
body, cookies = await asyncio.to_thread(bootstrap)
|
|
48
|
+
except (URLError, OSError):
|
|
49
|
+
# The upstream bootstrap URL contains a process token. Do not
|
|
50
|
+
# allow urllib's URL-bearing exception into API responses/logs.
|
|
51
|
+
raise StudioError("DSH_CORE_UNAVAILABLE", "插件服务连接失败,请返回 Studio 重试", status_code=503) from None
|
|
52
|
+
body = body.replace(b'<base href="/">', b'<base href="/studio-core/">')
|
|
53
|
+
result = Response(body, media_type="text/html", headers={"Cache-Control": "no-store"})
|
|
54
|
+
for cookie in cookies:
|
|
55
|
+
result.set_cookie(cookie.name, cookie.value, path=cookie.path, httponly=True, samesite="strict")
|
|
56
|
+
return result
|
|
57
|
+
|
|
58
|
+
# Registered last: the Studio API/static routes retain ownership of their paths.
|
|
59
|
+
@app.api_route("/{core_path:path}", methods=["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"])
|
|
60
|
+
async def core_http(core_path: str, request: Request):
|
|
61
|
+
if not authorized(request.cookies):
|
|
62
|
+
raise StudioError("LOCAL_SESSION_REQUIRED", "缺少有效的 Studio 本地会话", status_code=401)
|
|
63
|
+
# Retired Studio chat URLs must not start Core or depend on its availability.
|
|
64
|
+
if core_path.rstrip("/") == "chat" or core_path.startswith(("api/v1/", "v1/")):
|
|
65
|
+
raise StudioError("NOT_FOUND", "接口不存在", status_code=404)
|
|
66
|
+
# Browser mutations must originate in this document; never treat a
|
|
67
|
+
# cross-port loopback origin as trusted just because it is local.
|
|
68
|
+
if request.method not in {"GET", "HEAD"} and request.headers.get("origin") != str(request.base_url).rstrip("/"):
|
|
69
|
+
raise StudioError("LOCAL_ORIGIN_FORBIDDEN", "插件请求来源无效", status_code=403)
|
|
70
|
+
lease = await studio.dsh_capabilities.application_lease()
|
|
71
|
+
origin = lease.endpoint.rsplit("/", 1)[0]
|
|
72
|
+
path = request.url.path.removeprefix("/studio-core")
|
|
73
|
+
if request.url.query:
|
|
74
|
+
path += "?" + request.url.query
|
|
75
|
+
client = httpx.AsyncClient(trust_env=False, timeout=None)
|
|
76
|
+
headers = {key: value for key, value in request.headers.items() if key.lower() not in _HOP_HEADERS}
|
|
77
|
+
# Core checks origin against its own listening socket.
|
|
78
|
+
if "origin" in headers:
|
|
79
|
+
headers["origin"] = origin
|
|
80
|
+
try:
|
|
81
|
+
upstream = await client.send(client.build_request(request.method, origin + path, headers=headers, content=request.stream()), stream=True)
|
|
82
|
+
except BaseException:
|
|
83
|
+
await client.aclose()
|
|
84
|
+
raise
|
|
85
|
+
|
|
86
|
+
async def close():
|
|
87
|
+
await upstream.aclose()
|
|
88
|
+
await client.aclose()
|
|
89
|
+
|
|
90
|
+
result = StreamingResponse(upstream.aiter_raw(), status_code=upstream.status_code, background=BackgroundTask(close))
|
|
91
|
+
result.raw_headers = [(key, value) for key, value in upstream.headers.raw if key.decode().lower() not in _HOP_HEADERS]
|
|
92
|
+
return result
|
|
93
|
+
|
|
94
|
+
@app.websocket("/{core_path:path}")
|
|
95
|
+
async def core_socket(websocket: WebSocket, core_path: str):
|
|
96
|
+
# The SDK supports websockets 12 through 15; the legacy client is
|
|
97
|
+
# available throughout this range (the asyncio client starts at 13).
|
|
98
|
+
from websockets.legacy.client import connect
|
|
99
|
+
|
|
100
|
+
origin = websocket.headers.get("origin")
|
|
101
|
+
expected = f"http://{websocket.headers.get('host')}"
|
|
102
|
+
if not authorized(websocket.cookies) or origin != expected:
|
|
103
|
+
await websocket.close(code=1008)
|
|
104
|
+
return
|
|
105
|
+
lease = await studio.dsh_capabilities.application_lease()
|
|
106
|
+
endpoint = urlsplit(lease.endpoint)
|
|
107
|
+
path = websocket.url.path.removeprefix("/studio-core") + ("?" + websocket.url.query if websocket.url.query else "")
|
|
108
|
+
protocols = websocket.scope.get("subprotocols", [])
|
|
109
|
+
async with connect(
|
|
110
|
+
f"ws://127.0.0.1:{endpoint.port}{path}",
|
|
111
|
+
origin=f"http://127.0.0.1:{endpoint.port}",
|
|
112
|
+
extra_headers={"Cookie": websocket.headers.get("cookie", "")},
|
|
113
|
+
subprotocols=protocols or None, max_size=16 * 1024 * 1024,
|
|
114
|
+
) as upstream:
|
|
115
|
+
await websocket.accept(subprotocol=upstream.subprotocol)
|
|
116
|
+
|
|
117
|
+
async def to_core():
|
|
118
|
+
while True:
|
|
119
|
+
message = await websocket.receive()
|
|
120
|
+
if message["type"] == "websocket.disconnect":
|
|
121
|
+
return
|
|
122
|
+
await upstream.send(message.get("text") if message.get("text") is not None else message["bytes"])
|
|
123
|
+
|
|
124
|
+
async def to_browser():
|
|
125
|
+
async for message in upstream:
|
|
126
|
+
if isinstance(message, str):
|
|
127
|
+
await websocket.send_text(message)
|
|
128
|
+
else:
|
|
129
|
+
await websocket.send_bytes(message)
|
|
130
|
+
|
|
131
|
+
tasks = [asyncio.create_task(to_core()), asyncio.create_task(to_browser())]
|
|
132
|
+
try:
|
|
133
|
+
await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
|
|
134
|
+
finally:
|
|
135
|
+
for task in tasks:
|
|
136
|
+
task.cancel()
|
|
137
|
+
await asyncio.gather(*tasks, return_exceptions=True)
|