agentengine-sdk-python 0.8.2__py3-none-any.whl → 0.8.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/METADATA +22 -28
- agentengine_sdk_python-0.8.4.dist-info/RECORD +1070 -0
- ksadk/_build_provenance.json +1 -0
- ksadk/agui/_agent_helpers.py +4 -0
- ksadk/api/client.py +108 -91
- ksadk/builders/code_builder.py +36 -9
- ksadk/builders/framework_requirements.py +2 -1
- ksadk/builders/ks3_uploader.py +36 -7
- ksadk/builders/managed_runtime_builder.py +4 -0
- ksadk/cli/__init__.py +38 -3
- ksadk/cli/cmd_managed_runtime.py +13 -1
- ksadk/cli/cmd_plugin.py +662 -0
- ksadk/cli/cmd_web.py +2 -5
- ksadk/cli/runtime_bootstrap.py +23 -1
- ksadk/codex/client.py +424 -96
- ksadk/codex/projection.py +24 -0
- ksadk/codex/runtime.py +83 -283
- ksadk/common/auth.py +16 -10
- ksadk/configs/env_registry.py +59 -3
- ksadk/configs/settings.py +9 -0
- ksadk/context_engine/contributors.py +73 -8
- ksadk/conversations/__init__.py +19 -0
- ksadk/conversations/context.py +104 -24
- ksadk/conversations/contracts.py +266 -0
- ksadk/conversations/message_projection.py +154 -15
- ksadk/conversations/projector.py +614 -0
- ksadk/conversations/reducer.py +98 -0
- ksadk/conversations/runtime_invocation.py +5 -0
- ksadk/conversations/runtime_payloads.py +1 -0
- ksadk/conversations/runtime_preparation.py +30 -27
- ksadk/conversations/runtime_resume.py +50 -2
- ksadk/conversations/runtime_stream_events.py +5 -0
- ksadk/conversations/runtime_streaming.py +25 -7
- ksadk/deployment/env_forward.py +2 -2
- ksadk/deployment/providers/serverless.py +1 -1
- ksadk/events/_v1_compat/projection.py +2 -0
- ksadk/events/adapters/_codex_validators.py +18 -7
- ksadk/events/adapters/codex.py +190 -0
- ksadk/events/adapters/langgraph.py +15 -1
- ksadk/events/canonical_store.py +3 -1
- ksadk/events/projections.py +1 -1
- ksadk/harness/__init__.py +45 -35
- ksadk/harness/config.py +2 -2
- ksadk/harness/runtime.py +75 -16
- ksadk/harness/tools.py +38 -13
- ksadk/interaction/provider.py +1 -0
- ksadk/interaction/providers/langgraph.py +1 -0
- ksadk/kernel/bootstrap.py +28 -4
- ksadk/kernel/contract_fingerprints.py +5 -4
- ksadk/kernel/contracts.py +8 -0
- ksadk/kernel/control.py +1 -0
- ksadk/kernel/ingress.py +36 -2
- ksadk/kernel/memory_store.py +1 -0
- ksadk/kernel/postgres_store.py +1 -0
- ksadk/kernel/sqlite_store.py +28 -0
- ksadk/kernel/store.py +3 -0
- ksadk/kernel/worker.py +76 -10
- ksadk/knowledge_base/client.py +57 -27
- ksadk/mcp_runtime/__init__.py +12 -4
- ksadk/memory/adk/backends/sdk_ltm_backend.py +161 -41
- ksadk/memory/adk/resilient_session_service.py +25 -17
- ksadk/memory/adk/short_term_memory.py +26 -9
- ksadk/memory/models.py +7 -4
- ksadk/memory/provider_resolver.py +3 -0
- ksadk/memory/providers/local_sqlite.py +7 -0
- ksadk/model_proxy/server.py +10 -5
- ksadk/plugins/__init__.py +171 -0
- ksadk/plugins/artifacts.py +275 -0
- ksadk/plugins/bridges/__init__.py +47 -0
- ksadk/plugins/bridges/codex.py +659 -0
- ksadk/plugins/bridges/dsh.py +1300 -0
- ksadk/plugins/builtins.py +746 -0
- ksadk/plugins/bundle.py +246 -0
- ksadk/plugins/bundle_security.py +191 -0
- ksadk/plugins/codex_manifest.py +983 -0
- ksadk/plugins/composition.py +537 -0
- ksadk/plugins/context_contributor.py +437 -0
- ksadk/plugins/contracts.py +569 -0
- ksadk/plugins/delivery.py +153 -0
- ksadk/plugins/dsh_installation_digest.py +71 -0
- ksadk/plugins/dsh_toolchain.py +1024 -0
- ksadk/plugins/ecosystem_bridge.py +1105 -0
- ksadk/plugins/ecosystem_probe.py +191 -0
- ksadk/plugins/host.py +787 -0
- ksadk/plugins/kernel_adapter.py +205 -0
- ksadk/plugins/providers/__init__.py +108 -0
- ksadk/plugins/providers/bundles/dsh-knowledge/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-knowledge/index.mjs +53 -0
- ksadk/plugins/providers/bundles/dsh-knowledge/package.json +16 -0
- ksadk/plugins/providers/bundles/dsh-memory/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-memory/index.mjs +175 -0
- ksadk/plugins/providers/bundles/dsh-memory/package.json +16 -0
- ksadk/plugins/providers/bundles/dsh-platform-resources/client.mjs +166 -0
- ksadk/plugins/providers/bundles/dsh-platform-resources/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-platform-resources/index.mjs +9 -0
- ksadk/plugins/providers/bundles/dsh-platform-resources/package.json +12 -0
- ksadk/plugins/providers/bundles/dsh-skill-center/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-skill-center/index.mjs +125 -0
- ksadk/plugins/providers/bundles/dsh-skill-center/package.json +16 -0
- ksadk/plugins/providers/bundles/ksadk-codex/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +18 -0
- ksadk/plugins/providers/bundles/ksadk-codex/package.json +19 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/index.mjs +870 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +27 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-studio/client.js +92 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-studio/index.mjs +15 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-studio/package.json +7 -0
- ksadk/plugins/providers/bundles/ksadk-harness/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +19 -0
- ksadk/plugins/providers/bundles/ksadk-harness/package.json +19 -0
- ksadk/plugins/providers/codex.py +988 -0
- ksadk/plugins/providers/codex_dsh.py +83 -0
- ksadk/plugins/providers/codex_native.py +368 -0
- ksadk/plugins/providers/codex_turn.py +301 -0
- ksadk/plugins/providers/dsh.py +951 -0
- ksadk/plugins/providers/dsh_capabilities.py +1389 -0
- ksadk/plugins/providers/dsh_descriptor_host.py +226 -0
- ksadk/plugins/providers/dsh_mcp.py +467 -0
- ksadk/plugins/providers/harness.py +632 -0
- ksadk/plugins/providers/harness_dsh.py +91 -0
- ksadk/plugins/providers/legacy.py +215 -0
- ksadk/plugins/providers/legacy_catalog.py +100 -0
- ksadk/plugins/providers/mcp_projection.py +150 -0
- ksadk/plugins/providers/platform_resources.py +657 -0
- ksadk/plugins/providers/shipped_dsh.py +370 -0
- ksadk/plugins/resolver.py +338 -0
- ksadk/plugins/subagent_providers/__init__.py +12 -0
- ksadk/plugins/subagent_providers/codex.py +443 -0
- ksadk/plugins/subagents.py +333 -0
- ksadk/resource_runtime/__init__.py +4 -0
- ksadk/resource_runtime/broker.py +616 -0
- ksadk/resource_runtime/build_artifacts.py +165 -0
- ksadk/resource_runtime/contracts.py +138 -0
- ksadk/resource_runtime/discovery_receipts.py +100 -0
- ksadk/resource_runtime/discovery_skills.py +172 -0
- ksadk/resource_runtime/errors.py +6 -0
- ksadk/resource_runtime/ipc.py +142 -0
- ksadk/resource_runtime/kernel_approval.py +165 -0
- ksadk/resource_runtime/knowledge.py +114 -0
- ksadk/resource_runtime/langgraph.py +94 -0
- ksadk/resource_runtime/leases.py +191 -0
- ksadk/resource_runtime/managed_projection.py +186 -0
- ksadk/resource_runtime/mcp_server.py +138 -0
- ksadk/resource_runtime/memory_provider.py +318 -0
- ksadk/resource_runtime/memory_receipts.py +34 -0
- ksadk/resource_runtime/operation_ledger.py +211 -0
- ksadk/resource_runtime/plugin_config.py +48 -0
- ksadk/resource_runtime/policy_authorization.py +54 -0
- ksadk/resource_runtime/process.py +110 -0
- ksadk/resource_runtime/skill_artifacts.py +153 -0
- ksadk/resource_runtime/skill_runtime.py +42 -0
- ksadk/resource_runtime/skill_workspace.py +118 -0
- ksadk/resource_runtime/skills.py +215 -0
- ksadk/resource_runtime/snapshots.py +180 -0
- ksadk/resource_runtime/socket_server.py +103 -0
- ksadk/resource_runtime/supervisor.py +380 -0
- ksadk/resource_runtime/worker.py +504 -0
- ksadk/runners/_langgraph_runner_streams.py +74 -6
- ksadk/runners/adk_runner.py +149 -11
- ksadk/runners/base_runner.py +29 -1
- ksadk/runners/langgraph_runner.py +475 -145
- ksadk/runtime/_runner_adapter/stream_mapping.py +193 -60
- ksadk/runtime/adapter.py +3 -0
- ksadk/runtime/conversation_execution.py +92 -16
- ksadk/runtime/executor.py +78 -2
- ksadk/runtime/factory.py +30 -200
- ksadk/runtime/framework_adapters.py +41 -0
- ksadk/runtime/preprocessing.py +10 -2
- ksadk/runtime/runner_adapter.py +78 -14
- ksadk/runtime_context.py +40 -2
- ksadk/sandbox/__init__.py +2 -1
- ksadk/sandbox/backends/e2b.py +52 -11
- ksadk/sandbox/backends/local_process.py +9 -0
- ksadk/sandbox/base.py +2 -0
- ksadk/sandbox/e2b_connection.py +66 -0
- ksadk/sandbox/factory.py +72 -0
- ksadk/scheduler/__init__.py +18 -0
- ksadk/scheduler/calendar.py +102 -0
- ksadk/scheduler/contracts.py +254 -0
- ksadk/scheduler/dispatcher.py +129 -0
- ksadk/scheduler/engine.py +416 -0
- ksadk/scheduler/sqlite_store.py +581 -0
- ksadk/server/composition.py +2 -0
- ksadk/server/factory.py +5 -0
- ksadk/server/persistence_capability.py +516 -0
- ksadk/server/routes/control.py +210 -46
- ksadk/server/routes/dependencies.py +15 -0
- ksadk/server/routes/models.py +47 -4
- ksadk/server/routes/projection.py +252 -12
- ksadk/server/routes/sessions.py +284 -107
- ksadk/server/routes/streaming.py +43 -9
- ksadk/server/static/assets/{ArtifactsPanel-DSU1sWD_.js → ArtifactsPanel-CGbWlMNh.js} +1 -1
- ksadk/server/static/assets/{CodeBlock-DOH6MVcn.js → CodeBlock-b4C7upmO.js} +3 -3
- ksadk/server/static/assets/{MathMessageMarkdown-BL8my1R2.js → MathMessageMarkdown-DbdW5A4_.js} +4 -4
- ksadk/server/static/assets/{MermaidBlock-Dz4IP-Tx.js → MermaidBlock-BEBN4Ksz.js} +6 -6
- ksadk/server/static/assets/{NativeTerminalPanel-DUrK0JpZ.js → NativeTerminalPanel-zvL-WpAn.js} +1 -1
- ksadk/server/static/assets/{abnfDiagram-VCTEODGH-g20pFzNV.js → abnfDiagram-VCTEODGH-BYafW7Za.js} +1 -1
- ksadk/server/static/assets/{arc-C4FzinUA.js → arc-bTohInsS.js} +1 -1
- ksadk/server/static/assets/architecture-7GRP2DOG-BW5UtSnx.js +1 -0
- ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-DpIqL5h4.js → architectureDiagram-5GKGNRK7-Ch5Lbzsi.js} +1 -1
- ksadk/server/static/assets/{blockDiagram-NRAW4CY4-BjkljTNz.js → blockDiagram-NRAW4CY4-kqF4MDOG.js} +1 -1
- ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-Dk_ieq2X.js → c4Diagram-UCG6FXSJ-8uSRIODv.js} +1 -1
- ksadk/server/static/assets/channel-CF5Up3hQ.js +1 -0
- ksadk/server/static/assets/chunk-2Q5K7J3B-KkXX47WI.js +1 -0
- ksadk/server/static/assets/{chunk-5VM5RSS4-BVHAchFb.js → chunk-5VM5RSS4-DkhehZDr.js} +1 -1
- ksadk/server/static/assets/{chunk-F27PBJKO-C-ipQzuS.js → chunk-F27PBJKO-BdXhtPe9.js} +1 -1
- ksadk/server/static/assets/{chunk-G27WJ6UU-C2EyJbIK.js → chunk-G27WJ6UU-DPTpvpwi.js} +1 -1
- ksadk/server/static/assets/{chunk-JWPE2WC7-vYvVJb_M.js → chunk-JWPE2WC7-Pqoh38el.js} +1 -1
- ksadk/server/static/assets/{chunk-LCL6LL3I-BcI6ysPT.js → chunk-LCL6LL3I-DeU00qC-.js} +1 -1
- ksadk/server/static/assets/{chunk-POPQ4Y6H-C030x_Z1.js → chunk-POPQ4Y6H-CzxScFkr.js} +1 -1
- ksadk/server/static/assets/{chunk-RHFEMEQ7-yyGpsz4n.js → chunk-RHFEMEQ7-DpqMx-ux.js} +1 -1
- ksadk/server/static/assets/{chunk-SVP7TREG-BLTlmMU7.js → chunk-SVP7TREG-C6t0SypQ.js} +1 -1
- ksadk/server/static/assets/{chunk-XXDRQBXY-C_32ArgP.js → chunk-XXDRQBXY-DVaeafZk.js} +1 -1
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-Cz81acRQ.js +1 -0
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Cz81acRQ.js +1 -0
- ksadk/server/static/assets/{cose-bilkent-JH36ORCC-9YQYwdl0.js → cose-bilkent-JH36ORCC-Bf9D3tzJ.js} +1 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-DVWs8a2t.js +1 -0
- ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-ErLF5N13.js → cynefinDiagram-5FMLGOSQ-B9cY3iTz.js} +1 -1
- ksadk/server/static/assets/{dagre-3AP2YEHR-DFiQF-6f.js → dagre-3AP2YEHR-CSwlx3CB.js} +1 -1
- ksadk/server/static/assets/{dagre-BuhGnRI1.js → dagre-UBpgon5q.js} +1 -1
- ksadk/server/static/assets/{diagram-S7CK7UJ4-Bt1v8-GC.js → diagram-S7CK7UJ4-C9akhN9a.js} +1 -1
- ksadk/server/static/assets/{diagram-UQ7AKVKN-DSCxJdBK.js → diagram-UQ7AKVKN-CgedhTPI.js} +1 -1
- ksadk/server/static/assets/{diagram-VSXAHHWV-DHfYwp_9.js → diagram-VSXAHHWV-Cjucz5BY.js} +1 -1
- ksadk/server/static/assets/{diagram-VX7I27RA-DdzD-4Le.js → diagram-VX7I27RA-Dd4Vleyn.js} +1 -1
- ksadk/server/static/assets/{diagram-Z3DM3KII-Du-nAJ9F.js → diagram-Z3DM3KII-CZ2jGtYW.js} +1 -1
- ksadk/server/static/assets/{dist-B7seoj3d.js → dist-B2_CVgKv.js} +1 -1
- ksadk/server/static/assets/{dist-CSh_DE14.js → dist-B3FR1SKK.js} +1 -1
- ksadk/server/static/assets/{dist-DUX-id_F.js → dist-BIr4DSRq.js} +1 -1
- ksadk/server/static/assets/{dist-C_wsv-Qd.js → dist-BgV_owcB.js} +1 -1
- ksadk/server/static/assets/{dist-W-TIVntx.js → dist-Bj730Ib4.js} +1 -1
- ksadk/server/static/assets/{dist-BytlxIDT.js → dist-BnaTiyzN.js} +1 -1
- ksadk/server/static/assets/{dist-CXYYBw3_.js → dist-C1NMAY5a.js} +1 -1
- ksadk/server/static/assets/{dist-dDdADKFA.js → dist-C5_ZAZsG.js} +1 -1
- ksadk/server/static/assets/{dist-BVDffZ0U.js → dist-CB9iJrvg.js} +1 -1
- ksadk/server/static/assets/{dist-Bf2M8m3N.js → dist-CFzsn6BG.js} +1 -1
- ksadk/server/static/assets/{dist-ngtN0DJB.js → dist-Cf125P_m.js} +1 -1
- ksadk/server/static/assets/{dist-BE7bu-DL.js → dist-ClYUxfeK.js} +1 -1
- ksadk/server/static/assets/{dist-DNp6rLRA.js → dist-DFD6Qa6T.js} +1 -1
- ksadk/server/static/assets/{dist-BX8z72IC.js → dist-DVCOWtha.js} +1 -1
- ksadk/server/static/assets/{dist-dydu68Fl.js → dist-D_ctSS2i.js} +1 -1
- ksadk/server/static/assets/{dist-ClxGviKw.js → dist-DiixqL0J.js} +1 -1
- ksadk/server/static/assets/{dist-BjU6y-A2.js → dist-DoVSwoDb.js} +1 -1
- ksadk/server/static/assets/{dist-Dq9gLD7L.js → dist-DvFK7p5S.js} +1 -1
- ksadk/server/static/assets/{dist-8hqcx0sU.js → dist-QfkEHOlb.js} +1 -1
- ksadk/server/static/assets/{dist-CttYUqzS.js → dist-btbmmX5O.js} +1 -1
- ksadk/server/static/assets/{dist-DmldrHd_.js → dist-fBO2v5Kt.js} +1 -1
- ksadk/server/static/assets/{dist-DnfXs8Vn.js → dist-ufY3F5p6.js} +1 -1
- ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-Da9C9NO1.js → ebnfDiagram-PWID7BFC-Ci8NqqZu.js} +1 -1
- ksadk/server/static/assets/{erDiagram-SSCWMZ5O-EAGqqR79.js → erDiagram-SSCWMZ5O-CCIOhLZG.js} +1 -1
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-CQqR2hg3.js +1 -0
- ksadk/server/static/assets/flowDiagram-A5DVABFB-DDRRbGPm.js +1 -0
- ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-DqJsKb59.js → ganttDiagram-EL5Y4UJY-Cp_r9Hb6.js} +1 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-fgWEf7UD.js +1 -0
- ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-B6g4dtDi.js → gitGraphDiagram-WWUBYQGX-Dlhc8Wr8.js} +1 -1
- ksadk/server/static/assets/index-DcTML1Up.css +2 -0
- ksadk/server/static/assets/index-Dh2XHqPK.js +244 -0
- ksadk/server/static/assets/info-A6RAGUB7-BUecLTdt.js +1 -0
- ksadk/server/static/assets/{infoDiagram-RXCK75RN-Djm_nbd5.js → infoDiagram-RXCK75RN-CO0rRTRA.js} +1 -1
- ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-DWya9SG2.js → ishikawaDiagram-5VMMS53U-CHiaedSS.js} +1 -1
- ksadk/server/static/assets/{journeyDiagram-EYS64GPL-DutxhSNI.js → journeyDiagram-EYS64GPL-CHcCIB09.js} +1 -1
- ksadk/server/static/assets/{kanban-definition-3QL26DDD-DJdOF8Fm.js → kanban-definition-3QL26DDD-CJ_ebBZf.js} +1 -1
- ksadk/server/static/assets/{katex-vFWytM5c.js → katex-B4weu383.js} +1 -1
- ksadk/server/static/assets/{linear-BHjG8b-J.js → linear-V-MgYHW1.js} +1 -1
- ksadk/server/static/assets/{mermaid-parser.core-KGSy4jWT.js → mermaid-parser.core-CBijEX_c.js} +2 -2
- ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-9-HC88D4.js → mindmap-definition-FBJOCRG2-Bc-pQvpp.js} +1 -1
- ksadk/server/static/assets/packet-AYTQ26CC-BeW-btFv.js +1 -0
- ksadk/server/static/assets/{pegDiagram-XKGWAZYB-DrEZd4fD.js → pegDiagram-XKGWAZYB-D7genGLl.js} +1 -1
- ksadk/server/static/assets/pie-WAS4IAKB-X0xh4SaT.js +1 -0
- ksadk/server/static/assets/{pieDiagram-E7YTZNPT-DpjqOFFp.js → pieDiagram-E7YTZNPT-Bxj32zwD.js} +1 -1
- ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-BiNhgOXX.js → quadrantDiagram-AXDQQJYC-BURv2mGh.js} +1 -1
- ksadk/server/static/assets/radar-RG4KPBEZ-DzRMSqjd.js +1 -0
- ksadk/server/static/assets/railroad-74A4TZTK-Cc44icX-.js +1 -0
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-D6S4BdV-.js +1 -0
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-vD3aVE2o.js +1 -0
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-CYbW_b4T.js +1 -0
- ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-_Y3Ojg6G.js → railroadDiagram-O6MQD6OU-CCsh3avW.js} +1 -1
- ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-DeCFdg9K.js → requirementDiagram-EFPCY7ZU-_FRRBKEd.js} +1 -1
- ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-CPH75rhw.js → sankeyDiagram-P5KCCOFB-C-gr2o9M.js} +1 -1
- ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-OEpQQdr4.js → sequenceDiagram-WJ2MYXX4-D97NmfKg.js} +1 -1
- ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-heUErzhI.js → sizeCapture-X5ZJPWSS-DjrPC5FX.js} +1 -1
- ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-DvA3jSMB.js → stateDiagram-HBIQ2CUA-DzMNg1hh.js} +1 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BIcjKFhF.js +1 -0
- ksadk/server/static/assets/{swimlanes-XN3QIQJK-CR-dfN_t.js → swimlanes-XN3QIQJK-Cssf_CsU.js} +1 -1
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-tq3K3Ybl.js +8 -0
- ksadk/server/static/assets/{timeline-definition-24CTP7MA-DAVJf1TX.js → timeline-definition-24CTP7MA-BWTHzyS1.js} +1 -1
- ksadk/server/static/assets/treeView-Q6P3EWNA-DBXt3GdU.js +1 -0
- ksadk/server/static/assets/treemap-WGGIJYW6-DrCy4E_l.js +1 -0
- ksadk/server/static/assets/{vennDiagram-4TSXK5OY-DwM8eDkh.js → vennDiagram-4TSXK5OY-BSKgJsmR.js} +1 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-CefhOliM.js +1 -0
- ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-DZL-Zz2t.js → wardleyDiagram-VM6X3IG4-eflHNoaZ.js} +1 -1
- ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js → xychartDiagram-S5SC5T6Z-eYqrQ-v4.js} +1 -1
- ksadk/server/static/index.html +2 -2
- ksadk/session_context.py +66 -0
- ksadk/sessions/__init__.py +11 -21
- ksadk/sessions/_local_service_sync.py +263 -1
- ksadk/sessions/base.py +176 -0
- ksadk/sessions/errors.py +4 -0
- ksadk/sessions/in_memory.py +309 -19
- ksadk/sessions/local_service.py +83 -1
- ksadk/sessions/persistence.py +275 -0
- ksadk/sessions/postgres_service.py +358 -0
- ksadk/sessions/resilience.py +8 -0
- ksadk/sessions/resilient.py +362 -4
- ksadk/sessions/topology.py +135 -0
- ksadk/skills/models.py +26 -4
- ksadk/skills/package_store.py +186 -38
- ksadk/skills/runtime/agent.py +31 -6
- ksadk/skills/runtime/artifact_delivery.py +139 -0
- ksadk/skills/runtime/backends/e2b.py +98 -6
- ksadk/skills/runtime/backends/local.py +73 -8
- ksadk/skills/runtime/base.py +3 -0
- ksadk/skills/runtime/executor.py +2 -0
- ksadk/skills/runtime/loader.py +10 -2
- ksadk/skills/runtime/pinned.py +114 -0
- ksadk/skills/runtime/request.py +31 -0
- ksadk/skills/service_client.py +211 -24
- ksadk/studio/agent_lifecycle.py +26 -20
- ksadk/studio/api.py +714 -90
- ksadk/studio/api_catalog_routes.py +23 -0
- ksadk/studio/api_contracts.py +34 -1
- ksadk/studio/api_plugin_routes.py +911 -0
- ksadk/studio/api_resource_connections.py +183 -0
- ksadk/studio/attachment_store.py +187 -0
- ksadk/studio/authoring.py +10 -4
- ksadk/studio/authoring_coordinator.py +31 -16
- ksadk/studio/builder.py +199 -43
- ksadk/studio/cloud.py +346 -104
- ksadk/studio/cloud_shared_web.py +565 -0
- ksadk/studio/codex_agent_service.py +140 -27
- ksadk/studio/codex_builder.py +294 -16
- ksadk/studio/codex_credentials.py +90 -0
- ksadk/studio/codex_manifest.py +51 -4
- ksadk/studio/codex_plugin_store.py +746 -0
- ksadk/studio/codex_provider_build.py +231 -0
- ksadk/studio/codex_run.py +200 -29
- ksadk/studio/compatibility_report.py +456 -0
- ksadk/studio/compiler.py +84 -15
- ksadk/studio/contracts.py +249 -4
- ksadk/studio/dsh_application.py +137 -0
- ksadk/studio/dsh_capability_service.py +1107 -0
- ksadk/studio/dsh_models.py +59 -0
- ksadk/studio/dsh_provider_registration.py +1075 -0
- ksadk/studio/event_store.py +54 -6
- ksadk/studio/framework_run.py +37 -4
- ksadk/studio/hosted_kernel.py +89 -14
- ksadk/studio/mcp_runtime.py +11 -3
- ksadk/studio/model_client.py +2 -2
- ksadk/studio/operations.py +12 -2
- ksadk/studio/plugin_composition.py +468 -0
- ksadk/studio/plugin_kernel_adapter.py +28 -0
- ksadk/studio/plugin_runtime.py +831 -0
- ksadk/studio/resource_authority.py +637 -0
- ksadk/studio/resource_binding_validation.py +77 -0
- ksadk/studio/resource_build_admission.py +196 -0
- ksadk/studio/resource_build_materializer.py +149 -0
- ksadk/studio/resource_catalog.py +149 -3
- ksadk/studio/resource_connections.py +220 -0
- ksadk/studio/run_service.py +1144 -96
- ksadk/studio/runtime_source.py +24 -8
- ksadk/studio/scheduler_assistant.py +317 -0
- ksadk/studio/scheduler_runtime.py +383 -0
- ksadk/studio/scheduler_service.py +214 -0
- ksadk/studio/service.py +1131 -95
- ksadk/studio/shared_web.py +610 -87
- ksadk/studio/soul.py +52 -0
- ksadk/studio/static/assets/CodeBlock-DCUUY0PL-BLjA7kbS.js +41 -0
- ksadk/studio/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- ksadk/studio/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--BEOyPC3w.css +1 -0
- ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--CUYIXwgI.js +8 -0
- ksadk/studio/static/assets/MermaidBlock-DBFTztfQ-BTYKWEbD.js +44 -0
- ksadk/studio/static/assets/PrismRenderer-wiXRHURw.js +3 -0
- ksadk/studio/static/assets/abnfDiagram-VCTEODGH-CLETGjKq.js +1 -0
- ksadk/studio/static/assets/arc-Pry-7G1_.js +1 -0
- ksadk/studio/static/assets/architecture-7GRP2DOG-hXMiO_AU.js +1 -0
- ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-B5EQysk6.js +36 -0
- ksadk/studio/static/assets/array-BifhSqXX.js +1 -0
- ksadk/studio/static/assets/blockDiagram-I7D4REHJ-CFmPl1de.js +129 -0
- ksadk/studio/static/assets/c4Diagram-7LVT6UL2-BRrGu8qt.js +38 -0
- ksadk/studio/static/assets/channel-BqO-gtEw.js +1 -0
- ksadk/studio/static/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
- ksadk/studio/static/assets/chunk-4HAMMTFA-D220vUtq.js +62 -0
- ksadk/studio/static/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
- ksadk/studio/static/assets/chunk-75Z2AOVW-C8lLv_qc.js +2 -0
- ksadk/studio/static/assets/chunk-DU6HZSFF-C4DtVpCu.js +128 -0
- ksadk/studio/static/assets/chunk-F27PBJKO-Cpw14SNG.js +1 -0
- ksadk/studio/static/assets/chunk-FOHPRMQF-DHwB1DNv.js +161 -0
- ksadk/studio/static/assets/chunk-GMAD6QVW-DiQA-u2N.js +72 -0
- ksadk/studio/static/assets/chunk-GVQU2GXP-DUdNBUCi.js +1 -0
- ksadk/studio/static/assets/chunk-IMKFNOWR-BSlbjT_b.js +231 -0
- ksadk/studio/static/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
- ksadk/studio/static/assets/chunk-L3NEJ4N5-Db8Ab22W.js +1 -0
- ksadk/studio/static/assets/chunk-OSK3NFVY-M2m6G3j4.js +10 -0
- ksadk/studio/static/assets/chunk-P2QGCYS3-DezaQxiK.js +1 -0
- ksadk/studio/static/assets/chunk-POPQ4Y6H-DOpufJ3t.js +1 -0
- ksadk/studio/static/assets/chunk-PWAF6VOD-CfLb1gSc.js +1 -0
- ksadk/studio/static/assets/chunk-SHT3W25Y-DAyIVp5H.js +168 -0
- ksadk/studio/static/assets/chunk-SVP7TREG-DulomOrS.js +88 -0
- ksadk/studio/static/assets/chunk-TICWLB2K-bHJYoflj.js +206 -0
- ksadk/studio/static/assets/chunk-XXDRQBXY-7PcdR2B1.js +1 -0
- ksadk/studio/static/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
- ksadk/studio/static/assets/classDiagram-ZZMXUADV-D_bW8JjA.js +1 -0
- ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-D_bW8JjA.js +1 -0
- ksadk/studio/static/assets/cose-bilkent-JH36ORCC-snL88wkX.js +1 -0
- ksadk/studio/static/assets/cynefin-OW5HDTMX-Bd1YhRo1.js +1 -0
- ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-BBrIG_mI.js +62 -0
- ksadk/studio/static/assets/cytoscape.esm-CGd-uY3x.js +321 -0
- ksadk/studio/static/assets/dagre-GXQ25YYZ-DtF1nGdY.js +4 -0
- ksadk/studio/static/assets/dagre-PrKaheQc.js +1 -0
- ksadk/studio/static/assets/defaultLocale-BFoDCU3G.js +1 -0
- ksadk/studio/static/assets/diagram-S7CK7UJ4-0BZ98mya.js +30 -0
- ksadk/studio/static/assets/diagram-UQ7AKVKN-6mLKEo6L.js +41 -0
- ksadk/studio/static/assets/diagram-VSXAHHWV-CJBIaiZ2.js +3 -0
- ksadk/studio/static/assets/diagram-VX7I27RA-BohLEE1C.js +24 -0
- ksadk/studio/static/assets/diagram-Z3DM3KII-D8KIGonG.js +24 -0
- ksadk/studio/static/assets/dist-v5Q1xZ2K.js +1 -0
- ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-C99HU61t.js +1 -0
- ksadk/studio/static/assets/erDiagram-RLTQ6QDP-DLGry2Ap.js +99 -0
- ksadk/studio/static/assets/eventmodeling-NTZA5JFV-B1_5Ac8j.js +1 -0
- ksadk/studio/static/assets/flowDiagram-HODETNUW-DD5hmicn.js +1 -0
- ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BPJrVLSG.js +292 -0
- ksadk/studio/static/assets/gitGraph-4MIJSDKK-Cy_ZQBGi.js +1 -0
- ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-CZCUz4MT.js +106 -0
- ksadk/studio/static/assets/graphlib-DS17s2tU.js +1 -0
- ksadk/studio/static/assets/index-CeHL9ARV.css +2 -0
- ksadk/studio/static/assets/index-D9QEcVpL.js +320 -0
- ksadk/studio/static/assets/info-A6RAGUB7-DBzDQB_I.js +1 -0
- ksadk/studio/static/assets/infoDiagram-27XIBGKW-B-sq07Hi.js +2 -0
- ksadk/studio/static/assets/init-C-OQMol4.js +1 -0
- ksadk/studio/static/assets/ishikawaDiagram-5VMMS53U-CljI2wyf.js +70 -0
- ksadk/studio/static/assets/journeyDiagram-3NMN7TZE-D50Fo2sL.js +139 -0
- ksadk/studio/static/assets/kanban-definition-UXKFOSKX-DimfOTam.js +89 -0
- ksadk/studio/static/assets/katex-DhON-x74.js +257 -0
- ksadk/studio/static/assets/line-CX5BOOUP.js +1 -0
- ksadk/studio/static/assets/linear-BCxN9JLv.js +1 -0
- ksadk/studio/static/assets/mermaid-parser.core-BdCz8fkS.js +7 -0
- ksadk/studio/static/assets/mindmap-definition-YA3MSWOX-Bizzqy5R.js +96 -0
- ksadk/studio/static/assets/ordinal-BDEzSJ7C.js +1 -0
- ksadk/studio/static/assets/packet-AYTQ26CC-gPln-_kG.js +1 -0
- ksadk/studio/static/assets/path-fybaL0A-.js +1 -0
- ksadk/studio/static/assets/pegDiagram-XKGWAZYB-Dy3fB-gW.js +1 -0
- ksadk/studio/static/assets/pie-WAS4IAKB-qZdHMr7B.js +1 -0
- ksadk/studio/static/assets/pieDiagram-E7YTZNPT-B9mrFSDF.js +39 -0
- ksadk/studio/static/assets/quadrantDiagram-AXDQQJYC-NzUfCbMR.js +7 -0
- ksadk/studio/static/assets/radar-RG4KPBEZ-BZlnaea9.js +1 -0
- ksadk/studio/static/assets/railroad-74A4TZTK-Ce3__H9c.js +1 -0
- ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-DqQn7EzD.js +1 -0
- ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-B55kCA8F.js +1 -0
- ksadk/studio/static/assets/railroad-peg-WCYAUIDC-DfQnvkHd.js +1 -0
- ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-DnhMjZCk.js +1 -0
- ksadk/studio/static/assets/requirementDiagram-BXWQKSXE-BF3d103U.js +84 -0
- ksadk/studio/static/assets/rolldown-runtime-Dy4uBu1J-DK3Fl9T5.js +1 -0
- ksadk/studio/static/assets/rough.esm-Dy-Kn_BL.js +1 -0
- ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-Bo-JTwt0.js +40 -0
- ksadk/studio/static/assets/sequenceDiagram-WJ2MYXX4-Dh4wZtUm.js +162 -0
- ksadk/studio/static/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
- ksadk/studio/static/assets/src-SFn9St9H.js +1 -0
- ksadk/studio/static/assets/stateDiagram-D77RDMKH-DH774G6d.js +1 -0
- ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-DZvVWPBo.js +1 -0
- ksadk/studio/static/assets/swimlanes-42K2YHIH-Bl13OvTX.js +1 -0
- ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-BnFOTALJ.js +8 -0
- ksadk/studio/static/assets/timeline-definition-24CTP7MA-DxmSSjRB.js +120 -0
- ksadk/studio/static/assets/treeView-Q6P3EWNA-D5Nn9Swz.js +1 -0
- ksadk/studio/static/assets/treemap-WGGIJYW6-CgHgnQhE.js +1 -0
- ksadk/studio/static/assets/vennDiagram-4TSXK5OY-B9QEXcJq.js +34 -0
- ksadk/studio/static/assets/wardley-WFR3VGLG-DXrK2RRY.js +1 -0
- ksadk/studio/static/assets/wardleyDiagram-VM6X3IG4-Ba1AOWoe.js +78 -0
- ksadk/studio/static/assets/xychartDiagram-S5SC5T6Z-Cr5pt5Y-.js +7 -0
- ksadk/studio/static/index.html +2 -2
- ksadk/studio/validator.py +1 -1
- ksadk/studio/workspace.py +1 -0
- ksadk/version.py +1 -1
- ksadk_runtime_common/workspace_files/path_utils.py +41 -0
- agentengine_sdk_python-0.8.2.dist-info/RECORD +0 -778
- ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +0 -1
- ksadk/server/static/assets/channel-4cQHKtx1.js +0 -1
- ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +0 -1
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +0 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +0 -1
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +0 -1
- ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +0 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +0 -1
- ksadk/server/static/assets/index-8ipRcQ-M.js +0 -240
- ksadk/server/static/assets/index-ByFCqjlh.css +0 -2
- ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +0 -1
- ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +0 -1
- ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +0 -1
- ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +0 -1
- ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +0 -1
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +0 -1
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +0 -1
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +0 -1
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +0 -8
- ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +0 -1
- ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +0 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +0 -1
- ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +0 -3
- ksadk/studio/static/assets/index-BLpcdrgW.css +0 -1
- ksadk/studio/static/assets/index-CYekR2Xv.js +0 -260
- {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/WHEEL +0 -0
- {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/top_level.txt +0 -0
ksadk/studio/api.py
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
|
+
import base64
|
|
6
7
|
import hmac
|
|
7
8
|
import json
|
|
8
9
|
import os
|
|
@@ -18,8 +19,18 @@ from fastapi.responses import FileResponse, JSONResponse, StreamingResponse
|
|
|
18
19
|
from fastapi.staticfiles import StaticFiles
|
|
19
20
|
from starlette.background import BackgroundTask
|
|
20
21
|
|
|
22
|
+
from ksadk.api.client import AgentEngineAPIError
|
|
23
|
+
from ksadk.conversations.contracts import (
|
|
24
|
+
ConversationAttachmentPart,
|
|
25
|
+
ConversationTextPart,
|
|
26
|
+
validate_conversation_input,
|
|
27
|
+
)
|
|
28
|
+
from ksadk.conversations.projector import project_conversation_item
|
|
29
|
+
from ksadk.events.canonical import parse_runtime_event_lenient
|
|
30
|
+
from ksadk.scheduler.contracts import ScheduledTask
|
|
21
31
|
from ksadk.studio.api_catalog_routes import register_catalog_routes
|
|
22
32
|
from ksadk.studio.api_contracts import (
|
|
33
|
+
AgentScheduleRequest,
|
|
23
34
|
AuthoringCommitRequest,
|
|
24
35
|
BuildRequest,
|
|
25
36
|
CloudAgentVersionRollbackRequest,
|
|
@@ -27,6 +38,7 @@ from ksadk.studio.api_contracts import (
|
|
|
27
38
|
CloudChatMessageRequest,
|
|
28
39
|
ContextPreviewRequest,
|
|
29
40
|
ConversationAuthoringRequest,
|
|
41
|
+
ConversationTurnRequest,
|
|
30
42
|
CreateAgentRequest,
|
|
31
43
|
ImportRootRequest,
|
|
32
44
|
InteractionSubmitRequest,
|
|
@@ -65,6 +77,9 @@ from ksadk.studio.api_helpers import (
|
|
|
65
77
|
sse as _sse,
|
|
66
78
|
)
|
|
67
79
|
from ksadk.studio.api_memory_routes import register_memory_routes
|
|
80
|
+
from ksadk.studio.api_plugin_routes import register_plugin_routes
|
|
81
|
+
from ksadk.studio.api_resource_connections import register_resource_connection_routes
|
|
82
|
+
from ksadk.studio.cloud_shared_web import CloudSharedWebBridge, cloud_chat_target, is_cloud_agent_id
|
|
68
83
|
from ksadk.studio.codex_manifest import CodexAgentManifest
|
|
69
84
|
from ksadk.studio.contracts import (
|
|
70
85
|
AgentAppearance,
|
|
@@ -85,6 +100,113 @@ _PUBLIC_API_PATHS = {
|
|
|
85
100
|
}
|
|
86
101
|
_LOCAL_HOSTS = {"127.0.0.1", "::1", "localhost", "testserver"}
|
|
87
102
|
|
|
103
|
+
# RuntimeEvent/v2 itself is snake_case. Some pre-existing cloud SessionEvent
|
|
104
|
+
# projections, however, serialized the *envelope* with the REST camelCase
|
|
105
|
+
# convention. This is a narrow transport normalizer, not a provider payload
|
|
106
|
+
# rewrite: only fields owned by the frozen RuntimeEvent envelope/content
|
|
107
|
+
# contracts are translated before strict parsing.
|
|
108
|
+
_RUNTIME_EVENT_WIRE_ALIASES = {
|
|
109
|
+
"schemaVersion": "schema_version",
|
|
110
|
+
"eventId": "event_id",
|
|
111
|
+
"runId": "run_id",
|
|
112
|
+
"runSeq": "run_seq",
|
|
113
|
+
"scopeId": "scope_id",
|
|
114
|
+
"parentScopeId": "parent_scope_id",
|
|
115
|
+
"eventType": "event_type",
|
|
116
|
+
"itemId": "item_id",
|
|
117
|
+
"itemKind": "item_kind",
|
|
118
|
+
"interactionId": "interaction_id",
|
|
119
|
+
"interactionKind": "interaction_kind",
|
|
120
|
+
"continuationId": "continuation_id",
|
|
121
|
+
"resumeAttemptId": "resume_attempt_id",
|
|
122
|
+
"outputRefs": "output_refs",
|
|
123
|
+
"inputTokens": "input_tokens",
|
|
124
|
+
"outputTokens": "output_tokens",
|
|
125
|
+
"totalTokens": "total_tokens",
|
|
126
|
+
"cachedTokens": "cached_tokens",
|
|
127
|
+
"reasoningTokens": "reasoning_tokens",
|
|
128
|
+
}
|
|
129
|
+
_SOURCE_WIRE_ALIASES = {
|
|
130
|
+
"nativeEventId": "native_event_id",
|
|
131
|
+
"nativeCursor": "native_cursor",
|
|
132
|
+
"nativeRunId": "native_run_id",
|
|
133
|
+
"nativeItemId": "native_item_id",
|
|
134
|
+
}
|
|
135
|
+
_CONTENT_WIRE_ALIASES = {
|
|
136
|
+
"contentType": "content_type",
|
|
137
|
+
"partId": "part_id",
|
|
138
|
+
"callId": "call_id",
|
|
139
|
+
"artifactId": "artifact_id",
|
|
140
|
+
"mimeType": "mime_type",
|
|
141
|
+
"isError": "is_error",
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def _normalize_cloud_runtime_event_wire(value: dict[str, Any]) -> dict[str, Any]:
|
|
146
|
+
"""Normalize only historic REST casing at the RuntimeEvent boundary."""
|
|
147
|
+
|
|
148
|
+
normalized = {_RUNTIME_EVENT_WIRE_ALIASES.get(key, key): item for key, item in value.items()}
|
|
149
|
+
source = normalized.get("source")
|
|
150
|
+
if isinstance(source, dict):
|
|
151
|
+
normalized["source"] = {
|
|
152
|
+
_SOURCE_WIRE_ALIASES.get(key, key): item for key, item in source.items()
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
def normalize_content(content: Any) -> Any:
|
|
156
|
+
if not isinstance(content, dict):
|
|
157
|
+
return content
|
|
158
|
+
return {_CONTENT_WIRE_ALIASES.get(key, key): item for key, item in content.items()}
|
|
159
|
+
|
|
160
|
+
normalized["update"] = normalize_content(normalized.get("update"))
|
|
161
|
+
for key in ("initial", "snapshot"):
|
|
162
|
+
snapshot = normalized.get(key)
|
|
163
|
+
if not isinstance(snapshot, dict):
|
|
164
|
+
continue
|
|
165
|
+
parts = snapshot.get("parts")
|
|
166
|
+
if isinstance(parts, list):
|
|
167
|
+
normalized[key] = {
|
|
168
|
+
**snapshot,
|
|
169
|
+
"parts": [normalize_content(part) for part in parts],
|
|
170
|
+
}
|
|
171
|
+
return normalized
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def _cloud_event_conversation_item(
|
|
175
|
+
event: dict[str, Any], *, session_id: str
|
|
176
|
+
) -> dict[str, Any] | None:
|
|
177
|
+
"""Project a complete cloud RuntimeEvent without inventing a browser item.
|
|
178
|
+
|
|
179
|
+
Cloud SessionEvent history has a compatibility envelope around the runtime
|
|
180
|
+
payload. Keep the source event untouched, but add the same typed
|
|
181
|
+
ConversationItem that local Studio streams use whenever the nested event
|
|
182
|
+
validates against RuntimeEvent/v2. A malformed or older envelope is still
|
|
183
|
+
observable to diagnostics, never guessed into an actionable chat card.
|
|
184
|
+
"""
|
|
185
|
+
|
|
186
|
+
payload = event.get("payload") if isinstance(event.get("payload"), dict) else event
|
|
187
|
+
content = payload.get("content") if isinstance(payload.get("content"), dict) else {}
|
|
188
|
+
candidates = (
|
|
189
|
+
content.get("runtime_event"),
|
|
190
|
+
content.get("runtimeEvent"),
|
|
191
|
+
payload.get("runtime_event"),
|
|
192
|
+
payload.get("runtimeEvent"),
|
|
193
|
+
event.get("runtime_event"),
|
|
194
|
+
event.get("runtimeEvent"),
|
|
195
|
+
)
|
|
196
|
+
raw_event = next((candidate for candidate in candidates if isinstance(candidate, dict)), None)
|
|
197
|
+
if raw_event is None:
|
|
198
|
+
return None
|
|
199
|
+
try:
|
|
200
|
+
runtime_event = parse_runtime_event_lenient(_normalize_cloud_runtime_event_wire(raw_event))
|
|
201
|
+
item = project_conversation_item(
|
|
202
|
+
runtime_event, # type: ignore[arg-type]
|
|
203
|
+
session_id=session_id,
|
|
204
|
+
run_id=runtime_event.run_id,
|
|
205
|
+
)
|
|
206
|
+
except (TypeError, ValueError):
|
|
207
|
+
return None
|
|
208
|
+
return item.model_dump(by_alias=True, exclude_none=True, mode="json")
|
|
209
|
+
|
|
88
210
|
|
|
89
211
|
def create_studio_app(
|
|
90
212
|
root: Path | str,
|
|
@@ -101,9 +223,13 @@ def create_studio_app(
|
|
|
101
223
|
@asynccontextmanager
|
|
102
224
|
async def lifespan(_app: FastAPI) -> AsyncIterator[None]:
|
|
103
225
|
try:
|
|
226
|
+
await studio.start()
|
|
104
227
|
await studio.run_service.recover_interrupted()
|
|
228
|
+
await studio.scheduler.start_if_available()
|
|
105
229
|
yield
|
|
106
230
|
finally:
|
|
231
|
+
await studio.scheduler.stop()
|
|
232
|
+
await studio.aclose()
|
|
107
233
|
studio.credentials.clear_session()
|
|
108
234
|
|
|
109
235
|
app = FastAPI(
|
|
@@ -117,8 +243,88 @@ def create_studio_app(
|
|
|
117
243
|
app.state.studio_service = studio
|
|
118
244
|
app.state.session_token = session_secret
|
|
119
245
|
app.state.csrf_token = csrf_secret
|
|
246
|
+
from ksadk.studio.dsh_models import studio_model_projection
|
|
247
|
+
|
|
248
|
+
studio.dsh_capabilities.model_projection = lambda: studio_model_projection(
|
|
249
|
+
studio.catalog, studio.credentials
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
def _stream_studio_run(
|
|
253
|
+
build_id: str,
|
|
254
|
+
*,
|
|
255
|
+
user_input: str,
|
|
256
|
+
session_id: str | None,
|
|
257
|
+
model: str | None,
|
|
258
|
+
sandbox: str | None,
|
|
259
|
+
reasoning_effort: str | None = None,
|
|
260
|
+
approval_mode: str | None = None,
|
|
261
|
+
collaboration_mode: str | None = None,
|
|
262
|
+
goal_objective: str | None = None,
|
|
263
|
+
runtime_input: Any = None,
|
|
264
|
+
idempotency_key: str,
|
|
265
|
+
) -> StreamingResponse:
|
|
266
|
+
"""Create an observer-only SSE response for one durable Studio run."""
|
|
267
|
+
|
|
268
|
+
queue: asyncio.Queue = asyncio.Queue()
|
|
269
|
+
|
|
270
|
+
def observe(event):
|
|
271
|
+
queue.put_nowait(event)
|
|
272
|
+
|
|
273
|
+
# The Operation owns the runtime task. The SSE response is only one
|
|
274
|
+
# observer, so refreshing or switching chats cannot cancel the Run.
|
|
275
|
+
operation = studio.submit_studio_run(
|
|
276
|
+
build_id,
|
|
277
|
+
user_input,
|
|
278
|
+
session_id=session_id,
|
|
279
|
+
model=model,
|
|
280
|
+
sandbox=sandbox,
|
|
281
|
+
reasoning_effort=reasoning_effort,
|
|
282
|
+
approval_mode=approval_mode,
|
|
283
|
+
collaboration_mode=collaboration_mode,
|
|
284
|
+
goal_objective=goal_objective,
|
|
285
|
+
runtime_input=runtime_input,
|
|
286
|
+
idempotency_key=idempotency_key,
|
|
287
|
+
on_event=observe,
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
async def render():
|
|
291
|
+
while True:
|
|
292
|
+
try:
|
|
293
|
+
event = await asyncio.wait_for(queue.get(), timeout=0.1)
|
|
294
|
+
except TimeoutError:
|
|
295
|
+
event = None
|
|
296
|
+
if event is not None:
|
|
297
|
+
data = json.dumps(
|
|
298
|
+
event.data,
|
|
299
|
+
ensure_ascii=False,
|
|
300
|
+
separators=(",", ":"),
|
|
301
|
+
)
|
|
302
|
+
yield f"id: {event.id}\nevent: {event.type}\ndata: {data}\n\n"
|
|
303
|
+
current = studio.operations.get(operation.id)
|
|
304
|
+
if (
|
|
305
|
+
current.status
|
|
306
|
+
in {
|
|
307
|
+
OperationStatus.SUCCEEDED,
|
|
308
|
+
OperationStatus.FAILED,
|
|
309
|
+
OperationStatus.CANCELLED,
|
|
310
|
+
OperationStatus.INTERRUPTED,
|
|
311
|
+
}
|
|
312
|
+
and queue.empty()
|
|
313
|
+
):
|
|
314
|
+
if current.status == OperationStatus.FAILED:
|
|
315
|
+
data = json.dumps(current.error or {}, ensure_ascii=False)
|
|
316
|
+
yield f"event: run.failed\ndata: {data}\n\n"
|
|
317
|
+
break
|
|
318
|
+
|
|
319
|
+
return StreamingResponse(
|
|
320
|
+
render(),
|
|
321
|
+
media_type="text/event-stream",
|
|
322
|
+
headers={"Cache-Control": "no-store", "X-Accel-Buffering": "no"},
|
|
323
|
+
)
|
|
324
|
+
|
|
120
325
|
static_root = Path(__file__).with_name("static")
|
|
121
326
|
shared_web = StudioSharedWebBridge(studio)
|
|
327
|
+
cloud_web = CloudSharedWebBridge(studio.cloud)
|
|
122
328
|
app.state.shared_web_bridge = shared_web
|
|
123
329
|
app.mount("/static", StaticFiles(directory=static_root), name="studio-static")
|
|
124
330
|
|
|
@@ -212,6 +418,39 @@ def create_studio_app(
|
|
|
212
418
|
async def studio_error_handler(request: Request, exc: StudioError):
|
|
213
419
|
return _error_response(exc, request)
|
|
214
420
|
|
|
421
|
+
@app.exception_handler(AgentEngineAPIError)
|
|
422
|
+
async def agentengine_api_error_handler(request: Request, exc: AgentEngineAPIError):
|
|
423
|
+
http_status = exc.details.get("http_status", 502)
|
|
424
|
+
status_code = (
|
|
425
|
+
http_status if isinstance(http_status, int) and 400 <= http_status < 600 else 502
|
|
426
|
+
)
|
|
427
|
+
return _error_response(
|
|
428
|
+
StudioError(
|
|
429
|
+
"CLOUD_API_ERROR",
|
|
430
|
+
exc.message or "云端服务返回错误",
|
|
431
|
+
status_code=status_code,
|
|
432
|
+
details={"api_code": exc.code, "raw_code": exc.raw_code},
|
|
433
|
+
),
|
|
434
|
+
request,
|
|
435
|
+
)
|
|
436
|
+
|
|
437
|
+
@app.exception_handler(Exception)
|
|
438
|
+
async def generic_error_handler(request: Request, exc: Exception):
|
|
439
|
+
# Catch-all for bare Exception raises from the API client (e.g. HTTP
|
|
440
|
+
# errors, JSON parse failures) so they surface as structured JSON
|
|
441
|
+
# instead of opaque 500s. StudioError and AgentEngineAPIError are
|
|
442
|
+
# handled by their own dedicated handlers above.
|
|
443
|
+
if isinstance(exc, StudioError):
|
|
444
|
+
return _error_response(exc, request)
|
|
445
|
+
return _error_response(
|
|
446
|
+
StudioError(
|
|
447
|
+
"INTERNAL_ERROR",
|
|
448
|
+
"Studio 内部错误,请根据请求 ID 查看本地诊断日志。",
|
|
449
|
+
status_code=500,
|
|
450
|
+
),
|
|
451
|
+
request,
|
|
452
|
+
)
|
|
453
|
+
|
|
215
454
|
@app.exception_handler(RequestValidationError)
|
|
216
455
|
async def validation_error_handler(request: Request, exc: RequestValidationError):
|
|
217
456
|
first = exc.errors()[0] if exc.errors() else {}
|
|
@@ -229,7 +468,13 @@ def create_studio_app(
|
|
|
229
468
|
@app.get("/")
|
|
230
469
|
async def index():
|
|
231
470
|
path = static_root / "index.html"
|
|
232
|
-
|
|
471
|
+
html = path.read_text(encoding="utf-8")
|
|
472
|
+
# Vite filenames are content hashed and index.html is no-store. Keep
|
|
473
|
+
# entry module URLs byte-for-byte identical to their internal imports:
|
|
474
|
+
# adding a query only to the HTML entry makes browsers evaluate that
|
|
475
|
+
# module again when a lazy chunk imports the unversioned URL.
|
|
476
|
+
response = Response(content=html, media_type="text/html")
|
|
477
|
+
response.headers["Cache-Control"] = "no-store"
|
|
233
478
|
if security_enabled:
|
|
234
479
|
response.set_cookie(
|
|
235
480
|
"agentkit_studio_session",
|
|
@@ -272,9 +517,31 @@ def create_studio_app(
|
|
|
272
517
|
async def openai_responses(payload: dict[str, Any]):
|
|
273
518
|
metadata = payload.get("metadata")
|
|
274
519
|
metadata = metadata if isinstance(metadata, dict) else {}
|
|
275
|
-
|
|
520
|
+
agentengine_metadata = metadata.get("agentengine")
|
|
521
|
+
agentengine_metadata = (
|
|
522
|
+
agentengine_metadata if isinstance(agentengine_metadata, dict) else {}
|
|
523
|
+
)
|
|
524
|
+
agent_id = (
|
|
525
|
+
str(
|
|
526
|
+
metadata.get("agent_id")
|
|
527
|
+
or metadata.get("agentId")
|
|
528
|
+
or agentengine_metadata.get("agent_id")
|
|
529
|
+
or agentengine_metadata.get("agentId")
|
|
530
|
+
or ""
|
|
531
|
+
)
|
|
532
|
+
or None
|
|
533
|
+
)
|
|
276
534
|
requested_approval_mode = (
|
|
277
|
-
str(
|
|
535
|
+
str(
|
|
536
|
+
metadata.get("approval_mode")
|
|
537
|
+
or metadata.get("approvalMode")
|
|
538
|
+
or agentengine_metadata.get("tool_approval_mode")
|
|
539
|
+
or agentengine_metadata.get("approval_mode")
|
|
540
|
+
or agentengine_metadata.get("approvalMode")
|
|
541
|
+
or ""
|
|
542
|
+
)
|
|
543
|
+
.strip()
|
|
544
|
+
.lower()
|
|
278
545
|
)
|
|
279
546
|
if requested_approval_mode and requested_approval_mode not in {"ask", "risk", "full"}:
|
|
280
547
|
raise StudioError(
|
|
@@ -284,7 +551,13 @@ def create_studio_app(
|
|
|
284
551
|
field="metadata.approval_mode",
|
|
285
552
|
)
|
|
286
553
|
collaboration_mode = (
|
|
287
|
-
str(
|
|
554
|
+
str(
|
|
555
|
+
metadata.get("collaboration_mode")
|
|
556
|
+
or metadata.get("collaborationMode")
|
|
557
|
+
or agentengine_metadata.get("collaboration_mode")
|
|
558
|
+
or agentengine_metadata.get("collaborationMode")
|
|
559
|
+
or ""
|
|
560
|
+
)
|
|
288
561
|
.strip()
|
|
289
562
|
.lower()
|
|
290
563
|
)
|
|
@@ -296,7 +569,11 @@ def create_studio_app(
|
|
|
296
569
|
field="metadata.collaboration_mode",
|
|
297
570
|
)
|
|
298
571
|
goal_objective = str(
|
|
299
|
-
metadata.get("goal_objective")
|
|
572
|
+
metadata.get("goal_objective")
|
|
573
|
+
or metadata.get("goalObjective")
|
|
574
|
+
or agentengine_metadata.get("goal_objective")
|
|
575
|
+
or agentengine_metadata.get("goalObjective")
|
|
576
|
+
or ""
|
|
300
577
|
).strip()
|
|
301
578
|
reasoning = payload.get("reasoning")
|
|
302
579
|
reasoning = reasoning if isinstance(reasoning, dict) else {}
|
|
@@ -324,6 +601,7 @@ def create_studio_app(
|
|
|
324
601
|
"CollaborationMode": collaboration_mode,
|
|
325
602
|
"GoalObjective": goal_objective,
|
|
326
603
|
"ReasoningEffort": reasoning_effort,
|
|
604
|
+
"ModelExplicit": bool(str(payload.get("model") or "").strip()),
|
|
327
605
|
}
|
|
328
606
|
bridge_payload["Model"] = shared_web.select_model(
|
|
329
607
|
bridge_payload["AgentId"],
|
|
@@ -363,26 +641,113 @@ def create_studio_app(
|
|
|
363
641
|
try:
|
|
364
642
|
cookie_agent_id = request.cookies.get("agentkit_studio_chat_agent")
|
|
365
643
|
requested_agent_id = str(payload.get("AgentId") or cookie_agent_id or "")
|
|
644
|
+
cloud_mode = is_cloud_agent_id(requested_agent_id)
|
|
645
|
+
if cloud_mode:
|
|
646
|
+
# Cloud agents project onto the same shared-web action
|
|
647
|
+
# contract through the cloud-chat proxy, so the ksadk-web
|
|
648
|
+
# headless data layer drives them like hosted-ui does.
|
|
649
|
+
cloud_target = cloud_chat_target(requested_agent_id)
|
|
650
|
+
data = None
|
|
651
|
+
if action == "GetAgentUiBootstrap":
|
|
652
|
+
data = await cloud_web.bootstrap(cloud_target)
|
|
653
|
+
elif action == "ListAgentModels":
|
|
654
|
+
data = await cloud_web.list_models(cloud_target)
|
|
655
|
+
elif action == "ListSessions":
|
|
656
|
+
data = await cloud_web.list_sessions(
|
|
657
|
+
cloud_target,
|
|
658
|
+
page=int(payload.get("Page") or 1),
|
|
659
|
+
page_size=int(payload.get("PageSize") or 30),
|
|
660
|
+
)
|
|
661
|
+
elif action == "CreateSession":
|
|
662
|
+
data = await cloud_web.create_session(cloud_target)
|
|
663
|
+
elif action == "GetSession":
|
|
664
|
+
data = await cloud_web.get_session(
|
|
665
|
+
cloud_target, str(payload.get("SessionId") or "")
|
|
666
|
+
)
|
|
667
|
+
elif action == "DeleteSession":
|
|
668
|
+
data = await cloud_web.delete_session(
|
|
669
|
+
cloud_target, str(payload.get("SessionId") or "")
|
|
670
|
+
)
|
|
671
|
+
elif action == "ListSessionMessages":
|
|
672
|
+
data = await cloud_web.list_messages(
|
|
673
|
+
cloud_target,
|
|
674
|
+
str(payload.get("SessionId") or ""),
|
|
675
|
+
after_seq_id=_optional_int(payload.get("AfterSeqId")),
|
|
676
|
+
before_seq_id=_optional_int(payload.get("BeforeSeqId")),
|
|
677
|
+
limit=int(payload.get("Limit") or 50),
|
|
678
|
+
)
|
|
679
|
+
elif action == "ListSessionEvents":
|
|
680
|
+
data = await cloud_web.list_session_events(
|
|
681
|
+
cloud_target,
|
|
682
|
+
str(payload.get("SessionId") or ""),
|
|
683
|
+
after_seq_id=_optional_int(payload.get("AfterSeqId")),
|
|
684
|
+
offset=_optional_int(payload.get("Offset")),
|
|
685
|
+
limit=int(payload.get("Limit") or 200),
|
|
686
|
+
)
|
|
687
|
+
elif action == "SubmitInteraction":
|
|
688
|
+
data = await cloud_web.submit_interaction(
|
|
689
|
+
cloud_target, str(payload.get("SessionId") or ""), payload
|
|
690
|
+
)
|
|
691
|
+
elif action == "RunAgent":
|
|
692
|
+
# Open the upstream connection before StreamingResponse
|
|
693
|
+
# commits status 200, so admission failures remain a
|
|
694
|
+
# structured HTTP error instead of an empty SSE body.
|
|
695
|
+
upstream_stream = await cloud_web.open_run_stream(cloud_target, payload)
|
|
696
|
+
return StreamingResponse(
|
|
697
|
+
cloud_web.stream_run(
|
|
698
|
+
cloud_target,
|
|
699
|
+
payload,
|
|
700
|
+
upstream_stream=upstream_stream,
|
|
701
|
+
),
|
|
702
|
+
media_type="text/event-stream",
|
|
703
|
+
headers={"Cache-Control": "no-store", "X-Accel-Buffering": "no"},
|
|
704
|
+
)
|
|
705
|
+
elif action in {
|
|
706
|
+
"GetResponseFeedback",
|
|
707
|
+
"UpsertResponseFeedback",
|
|
708
|
+
"DeleteResponseFeedback",
|
|
709
|
+
"ListSessionCheckpoints",
|
|
710
|
+
"ListToolReceipts",
|
|
711
|
+
}:
|
|
712
|
+
data = {"Feedback": None} if action == "GetResponseFeedback" else {}
|
|
713
|
+
else:
|
|
714
|
+
return JSONResponse(
|
|
715
|
+
status_code=404,
|
|
716
|
+
content={
|
|
717
|
+
"Code": 404,
|
|
718
|
+
"Message": f"Studio 尚未实现云端共享 Web 动作:{action}",
|
|
719
|
+
"Data": {},
|
|
720
|
+
},
|
|
721
|
+
)
|
|
722
|
+
return {"Code": 0, "Message": "OK", "Data": data}
|
|
366
723
|
if action == "GetAgentUiBootstrap":
|
|
367
724
|
data = shared_web.bootstrap(shared_web.resolve_agent_id(requested_agent_id or None))
|
|
368
725
|
elif action == "ListAgentModels":
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
726
|
+
model_agent_id = shared_web.resolve_agent_id(requested_agent_id or None)
|
|
727
|
+
# A cold Studio process has no discovered provider descriptors.
|
|
728
|
+
# Resolve the same cached catalog as Resources before projecting
|
|
729
|
+
# model windows; visiting Resources must not be a prerequisite.
|
|
730
|
+
await runtime_model_catalog()
|
|
731
|
+
data = shared_web.list_models(model_agent_id)
|
|
372
732
|
elif action == "ListSessions":
|
|
373
|
-
data = shared_web.list_sessions(
|
|
733
|
+
data = await shared_web.list_sessions(
|
|
374
734
|
shared_web.resolve_agent_id(requested_agent_id or None),
|
|
375
735
|
page=int(payload.get("Page") or 1),
|
|
376
736
|
page_size=int(payload.get("PageSize") or 30),
|
|
377
737
|
)
|
|
378
738
|
elif action == "CreateSession":
|
|
379
|
-
data = shared_web.create_session(
|
|
739
|
+
data = await shared_web.create_session(
|
|
380
740
|
shared_web.resolve_agent_id(requested_agent_id or None)
|
|
381
741
|
)
|
|
382
742
|
elif action == "GetSession":
|
|
383
|
-
data = shared_web.get_session(str(payload.get("SessionId") or ""))
|
|
743
|
+
data = await shared_web.get_session(str(payload.get("SessionId") or ""))
|
|
744
|
+
elif action == "CompactSession":
|
|
745
|
+
data = await shared_web.compact_session(
|
|
746
|
+
shared_web.resolve_agent_id(requested_agent_id or None),
|
|
747
|
+
str(payload.get("SessionId") or ""),
|
|
748
|
+
)
|
|
384
749
|
elif action == "DeleteSession":
|
|
385
|
-
data = shared_web.delete_session(str(payload.get("SessionId") or ""))
|
|
750
|
+
data = await shared_web.delete_session(str(payload.get("SessionId") or ""))
|
|
386
751
|
elif action == "ListSessionMessages":
|
|
387
752
|
data = await shared_web.list_messages(
|
|
388
753
|
str(payload.get("SessionId") or ""),
|
|
@@ -393,8 +758,12 @@ def create_studio_app(
|
|
|
393
758
|
elif action == "ListSessionEvents":
|
|
394
759
|
data = await shared_web.list_session_events(str(payload.get("SessionId") or ""))
|
|
395
760
|
elif action == "RunAgent":
|
|
761
|
+
# A cold process has not discovered provider model descriptors
|
|
762
|
+
# yet. Run admission may need to materialize a current Build,
|
|
763
|
+
# so chat must not depend on visiting the Models page first.
|
|
764
|
+
await runtime_model_catalog()
|
|
396
765
|
return StreamingResponse(
|
|
397
|
-
shared_web.stream_run(payload),
|
|
766
|
+
shared_web.stream_run(payload, shared_ui=True),
|
|
398
767
|
media_type="text/event-stream",
|
|
399
768
|
headers={
|
|
400
769
|
"Cache-Control": "no-store",
|
|
@@ -403,6 +772,33 @@ def create_studio_app(
|
|
|
403
772
|
)
|
|
404
773
|
elif action == "CancelRun":
|
|
405
774
|
data = shared_web.cancel_run(str(payload.get("InvocationId") or ""))
|
|
775
|
+
elif action == "SubmitInteraction":
|
|
776
|
+
run_id = str(payload.get("RunId") or "")
|
|
777
|
+
interaction_id = str(payload.get("InteractionId") or "")
|
|
778
|
+
resolved = await studio.run_service.submit_interaction(
|
|
779
|
+
run_id,
|
|
780
|
+
interaction_id,
|
|
781
|
+
name=str(payload.get("Action") or "submit"),
|
|
782
|
+
data=(
|
|
783
|
+
dict(payload.get("Response"))
|
|
784
|
+
if isinstance(payload.get("Response"), dict)
|
|
785
|
+
else {}
|
|
786
|
+
),
|
|
787
|
+
expected_revision=int(payload.get("ExpectedRevision") or 0),
|
|
788
|
+
idempotency_key=str(payload.get("IdempotencyKey") or ""),
|
|
789
|
+
)
|
|
790
|
+
data = {
|
|
791
|
+
"schema_version": 1,
|
|
792
|
+
"command_id": str(
|
|
793
|
+
resolved.get("eventId")
|
|
794
|
+
or resolved.get("resolutionEventId")
|
|
795
|
+
or f"interaction:{interaction_id}"
|
|
796
|
+
),
|
|
797
|
+
"status": "accepted",
|
|
798
|
+
"message_id": None,
|
|
799
|
+
"run_id": run_id,
|
|
800
|
+
"accepted_seq": int(resolved.get("eventId") or 0),
|
|
801
|
+
}
|
|
406
802
|
elif action in {
|
|
407
803
|
"GetResponseFeedback",
|
|
408
804
|
"UpsertResponseFeedback",
|
|
@@ -434,12 +830,37 @@ def create_studio_app(
|
|
|
434
830
|
)
|
|
435
831
|
|
|
436
832
|
@app.get("/agentengine/api/v1/SubscribeRunEvents")
|
|
437
|
-
async def shared_chat_subscribe_run_events(
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
833
|
+
async def shared_chat_subscribe_run_events(
|
|
834
|
+
request: Request,
|
|
835
|
+
session_id: str = Query(alias="SessionId"),
|
|
836
|
+
invocation_id: str = Query(alias="InvocationId"),
|
|
837
|
+
after_seq_id: int = Query(default=0, alias="AfterSeqId", ge=0),
|
|
838
|
+
agent_id: str | None = Query(default=None, alias="AgentId"),
|
|
839
|
+
):
|
|
840
|
+
requested_agent_id = str(
|
|
841
|
+
agent_id or request.cookies.get("agentkit_studio_chat_agent") or ""
|
|
842
|
+
)
|
|
843
|
+
if is_cloud_agent_id(requested_agent_id):
|
|
844
|
+
cloud_target = cloud_chat_target(requested_agent_id)
|
|
845
|
+
return StreamingResponse(
|
|
846
|
+
cloud_web.subscribe_run_events(
|
|
847
|
+
cloud_target,
|
|
848
|
+
session_id,
|
|
849
|
+
invocation_id,
|
|
850
|
+
after_seq_id=after_seq_id,
|
|
851
|
+
),
|
|
852
|
+
media_type="text/event-stream",
|
|
853
|
+
headers={"Cache-Control": "no-store", "X-Accel-Buffering": "no"},
|
|
854
|
+
)
|
|
855
|
+
# Validate before StreamingResponse sends headers; invalid identities
|
|
856
|
+
# remain ordinary actionable HTTP errors.
|
|
857
|
+
await shared_web.subscription_run_id(session_id, invocation_id)
|
|
441
858
|
return StreamingResponse(
|
|
442
|
-
|
|
859
|
+
shared_web.subscribe_run_events(
|
|
860
|
+
session_id,
|
|
861
|
+
invocation_id,
|
|
862
|
+
after_seq_id=after_seq_id,
|
|
863
|
+
),
|
|
443
864
|
media_type="text/event-stream",
|
|
444
865
|
headers={"Cache-Control": "no-store", "X-Accel-Buffering": "no"},
|
|
445
866
|
)
|
|
@@ -491,6 +912,7 @@ def create_studio_app(
|
|
|
491
912
|
"deployment": True,
|
|
492
913
|
"cloudRebuild": False,
|
|
493
914
|
"reactChat": True,
|
|
915
|
+
"scheduler": studio.scheduler.availability(),
|
|
494
916
|
},
|
|
495
917
|
"runtimes": studio.runtime_catalog(),
|
|
496
918
|
"importableProject": studio.detect_importable_project(),
|
|
@@ -504,6 +926,116 @@ def create_studio_app(
|
|
|
504
926
|
async def update_settings(payload: dict[str, Any]):
|
|
505
927
|
return studio.update_settings(payload)
|
|
506
928
|
|
|
929
|
+
@app.get("/api/v1/schedules")
|
|
930
|
+
async def list_schedules():
|
|
931
|
+
return {
|
|
932
|
+
"items": studio.scheduler.list_tasks(),
|
|
933
|
+
"taskOccurrences": studio.scheduler.task_occurrence_summaries(),
|
|
934
|
+
"availability": studio.scheduler.availability(),
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
@app.post("/api/v1/schedules", status_code=201)
|
|
938
|
+
async def create_schedule(payload: ScheduledTask):
|
|
939
|
+
studio.validate_schedule_build(
|
|
940
|
+
payload.target.agent_version_ref,
|
|
941
|
+
agent_id=payload.target.agent_id,
|
|
942
|
+
)
|
|
943
|
+
return studio.scheduler.create_task(payload)
|
|
944
|
+
|
|
945
|
+
@app.get("/api/v1/schedules/{task_id}")
|
|
946
|
+
async def get_schedule(task_id: str):
|
|
947
|
+
return studio.scheduler.get_task(task_id)
|
|
948
|
+
|
|
949
|
+
@app.put("/api/v1/schedules/{task_id}")
|
|
950
|
+
async def update_schedule(task_id: str, payload: ScheduledTask):
|
|
951
|
+
studio.validate_schedule_build(
|
|
952
|
+
payload.target.agent_version_ref,
|
|
953
|
+
agent_id=payload.target.agent_id,
|
|
954
|
+
)
|
|
955
|
+
return studio.scheduler.update_task(task_id, payload)
|
|
956
|
+
|
|
957
|
+
@app.delete("/api/v1/schedules/{task_id}", status_code=204)
|
|
958
|
+
async def delete_schedule(task_id: str):
|
|
959
|
+
studio.scheduler.delete_task(task_id)
|
|
960
|
+
return Response(status_code=204)
|
|
961
|
+
|
|
962
|
+
@app.post("/api/v1/schedules/{task_id}:run", status_code=202)
|
|
963
|
+
async def run_schedule_now(task_id: str):
|
|
964
|
+
return await studio.scheduler.run_now(task_id)
|
|
965
|
+
|
|
966
|
+
@app.get("/api/v1/schedules/{task_id}/occurrences")
|
|
967
|
+
async def list_schedule_occurrences(task_id: str, limit: int = Query(default=50, ge=1, le=200)):
|
|
968
|
+
return {"items": studio.scheduler.list_occurrences(task_id, limit=limit)}
|
|
969
|
+
|
|
970
|
+
@app.get("/api/v1/schedule-occurrences")
|
|
971
|
+
async def list_all_schedule_occurrences(
|
|
972
|
+
limit: int = Query(default=200, ge=1, le=500),
|
|
973
|
+
):
|
|
974
|
+
return {"items": studio.scheduler.list_all_occurrences(limit=limit)}
|
|
975
|
+
|
|
976
|
+
@app.get("/api/v1/agents/{agent_id}/schedules")
|
|
977
|
+
async def list_agent_schedules(agent_id: str):
|
|
978
|
+
return {
|
|
979
|
+
"items": studio.list_agent_schedules(agent_id),
|
|
980
|
+
"availability": studio.scheduler.availability(),
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
@app.post("/api/v1/agents/{agent_id}/schedules", status_code=201)
|
|
984
|
+
async def create_agent_schedule(agent_id: str, payload: AgentScheduleRequest):
|
|
985
|
+
return await studio.create_agent_schedule(
|
|
986
|
+
agent_id,
|
|
987
|
+
display_name=payload.display_name,
|
|
988
|
+
prompt=payload.prompt,
|
|
989
|
+
schedule=payload.schedule,
|
|
990
|
+
enabled=payload.enabled,
|
|
991
|
+
continuity=payload.continuity,
|
|
992
|
+
session_id=payload.session_id,
|
|
993
|
+
)
|
|
994
|
+
|
|
995
|
+
@app.get("/api/v1/agents/{agent_id}/schedules/{task_id}")
|
|
996
|
+
async def get_agent_schedule(agent_id: str, task_id: str):
|
|
997
|
+
return studio.get_agent_schedule(agent_id, task_id)
|
|
998
|
+
|
|
999
|
+
@app.put("/api/v1/agents/{agent_id}/schedules/{task_id}")
|
|
1000
|
+
async def update_agent_schedule(
|
|
1001
|
+
agent_id: str,
|
|
1002
|
+
task_id: str,
|
|
1003
|
+
payload: AgentScheduleRequest,
|
|
1004
|
+
):
|
|
1005
|
+
existing = studio.get_agent_schedule(agent_id, task_id)
|
|
1006
|
+
await studio.validate_schedule_session(
|
|
1007
|
+
agent_id, payload.continuity, payload.session_id, existing.target.agent_version_ref
|
|
1008
|
+
)
|
|
1009
|
+
return studio.update_agent_schedule(
|
|
1010
|
+
agent_id,
|
|
1011
|
+
task_id,
|
|
1012
|
+
display_name=payload.display_name,
|
|
1013
|
+
prompt=payload.prompt,
|
|
1014
|
+
schedule=payload.schedule,
|
|
1015
|
+
enabled=payload.enabled,
|
|
1016
|
+
continuity=payload.continuity,
|
|
1017
|
+
session_id=payload.session_id,
|
|
1018
|
+
)
|
|
1019
|
+
|
|
1020
|
+
@app.delete("/api/v1/agents/{agent_id}/schedules/{task_id}", status_code=204)
|
|
1021
|
+
async def delete_agent_schedule(agent_id: str, task_id: str):
|
|
1022
|
+
studio.get_agent_schedule(agent_id, task_id)
|
|
1023
|
+
studio.scheduler.delete_task(task_id)
|
|
1024
|
+
return Response(status_code=204)
|
|
1025
|
+
|
|
1026
|
+
@app.post("/api/v1/agents/{agent_id}/schedules/{task_id}:run", status_code=202)
|
|
1027
|
+
async def run_agent_schedule_now(agent_id: str, task_id: str):
|
|
1028
|
+
return await studio.run_agent_schedule_now(agent_id, task_id)
|
|
1029
|
+
|
|
1030
|
+
@app.get("/api/v1/agents/{agent_id}/schedules/{task_id}/occurrences")
|
|
1031
|
+
async def list_agent_schedule_occurrences(
|
|
1032
|
+
agent_id: str,
|
|
1033
|
+
task_id: str,
|
|
1034
|
+
limit: int = Query(default=50, ge=1, le=200),
|
|
1035
|
+
):
|
|
1036
|
+
studio.get_agent_schedule(agent_id, task_id)
|
|
1037
|
+
return {"items": studio.scheduler.list_occurrences(task_id, limit=limit)}
|
|
1038
|
+
|
|
507
1039
|
@app.post("/api/v1/workspaces:open")
|
|
508
1040
|
async def open_workspace(payload: WorkspaceOpenRequest):
|
|
509
1041
|
# This endpoint only reconnects to the daemon's already-bound root. Do
|
|
@@ -580,57 +1112,118 @@ def create_studio_app(
|
|
|
580
1112
|
"Codex Studio 只支持只读本地运行",
|
|
581
1113
|
status_code=422,
|
|
582
1114
|
)
|
|
583
|
-
|
|
584
|
-
queue: asyncio.Queue = asyncio.Queue()
|
|
585
|
-
|
|
586
|
-
def observe(event):
|
|
587
|
-
queue.put_nowait(event)
|
|
588
|
-
|
|
589
|
-
# The Operation owns the runtime task. The SSE response is only one
|
|
590
|
-
# observer, so refreshing or switching chats cannot cancel the Run.
|
|
591
|
-
operation = studio.submit_studio_run(
|
|
1115
|
+
return _stream_studio_run(
|
|
592
1116
|
build_id,
|
|
593
|
-
payload.input.content,
|
|
1117
|
+
user_input=payload.input.content,
|
|
594
1118
|
session_id=payload.session_id,
|
|
595
1119
|
model=payload.model,
|
|
596
1120
|
sandbox=payload.sandbox,
|
|
597
1121
|
idempotency_key=key,
|
|
598
|
-
on_event=observe,
|
|
599
1122
|
)
|
|
600
1123
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
if event is not None:
|
|
608
|
-
data = json.dumps(
|
|
609
|
-
event.data,
|
|
610
|
-
ensure_ascii=False,
|
|
611
|
-
separators=(",", ":"),
|
|
612
|
-
)
|
|
613
|
-
yield f"id: {event.id}\nevent: {event.type}\ndata: {data}\n\n"
|
|
614
|
-
current = studio.operations.get(operation.id)
|
|
615
|
-
if (
|
|
616
|
-
current.status
|
|
617
|
-
in {
|
|
618
|
-
OperationStatus.SUCCEEDED,
|
|
619
|
-
OperationStatus.FAILED,
|
|
620
|
-
OperationStatus.CANCELLED,
|
|
621
|
-
OperationStatus.INTERRUPTED,
|
|
622
|
-
}
|
|
623
|
-
and queue.empty()
|
|
624
|
-
):
|
|
625
|
-
if current.status == OperationStatus.FAILED:
|
|
626
|
-
data = json.dumps(current.error or {}, ensure_ascii=False)
|
|
627
|
-
yield f"event: run.failed\ndata: {data}\n\n"
|
|
628
|
-
break
|
|
1124
|
+
@app.get("/api/v1/builds/{build_id}/conversation-surface")
|
|
1125
|
+
async def get_conversation_surface(
|
|
1126
|
+
build_id: str,
|
|
1127
|
+
session_id: str = Query(alias="sessionId", min_length=1, max_length=256),
|
|
1128
|
+
):
|
|
1129
|
+
return studio.conversation_surface(build_id, session_id=session_id)
|
|
629
1130
|
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
1131
|
+
@app.get("/api/v1/agents/{agent_id}/conversation-surface")
|
|
1132
|
+
async def get_agent_conversation_surface(
|
|
1133
|
+
agent_id: str,
|
|
1134
|
+
session_id: str = Query(alias="sessionId", min_length=1, max_length=256),
|
|
1135
|
+
):
|
|
1136
|
+
"""Resolve the immutable Build and its composer contract atomically.
|
|
1137
|
+
|
|
1138
|
+
The browser selects an Agent, not a mutable Draft or a Build id. This
|
|
1139
|
+
route gives it the same current-Build decision used by chat and local
|
|
1140
|
+
Scheduler authoring, so controls cannot be rendered from a stale or
|
|
1141
|
+
unrelated Build.
|
|
1142
|
+
"""
|
|
1143
|
+
|
|
1144
|
+
await runtime_model_catalog()
|
|
1145
|
+
build = await studio.ensure_current_build(agent_id)
|
|
1146
|
+
return {
|
|
1147
|
+
"buildId": build.id,
|
|
1148
|
+
"surface": studio.conversation_surface(
|
|
1149
|
+
build.id,
|
|
1150
|
+
session_id=session_id,
|
|
1151
|
+
),
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
@app.post("/api/v1/builds/{build_id}/conversation:stream")
|
|
1155
|
+
async def stream_conversation_turn(
|
|
1156
|
+
build_id: str,
|
|
1157
|
+
payload: ConversationTurnRequest,
|
|
1158
|
+
idempotency_key: str | None = Header(default=None, alias="Idempotency-Key"),
|
|
1159
|
+
):
|
|
1160
|
+
key = _require_idempotency_key(idempotency_key)
|
|
1161
|
+
conversation_input = payload.input
|
|
1162
|
+
if conversation_input.idempotency_key != key:
|
|
1163
|
+
raise StudioError(
|
|
1164
|
+
"CONVERSATION_IDEMPOTENCY_MISMATCH",
|
|
1165
|
+
"ConversationInput 的幂等键必须与请求头一致",
|
|
1166
|
+
status_code=422,
|
|
1167
|
+
)
|
|
1168
|
+
surface = studio.conversation_surface(
|
|
1169
|
+
build_id,
|
|
1170
|
+
session_id=conversation_input.session_id,
|
|
1171
|
+
)
|
|
1172
|
+
try:
|
|
1173
|
+
validate_conversation_input(surface, conversation_input)
|
|
1174
|
+
except ValueError as exc:
|
|
1175
|
+
raise StudioError(
|
|
1176
|
+
"CONVERSATION_INPUT_UNSUPPORTED",
|
|
1177
|
+
"当前 Agent 不支持此会话输入",
|
|
1178
|
+
status_code=422,
|
|
1179
|
+
details={"reason": str(exc), "surfaceId": surface.surface_id},
|
|
1180
|
+
) from exc
|
|
1181
|
+
text_parts = [
|
|
1182
|
+
part.text for part in conversation_input.parts if isinstance(part, ConversationTextPart)
|
|
1183
|
+
]
|
|
1184
|
+
runtime_parts: list[dict[str, str]] = [
|
|
1185
|
+
{"type": "text", "text": value} for value in text_parts
|
|
1186
|
+
]
|
|
1187
|
+
attachment_names: list[str] = []
|
|
1188
|
+
for part in conversation_input.parts:
|
|
1189
|
+
if not isinstance(part, ConversationAttachmentPart):
|
|
1190
|
+
continue
|
|
1191
|
+
stored = studio.conversation_attachments.resolve(part.attachment_ref)
|
|
1192
|
+
if part.media_type.lower() != stored.media_type.lower():
|
|
1193
|
+
raise StudioError(
|
|
1194
|
+
"CONVERSATION_ATTACHMENT_METADATA_MISMATCH",
|
|
1195
|
+
"会话附件类型与已上传内容不一致",
|
|
1196
|
+
status_code=422,
|
|
1197
|
+
details={"attachmentRef": part.attachment_ref},
|
|
1198
|
+
)
|
|
1199
|
+
encoded = base64.b64encode(stored.path.read_bytes()).decode("ascii")
|
|
1200
|
+
data_url = f"data:{stored.media_type};base64,{encoded}"
|
|
1201
|
+
attachment_names.append(part.name or stored.name)
|
|
1202
|
+
if stored.media_type.startswith("image/"):
|
|
1203
|
+
runtime_parts.append({"type": "image", "url": data_url})
|
|
1204
|
+
else:
|
|
1205
|
+
runtime_parts.append(
|
|
1206
|
+
{
|
|
1207
|
+
"type": "input_file",
|
|
1208
|
+
"filename": part.name or stored.name,
|
|
1209
|
+
"file_data": data_url,
|
|
1210
|
+
}
|
|
1211
|
+
)
|
|
1212
|
+
display_input = "\n".join(text_parts).strip()
|
|
1213
|
+
if not display_input:
|
|
1214
|
+
display_input = "请处理本轮附件:" + "、".join(attachment_names)
|
|
1215
|
+
return _stream_studio_run(
|
|
1216
|
+
build_id,
|
|
1217
|
+
user_input=display_input,
|
|
1218
|
+
session_id=conversation_input.session_id,
|
|
1219
|
+
model=conversation_input.model_ref,
|
|
1220
|
+
sandbox=payload.sandbox,
|
|
1221
|
+
reasoning_effort=conversation_input.reasoning,
|
|
1222
|
+
approval_mode=conversation_input.approval_mode,
|
|
1223
|
+
collaboration_mode=conversation_input.collaboration_mode,
|
|
1224
|
+
goal_objective=conversation_input.goal_objective,
|
|
1225
|
+
runtime_input=runtime_parts if attachment_names else None,
|
|
1226
|
+
idempotency_key=key,
|
|
634
1227
|
)
|
|
635
1228
|
|
|
636
1229
|
@app.post("/api/v1/agents", status_code=201)
|
|
@@ -644,6 +1237,15 @@ def create_studio_app(
|
|
|
644
1237
|
runtime=payload.runtime,
|
|
645
1238
|
)
|
|
646
1239
|
|
|
1240
|
+
@app.post("/api/v1/conversation-attachments", status_code=201)
|
|
1241
|
+
async def upload_conversation_attachment(file: UploadFile = File(...)):
|
|
1242
|
+
content = await file.read(studio.conversation_attachments.MAX_BYTES + 1)
|
|
1243
|
+
return studio.conversation_attachments.store(
|
|
1244
|
+
content,
|
|
1245
|
+
filename=file.filename or "attachment",
|
|
1246
|
+
media_type=file.content_type or "application/octet-stream",
|
|
1247
|
+
)
|
|
1248
|
+
|
|
647
1249
|
@app.post("/api/v1/assets/agent-avatars", status_code=201)
|
|
648
1250
|
async def upload_agent_avatar(request: Request):
|
|
649
1251
|
declared_size = request.headers.get("Content-Length")
|
|
@@ -777,7 +1379,9 @@ def create_studio_app(
|
|
|
777
1379
|
|
|
778
1380
|
@app.get("/api/v1/agents/{agent_id}/models")
|
|
779
1381
|
async def get_agent_models(agent_id: str):
|
|
780
|
-
|
|
1382
|
+
model_agent_id = shared_web.resolve_agent_id(agent_id)
|
|
1383
|
+
await runtime_model_catalog()
|
|
1384
|
+
return shared_web.list_models(model_agent_id)
|
|
781
1385
|
|
|
782
1386
|
@app.put("/api/v1/agents/{agent_id}")
|
|
783
1387
|
async def update_agent(
|
|
@@ -878,6 +1482,7 @@ def create_studio_app(
|
|
|
878
1482
|
payload: BuildRequest,
|
|
879
1483
|
idempotency_key: str | None = Header(default=None, alias="Idempotency-Key"),
|
|
880
1484
|
):
|
|
1485
|
+
await runtime_model_catalog()
|
|
881
1486
|
return studio.submit_studio_build(
|
|
882
1487
|
agent_id,
|
|
883
1488
|
revision=payload.revision,
|
|
@@ -955,6 +1560,8 @@ def create_studio_app(
|
|
|
955
1560
|
interaction_id,
|
|
956
1561
|
name=payload.name,
|
|
957
1562
|
data=payload.data,
|
|
1563
|
+
expected_revision=payload.expected_revision,
|
|
1564
|
+
idempotency_key=payload.idempotency_key,
|
|
958
1565
|
)
|
|
959
1566
|
|
|
960
1567
|
@app.get("/api/v1/runs/{run_id}/context")
|
|
@@ -1236,7 +1843,7 @@ def create_studio_app(
|
|
|
1236
1843
|
async def list_deployments():
|
|
1237
1844
|
"""Read local deployment receipts without implicit cloud refreshes."""
|
|
1238
1845
|
|
|
1239
|
-
return {"items": studio.cloud.list()}
|
|
1846
|
+
return {"items": studio.cloud.list(), "currentIdentity": studio.cloud.cached_identity()}
|
|
1240
1847
|
|
|
1241
1848
|
@app.get("/api/v1/cloud-agents")
|
|
1242
1849
|
async def list_account_cloud_agents(
|
|
@@ -1312,9 +1919,7 @@ def create_studio_app(
|
|
|
1312
1919
|
):
|
|
1313
1920
|
"""List Server-owned sessions for this local deployment receipt only."""
|
|
1314
1921
|
|
|
1315
|
-
return await studio.cloud.list_cloud_chat_sessions(
|
|
1316
|
-
deployment_id, page=page, size=size
|
|
1317
|
-
)
|
|
1922
|
+
return await studio.cloud.list_cloud_chat_sessions(deployment_id, page=page, size=size)
|
|
1318
1923
|
|
|
1319
1924
|
@app.get("/api/v1/deployments/{deployment_id}/cloud-chat/models")
|
|
1320
1925
|
async def list_cloud_chat_models(deployment_id: str):
|
|
@@ -1331,9 +1936,7 @@ def create_studio_app(
|
|
|
1331
1936
|
|
|
1332
1937
|
return await studio.cloud.create_cloud_chat_session(deployment_id)
|
|
1333
1938
|
|
|
1334
|
-
@app.get(
|
|
1335
|
-
"/api/v1/deployments/{deployment_id}/cloud-chat/sessions/{session_id}/messages"
|
|
1336
|
-
)
|
|
1939
|
+
@app.get("/api/v1/deployments/{deployment_id}/cloud-chat/sessions/{session_id}/messages")
|
|
1337
1940
|
async def list_cloud_chat_messages(
|
|
1338
1941
|
deployment_id: str,
|
|
1339
1942
|
session_id: str,
|
|
@@ -1347,25 +1950,23 @@ def create_studio_app(
|
|
|
1347
1950
|
limit=limit,
|
|
1348
1951
|
)
|
|
1349
1952
|
|
|
1350
|
-
@app.get(
|
|
1351
|
-
"/api/v1/deployments/{deployment_id}/cloud-chat/sessions/{session_id}/events"
|
|
1352
|
-
)
|
|
1953
|
+
@app.get("/api/v1/deployments/{deployment_id}/cloud-chat/sessions/{session_id}/events")
|
|
1353
1954
|
async def list_cloud_chat_events(
|
|
1354
1955
|
deployment_id: str,
|
|
1355
1956
|
session_id: str,
|
|
1356
1957
|
after_seq_id: int | None = Query(default=None, alias="afterSeqId", ge=0),
|
|
1958
|
+
offset: int | None = Query(default=None, ge=0),
|
|
1357
1959
|
limit: int = Query(default=200, ge=1, le=1000),
|
|
1358
1960
|
):
|
|
1359
1961
|
return await studio.cloud.list_cloud_chat_events(
|
|
1360
1962
|
deployment_id,
|
|
1361
1963
|
session_id=session_id,
|
|
1362
1964
|
after_seq_id=after_seq_id,
|
|
1965
|
+
offset=offset,
|
|
1363
1966
|
limit=limit,
|
|
1364
1967
|
)
|
|
1365
1968
|
|
|
1366
|
-
@app.get(
|
|
1367
|
-
"/api/v1/deployments/{deployment_id}/cloud-chat/sessions/{session_id}/events/stream"
|
|
1368
|
-
)
|
|
1969
|
+
@app.get("/api/v1/deployments/{deployment_id}/cloud-chat/sessions/{session_id}/events/stream")
|
|
1369
1970
|
async def stream_cloud_chat_events(
|
|
1370
1971
|
request: Request,
|
|
1371
1972
|
deployment_id: str,
|
|
@@ -1399,9 +2000,7 @@ def create_studio_app(
|
|
|
1399
2000
|
if not isinstance(event, dict):
|
|
1400
2001
|
continue
|
|
1401
2002
|
event_payload = (
|
|
1402
|
-
event.get("payload")
|
|
1403
|
-
if isinstance(event.get("payload"), dict)
|
|
1404
|
-
else event
|
|
2003
|
+
event.get("payload") if isinstance(event.get("payload"), dict) else event
|
|
1405
2004
|
)
|
|
1406
2005
|
seq = int(
|
|
1407
2006
|
event_payload.get("seq")
|
|
@@ -1427,25 +2026,44 @@ def create_studio_app(
|
|
|
1427
2026
|
if isinstance(event_payload.get("content"), dict)
|
|
1428
2027
|
else {}
|
|
1429
2028
|
)
|
|
1430
|
-
status = str(
|
|
1431
|
-
event_payload.get("status") or content.get("status") or ""
|
|
1432
|
-
).lower()
|
|
2029
|
+
status = str(event_payload.get("status") or content.get("status") or "").lower()
|
|
1433
2030
|
event_is_terminal = event_type in {
|
|
1434
|
-
"run.completed",
|
|
1435
|
-
"run.
|
|
2031
|
+
"run.completed",
|
|
2032
|
+
"run.complete",
|
|
2033
|
+
"run.succeeded",
|
|
2034
|
+
"run.failed",
|
|
2035
|
+
"run.cancelled",
|
|
2036
|
+
"run.expired",
|
|
2037
|
+
"run.error",
|
|
1436
2038
|
} or (
|
|
1437
2039
|
event_type in {"run_status", "run.status"}
|
|
1438
|
-
and status
|
|
1439
|
-
|
|
1440
|
-
"
|
|
2040
|
+
and status
|
|
2041
|
+
in {
|
|
2042
|
+
"completed",
|
|
2043
|
+
"complete",
|
|
2044
|
+
"succeeded",
|
|
2045
|
+
"success",
|
|
2046
|
+
"failed",
|
|
2047
|
+
"cancelled",
|
|
2048
|
+
"canceled",
|
|
2049
|
+
"expired",
|
|
2050
|
+
"error",
|
|
2051
|
+
"aborted",
|
|
1441
2052
|
}
|
|
1442
2053
|
)
|
|
1443
2054
|
terminal = terminal or event_is_terminal
|
|
1444
2055
|
emitted = True
|
|
2056
|
+
projected_event = dict(event)
|
|
2057
|
+
conversation_item = _cloud_event_conversation_item(
|
|
2058
|
+
event,
|
|
2059
|
+
session_id=session_id,
|
|
2060
|
+
)
|
|
2061
|
+
if conversation_item is not None:
|
|
2062
|
+
projected_event["conversationItem"] = conversation_item
|
|
1445
2063
|
yield (
|
|
1446
2064
|
(f"id: {seq}\n" if seq else "")
|
|
1447
2065
|
+ "event: session.event\n"
|
|
1448
|
-
+ f"data: {json.dumps(
|
|
2066
|
+
+ f"data: {json.dumps(projected_event, ensure_ascii=False)}\n\n"
|
|
1449
2067
|
)
|
|
1450
2068
|
if terminal or payload.get("session_deleted"):
|
|
1451
2069
|
break
|
|
@@ -1465,9 +2083,7 @@ def create_studio_app(
|
|
|
1465
2083
|
status_code=204,
|
|
1466
2084
|
)
|
|
1467
2085
|
async def delete_cloud_chat_session(deployment_id: str, session_id: str):
|
|
1468
|
-
await studio.cloud.delete_cloud_chat_session(
|
|
1469
|
-
deployment_id, session_id=session_id
|
|
1470
|
-
)
|
|
2086
|
+
await studio.cloud.delete_cloud_chat_session(deployment_id, session_id=session_id)
|
|
1471
2087
|
return Response(status_code=204)
|
|
1472
2088
|
|
|
1473
2089
|
@app.post(
|
|
@@ -1594,5 +2210,13 @@ def create_studio_app(
|
|
|
1594
2210
|
runtime_model_catalog=runtime_model_catalog,
|
|
1595
2211
|
)
|
|
1596
2212
|
register_memory_routes(app, studio)
|
|
2213
|
+
register_resource_connection_routes(app, studio)
|
|
2214
|
+
register_plugin_routes(app, studio)
|
|
2215
|
+
|
|
2216
|
+
from ksadk.studio.dsh_application import register_dsh_application
|
|
2217
|
+
|
|
2218
|
+
register_dsh_application(
|
|
2219
|
+
app, studio, session_secret=session_secret, security_enabled=security_enabled
|
|
2220
|
+
)
|
|
1597
2221
|
|
|
1598
2222
|
return app
|