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/shared_web.py
CHANGED
|
@@ -9,8 +9,22 @@ from datetime import datetime, timezone
|
|
|
9
9
|
from typing import Any
|
|
10
10
|
from uuid import uuid4
|
|
11
11
|
|
|
12
|
-
from ksadk.
|
|
12
|
+
from ksadk.conversations.contracts import (
|
|
13
|
+
APPROVAL_MODE_EXTENSION,
|
|
14
|
+
COLLABORATION_MODE_EXTENSION,
|
|
15
|
+
GOAL_OBJECTIVE_EXTENSION,
|
|
16
|
+
ConversationAttachmentPart,
|
|
17
|
+
ConversationInput,
|
|
18
|
+
ConversationTextPart,
|
|
19
|
+
validate_conversation_input,
|
|
20
|
+
)
|
|
21
|
+
from ksadk.conversations.message_projection import project_session_messages
|
|
22
|
+
from ksadk.events.canonical import parse_runtime_event
|
|
23
|
+
from ksadk.events.canonical_store import session_event_to_runtime_event
|
|
24
|
+
from ksadk.sessions.base import Session
|
|
25
|
+
from ksadk.studio.contracts import OperationStatus, RunRecord, RunStatus
|
|
13
26
|
from ksadk.studio.errors import StudioError, not_found
|
|
27
|
+
from ksadk.studio.run_service import project_runtime_event
|
|
14
28
|
from ksadk.studio.service import StudioService
|
|
15
29
|
from ksadk.tools.gateway import tool_approval_capability
|
|
16
30
|
|
|
@@ -80,10 +94,12 @@ class StudioSharedWebBridge:
|
|
|
80
94
|
"CheckpointResumePreview": False,
|
|
81
95
|
},
|
|
82
96
|
"ApprovalPolicy": tool_approval_capability(),
|
|
97
|
+
"InteractionV1": True,
|
|
83
98
|
"WorkspaceFiles": {"Enabled": False},
|
|
84
99
|
"NativeDashboard": {"Enabled": False},
|
|
85
100
|
"NativeTerminal": {"Enabled": False},
|
|
86
101
|
"Thinking": False,
|
|
102
|
+
"ContextCompaction": self.studio.is_codex_agent(agent_id),
|
|
87
103
|
},
|
|
88
104
|
}
|
|
89
105
|
|
|
@@ -101,14 +117,14 @@ class StudioSharedWebBridge:
|
|
|
101
117
|
|
|
102
118
|
return self._select_model(agent_id, str(requested or ""))
|
|
103
119
|
|
|
104
|
-
def list_sessions(
|
|
120
|
+
async def list_sessions(
|
|
105
121
|
self,
|
|
106
122
|
agent_id: str,
|
|
107
123
|
*,
|
|
108
124
|
page: int = 1,
|
|
109
125
|
page_size: int = 30,
|
|
110
126
|
) -> dict[str, Any]:
|
|
111
|
-
sessions = self._sessions(agent_id)
|
|
127
|
+
sessions = await self._sessions(agent_id)
|
|
112
128
|
safe_page = max(1, page)
|
|
113
129
|
safe_size = min(100, max(1, page_size))
|
|
114
130
|
start = (safe_page - 1) * safe_size
|
|
@@ -119,29 +135,79 @@ class StudioSharedWebBridge:
|
|
|
119
135
|
"PageSize": safe_size,
|
|
120
136
|
}
|
|
121
137
|
|
|
122
|
-
def create_session(self, agent_id: str) -> dict[str, Any]:
|
|
138
|
+
async def create_session(self, agent_id: str) -> dict[str, Any]:
|
|
123
139
|
self._draft(agent_id)
|
|
124
140
|
session_id = f"ses_{uuid4().hex}"
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
"
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
"Title": "新会话",
|
|
132
|
-
"CreatedAt": now,
|
|
133
|
-
"UpdatedAt": now,
|
|
134
|
-
}
|
|
135
|
-
}
|
|
141
|
+
session = await self.studio.session_service.create_session(
|
|
142
|
+
agent_id,
|
|
143
|
+
"local-user",
|
|
144
|
+
session_id,
|
|
145
|
+
)
|
|
146
|
+
return {"Session": self._session_metadata_record(session)}
|
|
136
147
|
|
|
137
|
-
def get_session(self, session_id: str) -> dict[str, Any]:
|
|
148
|
+
async def get_session(self, session_id: str) -> dict[str, Any]:
|
|
138
149
|
runs = self.studio.event_store.list_runs(session_id=session_id)
|
|
150
|
+
if runs:
|
|
151
|
+
return {"Session": self._session_record(runs)}
|
|
152
|
+
session = await self.studio.session_service.get_session_metadata(session_id)
|
|
153
|
+
if session is None:
|
|
154
|
+
raise not_found("session", session_id)
|
|
155
|
+
return {"Session": self._session_metadata_record(session)}
|
|
156
|
+
|
|
157
|
+
async def compact_session(self, agent_id: str, session_id: str) -> dict[str, Any]:
|
|
158
|
+
from ksadk.codex.runtime import CodexRuntimeAdapter
|
|
159
|
+
|
|
160
|
+
runs = self.studio.event_store.list_runs(session_id=session_id, agent_id=agent_id)
|
|
139
161
|
if not runs:
|
|
140
162
|
raise not_found("session", session_id)
|
|
141
|
-
|
|
163
|
+
latest = runs[-1]
|
|
164
|
+
if latest.runtime_type != "codex":
|
|
165
|
+
raise StudioError("COMPACTION_UNSUPPORTED", "此运行时尚未提供手动压缩", status_code=409)
|
|
166
|
+
key = (agent_id, session_id)
|
|
167
|
+
service = self.studio.run_service
|
|
168
|
+
if key in service._active_sessions or any(self._active_status(run.status) for run in runs):
|
|
169
|
+
raise StudioError(
|
|
170
|
+
"SESSION_RUN_ACTIVE", "请等待当前运行完成后压缩上下文", status_code=409
|
|
171
|
+
)
|
|
172
|
+
thread_id = str((latest.runtime_handle.get("native_ref") or {}).get("thread_id") or "")
|
|
173
|
+
if not thread_id:
|
|
174
|
+
raise StudioError(
|
|
175
|
+
"CONTEXT_UNAVAILABLE", "此会话尚无可压缩的原生上下文", status_code=409
|
|
176
|
+
)
|
|
177
|
+
service._active_sessions.add(key)
|
|
178
|
+
adapter = None
|
|
179
|
+
try:
|
|
180
|
+
spec = self.studio.resolve_run_spec(latest.build_id, model=latest.model or None)
|
|
181
|
+
adapter = self.studio.runtime_executor.create_adapter(spec.launch_context)
|
|
182
|
+
if not isinstance(adapter, CodexRuntimeAdapter):
|
|
183
|
+
raise StudioError(
|
|
184
|
+
"COMPACTION_UNSUPPORTED", "此运行时尚未提供手动压缩", status_code=409
|
|
185
|
+
)
|
|
186
|
+
usage = await adapter.compact_session(thread_id, dict(spec.request_config))
|
|
187
|
+
last = usage.get("last") or {}
|
|
188
|
+
context_usage = {
|
|
189
|
+
"used_tokens": last.get("totalTokens"),
|
|
190
|
+
"source": "runtime",
|
|
191
|
+
"model": latest.model,
|
|
192
|
+
}
|
|
193
|
+
self.studio.event_store.append(
|
|
194
|
+
latest.id,
|
|
195
|
+
"context.compaction.completed",
|
|
196
|
+
{
|
|
197
|
+
"trigger": "manual",
|
|
198
|
+
"contextUsage": context_usage,
|
|
199
|
+
},
|
|
200
|
+
)
|
|
201
|
+
return {"Status": "completed", "ContextUsage": context_usage}
|
|
202
|
+
finally:
|
|
203
|
+
try:
|
|
204
|
+
if adapter is not None:
|
|
205
|
+
await adapter.close_all()
|
|
206
|
+
finally:
|
|
207
|
+
service._active_sessions.discard(key)
|
|
142
208
|
|
|
143
|
-
def delete_session(self, session_id: str) -> dict[str, Any]:
|
|
144
|
-
self.studio.
|
|
209
|
+
async def delete_session(self, session_id: str) -> dict[str, Any]:
|
|
210
|
+
await self.studio.delete_session(session_id)
|
|
145
211
|
return {}
|
|
146
212
|
|
|
147
213
|
async def list_messages(
|
|
@@ -172,7 +238,14 @@ class StudioSharedWebBridge:
|
|
|
172
238
|
{
|
|
173
239
|
"MessageId": f"{run.id}:assistant",
|
|
174
240
|
"Role": "assistant",
|
|
175
|
-
"Content": {
|
|
241
|
+
"Content": {
|
|
242
|
+
# Run status is metadata, not an assistant reply. An
|
|
243
|
+
# empty pending reply lets canonical reasoning/tools
|
|
244
|
+
# restore without a synthetic status text shadowing them.
|
|
245
|
+
"text": (
|
|
246
|
+
run.output if self._active_status(run.status) else self._run_output(run)
|
|
247
|
+
)
|
|
248
|
+
},
|
|
176
249
|
"Timestamp": self._timestamp(run.completed_at or run.started_at),
|
|
177
250
|
"SeqId": sequence,
|
|
178
251
|
"InvocationId": run.id,
|
|
@@ -180,6 +253,16 @@ class StudioSharedWebBridge:
|
|
|
180
253
|
}
|
|
181
254
|
)
|
|
182
255
|
|
|
256
|
+
extra_events = await self._untracked_runtime_events(session_id, runs)
|
|
257
|
+
if extra_events:
|
|
258
|
+
messages.extend(project_session_messages(extra_events))
|
|
259
|
+
messages.sort(key=lambda item: self._timestamp_value(item["Timestamp"]))
|
|
260
|
+
for sequence, message in enumerate(messages, 1):
|
|
261
|
+
message["SeqId"] = sequence
|
|
262
|
+
if isinstance(message["Timestamp"], (int, float)):
|
|
263
|
+
message["Timestamp"] = self._timestamp(message["Timestamp"])
|
|
264
|
+
message.pop("StartSeqId", None)
|
|
265
|
+
|
|
183
266
|
latest_seq_id = sequence
|
|
184
267
|
if after_seq_id is not None:
|
|
185
268
|
messages = [item for item in messages if item["SeqId"] > after_seq_id]
|
|
@@ -205,12 +288,31 @@ class StudioSharedWebBridge:
|
|
|
205
288
|
events.append(
|
|
206
289
|
{
|
|
207
290
|
"SeqId": sequence,
|
|
208
|
-
"EventType": event.type,
|
|
291
|
+
"EventType": self._shared_event_type(event.type, event.data),
|
|
209
292
|
"InvocationId": run.id,
|
|
210
|
-
"Content": event.data,
|
|
293
|
+
"Content": self._shared_event_content(event.data, run.id),
|
|
211
294
|
"Timestamp": self._timestamp(event.created_at),
|
|
212
295
|
}
|
|
213
296
|
)
|
|
297
|
+
extra_events = await self._untracked_runtime_events(session_id, runs)
|
|
298
|
+
for event in extra_events:
|
|
299
|
+
native = event["Content"]["runtime_event"]
|
|
300
|
+
event_type, content = project_runtime_event(
|
|
301
|
+
parse_runtime_event(native), session_id=session_id
|
|
302
|
+
)
|
|
303
|
+
events.append(
|
|
304
|
+
{
|
|
305
|
+
"SeqId": 0,
|
|
306
|
+
"EventType": self._shared_event_type(event_type, content),
|
|
307
|
+
"InvocationId": event["InvocationId"],
|
|
308
|
+
"Content": content,
|
|
309
|
+
"Timestamp": self._timestamp(event["Timestamp"]),
|
|
310
|
+
}
|
|
311
|
+
)
|
|
312
|
+
if extra_events:
|
|
313
|
+
events.sort(key=lambda item: self._timestamp_value(item["Timestamp"]))
|
|
314
|
+
for sequence, event in enumerate(events, 1):
|
|
315
|
+
event["SeqId"] = sequence
|
|
214
316
|
return {
|
|
215
317
|
"Events": events,
|
|
216
318
|
"Total": len(events),
|
|
@@ -218,6 +320,147 @@ class StudioSharedWebBridge:
|
|
|
218
320
|
"Limit": len(events),
|
|
219
321
|
}
|
|
220
322
|
|
|
323
|
+
async def _untracked_runtime_events(
|
|
324
|
+
self, session_id: str, runs: list[RunRecord]
|
|
325
|
+
) -> list[dict[str, Any]]:
|
|
326
|
+
"""Read Kernel-owned runs absent from Studio's foreground run index.
|
|
327
|
+
|
|
328
|
+
Scheduled runs already have a durable canonical transcript. Project
|
|
329
|
+
that log through the shared message contract, including in sessions
|
|
330
|
+
that also contain foreground turns, without manufacturing RunRecords.
|
|
331
|
+
"""
|
|
332
|
+
tracked = {run.id for run in runs}
|
|
333
|
+
for run in runs:
|
|
334
|
+
tracked.add(str(run.runtime_handle.get("run_id") or ""))
|
|
335
|
+
for event in await self.studio.run_service.events(run.id):
|
|
336
|
+
native = event.data.get("runtimeEvent")
|
|
337
|
+
if isinstance(native, dict):
|
|
338
|
+
tracked.add(str(native.get("run_id") or ""))
|
|
339
|
+
result = []
|
|
340
|
+
for row in await self.studio.session_service.get_events(session_id):
|
|
341
|
+
native = session_event_to_runtime_event(row)
|
|
342
|
+
if native is None or native.run_id in tracked:
|
|
343
|
+
continue
|
|
344
|
+
result.append(
|
|
345
|
+
{
|
|
346
|
+
"EventId": native.event_id,
|
|
347
|
+
"SessionId": session_id,
|
|
348
|
+
"SeqId": row.seq_id,
|
|
349
|
+
"EventType": native.event_type,
|
|
350
|
+
"InvocationId": native.run_id,
|
|
351
|
+
"Timestamp": row.timestamp,
|
|
352
|
+
"Content": {"runtime_event": native.model_dump(mode="json")},
|
|
353
|
+
"Metadata": {"ksadk_canonical_runtime_event": True},
|
|
354
|
+
}
|
|
355
|
+
)
|
|
356
|
+
return result
|
|
357
|
+
|
|
358
|
+
@staticmethod
|
|
359
|
+
def _timestamp_value(value: str | float) -> float:
|
|
360
|
+
if isinstance(value, (float, int)):
|
|
361
|
+
return value
|
|
362
|
+
return datetime.fromisoformat(value.replace("Z", "+00:00")).timestamp() if value else 0
|
|
363
|
+
|
|
364
|
+
@staticmethod
|
|
365
|
+
def _shared_event_type(event_type: str, data: dict[str, Any]) -> str:
|
|
366
|
+
native = data.get("runtimeEvent")
|
|
367
|
+
if (
|
|
368
|
+
event_type == "run.interrupted"
|
|
369
|
+
and isinstance(native, dict)
|
|
370
|
+
and native.get("interaction_id")
|
|
371
|
+
):
|
|
372
|
+
# A resumable interaction is waiting, not a terminal interruption.
|
|
373
|
+
return "run.waiting"
|
|
374
|
+
return event_type
|
|
375
|
+
|
|
376
|
+
@staticmethod
|
|
377
|
+
def _shared_event_content(data: dict[str, Any], run_id: str) -> dict[str, Any]:
|
|
378
|
+
"""Use the public Studio run identity in shared-Web history projections.
|
|
379
|
+
|
|
380
|
+
The persisted canonical event retains the adapter's native run ID.
|
|
381
|
+
ListSessionMessages uses the Studio ID, so its event projection must
|
|
382
|
+
use the same ID or hydration retains both copies of the answer.
|
|
383
|
+
"""
|
|
384
|
+
native = data.get("runtimeEvent")
|
|
385
|
+
if not isinstance(native, dict):
|
|
386
|
+
return data
|
|
387
|
+
return {**data, "runtimeEvent": {**native, "run_id": run_id}}
|
|
388
|
+
|
|
389
|
+
async def subscription_run_id(self, session_id: str, invocation_id: str) -> str:
|
|
390
|
+
run_id = self._run_ids_by_invocation.get(invocation_id, invocation_id)
|
|
391
|
+
try:
|
|
392
|
+
run = self.studio.event_store.get(run_id)
|
|
393
|
+
except StudioError as error:
|
|
394
|
+
if error.code != "RUN_NOT_FOUND":
|
|
395
|
+
raise
|
|
396
|
+
else:
|
|
397
|
+
if run.session_id != session_id:
|
|
398
|
+
raise not_found("run", invocation_id)
|
|
399
|
+
return run_id
|
|
400
|
+
for row in await self.studio.session_service.get_events(session_id):
|
|
401
|
+
native = session_event_to_runtime_event(row)
|
|
402
|
+
if native is not None and native.run_id == run_id:
|
|
403
|
+
return run_id
|
|
404
|
+
raise not_found("run", invocation_id)
|
|
405
|
+
|
|
406
|
+
async def subscribe_run_events(
|
|
407
|
+
self,
|
|
408
|
+
session_id: str,
|
|
409
|
+
invocation_id: str,
|
|
410
|
+
*,
|
|
411
|
+
after_seq_id: int = 0,
|
|
412
|
+
) -> AsyncIterator[str]:
|
|
413
|
+
run_id = await self.subscription_run_id(session_id, invocation_id)
|
|
414
|
+
runs = self.studio.event_store.list_runs(session_id=session_id)
|
|
415
|
+
if await self._untracked_runtime_events(session_id, runs):
|
|
416
|
+
cursor = after_seq_id
|
|
417
|
+
while True:
|
|
418
|
+
history = await self.list_session_events(session_id)
|
|
419
|
+
run_events = [
|
|
420
|
+
event for event in history["Events"] if event["InvocationId"] == run_id
|
|
421
|
+
]
|
|
422
|
+
for event in run_events:
|
|
423
|
+
if event["SeqId"] > cursor:
|
|
424
|
+
yield self._sse("message", {**event, "SessionId": session_id})
|
|
425
|
+
cursor = event["SeqId"]
|
|
426
|
+
if any(
|
|
427
|
+
event["EventType"]
|
|
428
|
+
in {"run.completed", "run.failed", "run.cancelled", "run.interrupted"}
|
|
429
|
+
for event in run_events
|
|
430
|
+
):
|
|
431
|
+
yield "event: done\ndata: [DONE]\n\n"
|
|
432
|
+
return
|
|
433
|
+
yield ": ping\n\n"
|
|
434
|
+
await asyncio.sleep(0.25)
|
|
435
|
+
# Match ListSessionEvents' session cursor without rereading every old
|
|
436
|
+
# run on every live poll. Only the subscribed run can still grow.
|
|
437
|
+
offset = 0
|
|
438
|
+
for record in self.studio.event_store.list_runs(session_id=session_id):
|
|
439
|
+
if record.id == run_id:
|
|
440
|
+
break
|
|
441
|
+
offset += len(self.studio.event_store.events(record.id))
|
|
442
|
+
cursor = max(0, after_seq_id - offset)
|
|
443
|
+
while True:
|
|
444
|
+
for event in await self.studio.run_service.events(run_id, after=cursor):
|
|
445
|
+
cursor = max(cursor, event.id)
|
|
446
|
+
yield self._sse(
|
|
447
|
+
"message",
|
|
448
|
+
{
|
|
449
|
+
"SeqId": offset + event.id,
|
|
450
|
+
"SessionId": session_id,
|
|
451
|
+
"InvocationId": invocation_id,
|
|
452
|
+
"EventType": self._shared_event_type(event.type, event.data),
|
|
453
|
+
"Content": self._shared_event_content(event.data, run_id),
|
|
454
|
+
"Timestamp": self._timestamp(event.created_at),
|
|
455
|
+
},
|
|
456
|
+
)
|
|
457
|
+
record = self.studio.event_store.get(run_id)
|
|
458
|
+
if not self._active_status(record.status):
|
|
459
|
+
yield "event: done\ndata: [DONE]\n\n"
|
|
460
|
+
return
|
|
461
|
+
yield ": ping\n\n"
|
|
462
|
+
await asyncio.sleep(0.25)
|
|
463
|
+
|
|
221
464
|
def cancel_run(self, invocation_id: str) -> dict[str, Any]:
|
|
222
465
|
operation_id = self._operations_by_invocation.get(invocation_id)
|
|
223
466
|
if operation_id:
|
|
@@ -240,19 +483,46 @@ class StudioSharedWebBridge:
|
|
|
240
483
|
run_id = self._response_runs.get(response_id, response_id)
|
|
241
484
|
return self.studio.event_store.get(run_id).session_id
|
|
242
485
|
|
|
243
|
-
async def stream_run(
|
|
486
|
+
async def stream_run(
|
|
487
|
+
self, payload: dict[str, Any], *, shared_ui: bool = False
|
|
488
|
+
) -> AsyncIterator[str]:
|
|
244
489
|
agent_id = self.resolve_agent_id(str(payload.get("AgentId") or "") or None)
|
|
245
490
|
session_id = str(payload.get("SessionId") or f"ses_{uuid4().hex}")
|
|
246
491
|
invocation_id = str(payload.get("InvocationId") or f"resp_{uuid4().hex}")
|
|
247
492
|
prompt = self._input_text(payload)
|
|
248
493
|
runtime_input = self._runtime_input(payload)
|
|
249
494
|
model = self._select_model(agent_id, str(payload.get("Model") or ""))
|
|
250
|
-
|
|
251
|
-
collaboration_mode =
|
|
252
|
-
|
|
253
|
-
|
|
495
|
+
model_explicit = bool(payload.get("ModelExplicit", str(payload.get("Model") or "")))
|
|
496
|
+
approval_mode, collaboration_mode, goal_objective, reasoning_effort = (
|
|
497
|
+
self._request_controls(payload)
|
|
498
|
+
)
|
|
499
|
+
try:
|
|
500
|
+
build = await self._ensure_build(agent_id)
|
|
501
|
+
self._validate_conversation_turn(
|
|
502
|
+
build_id=build.id,
|
|
503
|
+
session_id=session_id,
|
|
504
|
+
invocation_id=invocation_id,
|
|
505
|
+
prompt=prompt,
|
|
506
|
+
runtime_input=runtime_input,
|
|
507
|
+
model=model if model_explicit else "",
|
|
508
|
+
approval_mode=approval_mode,
|
|
509
|
+
collaboration_mode=collaboration_mode,
|
|
510
|
+
goal_objective=goal_objective,
|
|
511
|
+
reasoning_effort=reasoning_effort,
|
|
512
|
+
)
|
|
513
|
+
except StudioError as exc:
|
|
514
|
+
# StreamingResponse starts the HTTP response before advancing this
|
|
515
|
+
# generator. Preflight failures therefore belong in the stream;
|
|
516
|
+
# raising here would turn an actionable Studio error into Starlette's
|
|
517
|
+
# "response already started" RuntimeError.
|
|
518
|
+
yield self._failed_sse(invocation_id, exc.message)
|
|
519
|
+
return
|
|
520
|
+
except Exception:
|
|
521
|
+
yield self._failed_sse(invocation_id, "本地 Agent 运行失败")
|
|
522
|
+
return
|
|
254
523
|
execution = asyncio.create_task(
|
|
255
524
|
self._execute_run(
|
|
525
|
+
build=build,
|
|
256
526
|
agent_id=agent_id,
|
|
257
527
|
session_id=session_id,
|
|
258
528
|
invocation_id=invocation_id,
|
|
@@ -304,6 +574,15 @@ class StudioSharedWebBridge:
|
|
|
304
574
|
if event_name == "response.output_text.delta":
|
|
305
575
|
emitted_text += str(event_payload.get("delta") or "")
|
|
306
576
|
yield self._sse(event_name, event_payload)
|
|
577
|
+
if (
|
|
578
|
+
shared_ui
|
|
579
|
+
and event_name == "a2ui.interaction"
|
|
580
|
+
and event_payload.get("kind") in {"form", "structured_input"}
|
|
581
|
+
):
|
|
582
|
+
# The shared UI restores the durable Interaction/v1
|
|
583
|
+
# request, then subscribes to this same live run.
|
|
584
|
+
# Leave the execution attached while input is pending.
|
|
585
|
+
return
|
|
307
586
|
else:
|
|
308
587
|
idle_polls += 1
|
|
309
588
|
if idle_polls >= 20:
|
|
@@ -355,17 +634,33 @@ class StudioSharedWebBridge:
|
|
|
355
634
|
session_id = str(payload.get("SessionId") or f"ses_{uuid4().hex}")
|
|
356
635
|
invocation_id = str(payload.get("InvocationId") or f"resp_{uuid4().hex}")
|
|
357
636
|
model = self._select_model(agent_id, str(payload.get("Model") or ""))
|
|
358
|
-
|
|
359
|
-
collaboration_mode =
|
|
360
|
-
|
|
361
|
-
|
|
637
|
+
model_explicit = bool(payload.get("ModelExplicit", str(payload.get("Model") or "")))
|
|
638
|
+
approval_mode, collaboration_mode, goal_objective, reasoning_effort = (
|
|
639
|
+
self._request_controls(payload)
|
|
640
|
+
)
|
|
641
|
+
build = await self._ensure_build(agent_id)
|
|
642
|
+
prompt = self._input_text(payload)
|
|
643
|
+
runtime_input = self._runtime_input(payload)
|
|
644
|
+
self._validate_conversation_turn(
|
|
645
|
+
build_id=build.id,
|
|
646
|
+
session_id=session_id,
|
|
647
|
+
invocation_id=invocation_id,
|
|
648
|
+
prompt=prompt,
|
|
649
|
+
runtime_input=runtime_input,
|
|
650
|
+
model=model if model_explicit else "",
|
|
651
|
+
approval_mode=approval_mode,
|
|
652
|
+
collaboration_mode=collaboration_mode,
|
|
653
|
+
goal_objective=goal_objective,
|
|
654
|
+
reasoning_effort=reasoning_effort,
|
|
655
|
+
)
|
|
362
656
|
try:
|
|
363
657
|
run = await self._execute_run(
|
|
658
|
+
build=build,
|
|
364
659
|
agent_id=agent_id,
|
|
365
660
|
session_id=session_id,
|
|
366
661
|
invocation_id=invocation_id,
|
|
367
|
-
prompt=
|
|
368
|
-
runtime_input=
|
|
662
|
+
prompt=prompt,
|
|
663
|
+
runtime_input=runtime_input,
|
|
369
664
|
model=model,
|
|
370
665
|
approval_mode=approval_mode,
|
|
371
666
|
collaboration_mode=collaboration_mode,
|
|
@@ -383,6 +678,7 @@ class StudioSharedWebBridge:
|
|
|
383
678
|
async def _execute_run(
|
|
384
679
|
self,
|
|
385
680
|
*,
|
|
681
|
+
build: Any = None,
|
|
386
682
|
agent_id: str,
|
|
387
683
|
session_id: str,
|
|
388
684
|
invocation_id: str,
|
|
@@ -394,7 +690,15 @@ class StudioSharedWebBridge:
|
|
|
394
690
|
goal_objective: str = "",
|
|
395
691
|
reasoning_effort: str = "",
|
|
396
692
|
) -> RunRecord:
|
|
397
|
-
build
|
|
693
|
+
if build is None:
|
|
694
|
+
build = await self._ensure_build(agent_id)
|
|
695
|
+
bound_agent = str(getattr(build, "agent_name", None) or getattr(build, "agent_id", ""))
|
|
696
|
+
if bound_agent != agent_id:
|
|
697
|
+
raise StudioError(
|
|
698
|
+
"CONVERSATION_BUILD_MISMATCH",
|
|
699
|
+
"会话 Build 不属于当前 Agent",
|
|
700
|
+
status_code=409,
|
|
701
|
+
)
|
|
398
702
|
|
|
399
703
|
def observe(event: Any) -> None:
|
|
400
704
|
if event.type == "run.created":
|
|
@@ -522,6 +826,23 @@ class StudioSharedWebBridge:
|
|
|
522
826
|
)
|
|
523
827
|
)
|
|
524
828
|
continue
|
|
829
|
+
if event.type == "approval.resolved":
|
|
830
|
+
projected.append(
|
|
831
|
+
(
|
|
832
|
+
"response.ksadk.approval_resolved",
|
|
833
|
+
{
|
|
834
|
+
"type": "response.ksadk.approval_resolved",
|
|
835
|
+
"approvalRequestId": event.data.get("approvalId")
|
|
836
|
+
or event.data.get("interactionId"),
|
|
837
|
+
"decision": event.data.get("decision")
|
|
838
|
+
or event.data.get("name")
|
|
839
|
+
or "approved",
|
|
840
|
+
"revision": event.data.get("revision") or 2,
|
|
841
|
+
"runId": run.id,
|
|
842
|
+
},
|
|
843
|
+
)
|
|
844
|
+
)
|
|
845
|
+
continue
|
|
525
846
|
item_event = self._response_item_event(event.type, event.data, starts)
|
|
526
847
|
if item_event is not None:
|
|
527
848
|
projected.append(item_event)
|
|
@@ -550,7 +871,9 @@ class StudioSharedWebBridge:
|
|
|
550
871
|
"status": (
|
|
551
872
|
"failed"
|
|
552
873
|
if event_type.endswith("failed") or data.get("exitCode") not in {None, 0}
|
|
553
|
-
else "completed"
|
|
874
|
+
else "completed"
|
|
875
|
+
if done
|
|
876
|
+
else "in_progress"
|
|
554
877
|
),
|
|
555
878
|
"action": {
|
|
556
879
|
"commands": [command],
|
|
@@ -571,17 +894,24 @@ class StudioSharedWebBridge:
|
|
|
571
894
|
"status": (
|
|
572
895
|
"failed"
|
|
573
896
|
if event_type.endswith("failed")
|
|
574
|
-
else "completed"
|
|
897
|
+
else "completed"
|
|
898
|
+
if done
|
|
899
|
+
else "in_progress"
|
|
575
900
|
),
|
|
576
901
|
"output": data.get("output") or data.get("result") or "",
|
|
577
902
|
}
|
|
578
903
|
elif event_type == "approval.requested":
|
|
904
|
+
approval_id = str(data.get("approvalId") or data.get("interactionId") or call_id or "")
|
|
905
|
+
detail = data.get("detail")
|
|
906
|
+
arguments = detail if isinstance(detail, dict) else {"detail": detail}
|
|
579
907
|
item = {
|
|
580
|
-
"id":
|
|
908
|
+
"id": approval_id or f"approval_{uuid4().hex}",
|
|
581
909
|
"call_id": call_id,
|
|
582
|
-
"type": "
|
|
910
|
+
"type": "mcp_approval_request",
|
|
911
|
+
"name": str(data.get("kind") or started.get("tool") or "人工确认"),
|
|
912
|
+
"arguments": json.dumps(arguments, ensure_ascii=False),
|
|
913
|
+
"run_id": str(data.get("runId") or ""),
|
|
583
914
|
"status": "in_progress",
|
|
584
|
-
"action": data,
|
|
585
915
|
}
|
|
586
916
|
else:
|
|
587
917
|
return None
|
|
@@ -659,39 +989,138 @@ class StudioSharedWebBridge:
|
|
|
659
989
|
}
|
|
660
990
|
|
|
661
991
|
async def _ensure_build(self, agent_id: str):
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
992
|
+
return await self.studio.ensure_current_build(agent_id)
|
|
993
|
+
|
|
994
|
+
def _validate_conversation_turn(
|
|
995
|
+
self,
|
|
996
|
+
*,
|
|
997
|
+
build_id: str,
|
|
998
|
+
session_id: str,
|
|
999
|
+
invocation_id: str,
|
|
1000
|
+
prompt: str,
|
|
1001
|
+
runtime_input: Any,
|
|
1002
|
+
model: str,
|
|
1003
|
+
approval_mode: str,
|
|
1004
|
+
collaboration_mode: str,
|
|
1005
|
+
goal_objective: str,
|
|
1006
|
+
reasoning_effort: str,
|
|
1007
|
+
) -> None:
|
|
1008
|
+
"""Revalidate compatibility requests against the active Surface.
|
|
1009
|
+
|
|
1010
|
+
`/v1/responses` and the legacy RunAgent action remain supported wire
|
|
1011
|
+
shapes, but neither may smuggle provider-only input past the shared
|
|
1012
|
+
ConversationInput contract.
|
|
1013
|
+
"""
|
|
1014
|
+
|
|
1015
|
+
surface = self.studio.conversation_surface(build_id, session_id=session_id)
|
|
1016
|
+
parts: list[ConversationTextPart | ConversationAttachmentPart] = [
|
|
1017
|
+
ConversationTextPart(text=prompt)
|
|
1018
|
+
]
|
|
1019
|
+
for index, item in enumerate(runtime_input if isinstance(runtime_input, list) else []):
|
|
1020
|
+
if not isinstance(item, dict):
|
|
1021
|
+
continue
|
|
1022
|
+
kind = str(item.get("type") or "")
|
|
1023
|
+
if kind in {"image", "input_image"}:
|
|
1024
|
+
media_type = self._data_url_media_type(
|
|
1025
|
+
str(item.get("url") or item.get("image_url") or ""),
|
|
1026
|
+
fallback="image/*",
|
|
1027
|
+
)
|
|
1028
|
+
parts.append(
|
|
1029
|
+
ConversationAttachmentPart(
|
|
1030
|
+
attachment_ref=f"attachment://inline/{invocation_id}/{index}",
|
|
1031
|
+
media_type=media_type,
|
|
1032
|
+
name=str(item.get("filename") or "image"),
|
|
1033
|
+
)
|
|
1034
|
+
)
|
|
1035
|
+
elif kind == "input_file":
|
|
1036
|
+
parts.append(
|
|
1037
|
+
ConversationAttachmentPart(
|
|
1038
|
+
attachment_ref=f"attachment://inline/{invocation_id}/{index}",
|
|
1039
|
+
media_type=self._data_url_media_type(
|
|
1040
|
+
str(item.get("file_data") or item.get("file_url") or ""),
|
|
1041
|
+
fallback="application/octet-stream",
|
|
1042
|
+
),
|
|
1043
|
+
name=str(item.get("filename") or "attachment"),
|
|
1044
|
+
)
|
|
1045
|
+
)
|
|
1046
|
+
conversation_input = ConversationInput(
|
|
1047
|
+
input_id=invocation_id,
|
|
1048
|
+
session_id=session_id,
|
|
1049
|
+
idempotency_key=f"responses:{invocation_id}",
|
|
1050
|
+
parts=tuple(parts),
|
|
1051
|
+
model_ref=model or None,
|
|
1052
|
+
reasoning=reasoning_effort or None,
|
|
1053
|
+
extensions={
|
|
1054
|
+
key: value
|
|
1055
|
+
for key, value in (
|
|
1056
|
+
(APPROVAL_MODE_EXTENSION, approval_mode or None),
|
|
1057
|
+
(COLLABORATION_MODE_EXTENSION, collaboration_mode or None),
|
|
1058
|
+
(GOAL_OBJECTIVE_EXTENSION, goal_objective or None),
|
|
1059
|
+
)
|
|
1060
|
+
if value is not None
|
|
1061
|
+
},
|
|
1062
|
+
)
|
|
1063
|
+
try:
|
|
1064
|
+
validate_conversation_input(surface, conversation_input)
|
|
1065
|
+
except ValueError as exc:
|
|
677
1066
|
raise StudioError(
|
|
678
|
-
"
|
|
679
|
-
"当前 Agent
|
|
680
|
-
"API Key 只提供访问凭证,不会自动绑定模型。",
|
|
1067
|
+
"CONVERSATION_INPUT_UNSUPPORTED",
|
|
1068
|
+
"当前 Agent 不支持此会话输入",
|
|
681
1069
|
status_code=422,
|
|
682
|
-
|
|
683
|
-
)
|
|
684
|
-
|
|
1070
|
+
details={"reason": str(exc), "surfaceId": surface.surface_id},
|
|
1071
|
+
) from exc
|
|
1072
|
+
|
|
1073
|
+
@staticmethod
|
|
1074
|
+
def _data_url_media_type(value: str, *, fallback: str) -> str:
|
|
1075
|
+
if value.startswith("data:"):
|
|
1076
|
+
media_type = value[5:].split(";", 1)[0].strip().lower()
|
|
1077
|
+
if media_type:
|
|
1078
|
+
return media_type
|
|
1079
|
+
return fallback
|
|
685
1080
|
|
|
686
|
-
def _sessions(self, agent_id: str) -> list[dict[str, Any]]:
|
|
1081
|
+
async def _sessions(self, agent_id: str) -> list[dict[str, Any]]:
|
|
1082
|
+
persisted = await self.studio.session_service.list_session_metadata(
|
|
1083
|
+
agent_id=agent_id,
|
|
1084
|
+
)
|
|
1085
|
+
records = {
|
|
1086
|
+
session.id: self._session_metadata_record(session)
|
|
1087
|
+
for session in persisted
|
|
1088
|
+
if session.user_id in {"local-user", "local-studio"}
|
|
1089
|
+
}
|
|
687
1090
|
grouped: dict[str, list[RunRecord]] = {}
|
|
688
1091
|
for run in self.studio.event_store.list_runs():
|
|
689
1092
|
if run.agent_id != agent_id:
|
|
690
1093
|
continue
|
|
691
1094
|
grouped.setdefault(run.session_id, []).append(run)
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
1095
|
+
for session_id, runs in grouped.items():
|
|
1096
|
+
records[session_id] = self._session_record(runs)
|
|
1097
|
+
ordered = list(records.values())
|
|
1098
|
+
ordered.sort(key=lambda item: item["UpdatedAt"], reverse=True)
|
|
1099
|
+
return ordered
|
|
1100
|
+
|
|
1101
|
+
def _session_metadata_record(self, session: Session) -> dict[str, Any]:
|
|
1102
|
+
title = session.title
|
|
1103
|
+
if not title and session.first_prompt:
|
|
1104
|
+
title = self._short_title(session.first_prompt)
|
|
1105
|
+
return {
|
|
1106
|
+
"SessionId": session.id,
|
|
1107
|
+
"AgentId": session.agent_id,
|
|
1108
|
+
"UserId": session.user_id or "local-user",
|
|
1109
|
+
"Title": title or "新会话",
|
|
1110
|
+
"FirstPrompt": session.first_prompt,
|
|
1111
|
+
"LastPrompt": session.last_prompt,
|
|
1112
|
+
"CreatedAt": self._timestamp(session.created_at),
|
|
1113
|
+
"UpdatedAt": self._timestamp(session.updated_at),
|
|
1114
|
+
"ActiveRunStatus": "",
|
|
1115
|
+
"ActiveInvocationId": "",
|
|
1116
|
+
"TokenUsage": {
|
|
1117
|
+
"input_tokens": 0,
|
|
1118
|
+
"output_tokens": 0,
|
|
1119
|
+
"total_tokens": 0,
|
|
1120
|
+
"turns": 0,
|
|
1121
|
+
"last_response_id": "",
|
|
1122
|
+
},
|
|
1123
|
+
}
|
|
695
1124
|
|
|
696
1125
|
def _session_record(self, runs: list[RunRecord]) -> dict[str, Any]:
|
|
697
1126
|
ordered = sorted(
|
|
@@ -702,6 +1131,7 @@ class StudioSharedWebBridge:
|
|
|
702
1131
|
)
|
|
703
1132
|
first = ordered[0]
|
|
704
1133
|
latest = ordered[-1]
|
|
1134
|
+
active = next((run for run in reversed(ordered) if self._active_status(run.status)), None)
|
|
705
1135
|
usage = {
|
|
706
1136
|
"input_tokens": sum(run.usage.input_tokens for run in ordered),
|
|
707
1137
|
"output_tokens": sum(run.usage.output_tokens for run in ordered),
|
|
@@ -718,11 +1148,26 @@ class StudioSharedWebBridge:
|
|
|
718
1148
|
"LastPrompt": latest.input,
|
|
719
1149
|
"CreatedAt": self._timestamp(first.started_at),
|
|
720
1150
|
"UpdatedAt": self._timestamp(latest.completed_at or latest.started_at),
|
|
721
|
-
"ActiveRunStatus": self._active_status(
|
|
722
|
-
"ActiveInvocationId":
|
|
1151
|
+
"ActiveRunStatus": self._active_status(active.status) if active else "",
|
|
1152
|
+
"ActiveInvocationId": active.id if active else "",
|
|
723
1153
|
"TokenUsage": usage,
|
|
1154
|
+
"ContextUsage": self._context_usage(latest),
|
|
724
1155
|
}
|
|
725
1156
|
|
|
1157
|
+
def _context_usage(self, latest: RunRecord) -> dict[str, Any] | None:
|
|
1158
|
+
if latest.runtime_type != "codex":
|
|
1159
|
+
return None
|
|
1160
|
+
for event in reversed(self.studio.event_store.events(latest.id)):
|
|
1161
|
+
if event.type == "context.compaction.completed":
|
|
1162
|
+
return event.data.get("contextUsage")
|
|
1163
|
+
if latest.runtime_type == "codex" and latest.usage.input_tokens > 0:
|
|
1164
|
+
return {
|
|
1165
|
+
"used_tokens": latest.usage.input_tokens,
|
|
1166
|
+
"source": "last_request",
|
|
1167
|
+
"model": latest.model,
|
|
1168
|
+
}
|
|
1169
|
+
return None
|
|
1170
|
+
|
|
726
1171
|
def _model_descriptor(
|
|
727
1172
|
self, agent_id: str, models: list[dict[str, Any]] | None = None
|
|
728
1173
|
) -> dict[str, Any]:
|
|
@@ -799,7 +1244,7 @@ class StudioSharedWebBridge:
|
|
|
799
1244
|
"id": model_name,
|
|
800
1245
|
"display_name": model_name,
|
|
801
1246
|
"source": "agentkit-studio",
|
|
802
|
-
"
|
|
1247
|
+
"input_budget_tokens": draft.spec.context.max_input_tokens,
|
|
803
1248
|
"max_output_tokens": 2048,
|
|
804
1249
|
"capabilities": {
|
|
805
1250
|
"function_calling": True,
|
|
@@ -824,8 +1269,8 @@ class StudioSharedWebBridge:
|
|
|
824
1269
|
"id": model_id,
|
|
825
1270
|
"display_name": resolved_display_name,
|
|
826
1271
|
"source": "agentkit-studio",
|
|
827
|
-
"context_window_tokens": metadata.get("context_window_tokens")
|
|
828
|
-
|
|
1272
|
+
"context_window_tokens": metadata.get("context_window_tokens"),
|
|
1273
|
+
"input_budget_tokens": draft.spec.context.max_input_tokens,
|
|
829
1274
|
"max_output_tokens": max_output_tokens,
|
|
830
1275
|
"capabilities": {
|
|
831
1276
|
**dict(metadata.get("capabilities") or {}),
|
|
@@ -843,7 +1288,7 @@ class StudioSharedWebBridge:
|
|
|
843
1288
|
"id": model_id,
|
|
844
1289
|
"display_name": model_id if model_id != "unconfigured-model" else "未配置模型",
|
|
845
1290
|
"source": "agentkit-studio",
|
|
846
|
-
"
|
|
1291
|
+
"input_budget_tokens": draft.spec.context.max_input_tokens,
|
|
847
1292
|
"max_output_tokens": 2048,
|
|
848
1293
|
"capabilities": {
|
|
849
1294
|
"function_calling": True,
|
|
@@ -869,7 +1314,7 @@ class StudioSharedWebBridge:
|
|
|
869
1314
|
return self.studio.agent_detail(agent_id)["draft"]
|
|
870
1315
|
|
|
871
1316
|
async def _run_activities(self, run: RunRecord) -> list[dict[str, Any]]:
|
|
872
|
-
activities:
|
|
1317
|
+
activities: dict[str, dict[str, Any]] = {}
|
|
873
1318
|
for event in await self.studio.run_service.events(run.id):
|
|
874
1319
|
operations = (
|
|
875
1320
|
event.data.get("a2uiOperations")
|
|
@@ -881,16 +1326,78 @@ class StudioSharedWebBridge:
|
|
|
881
1326
|
surface_id = str(
|
|
882
1327
|
event.data.get("surfaceId") or event.data.get("surface_id") or f"{run.id}-surface"
|
|
883
1328
|
)
|
|
884
|
-
activities.
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
"Content": {"a2ui_operations": operations},
|
|
891
|
-
}
|
|
1329
|
+
previous = activities.get(surface_id)
|
|
1330
|
+
# Snapshot updates may repeat createSurface; only the latest full
|
|
1331
|
+
# snapshot should become a history row. Delta-only batches append.
|
|
1332
|
+
reset = any(isinstance(op, dict) and "createSurface" in op for op in operations)
|
|
1333
|
+
previous_operations = (
|
|
1334
|
+
previous["Content"]["a2ui_operations"] if previous and not reset else []
|
|
892
1335
|
)
|
|
893
|
-
|
|
1336
|
+
activities[surface_id] = {
|
|
1337
|
+
"SeqId": event.id,
|
|
1338
|
+
"Type": event.type,
|
|
1339
|
+
"MessageId": f"{run.id}:assistant",
|
|
1340
|
+
"SurfaceId": surface_id,
|
|
1341
|
+
"Content": {"a2ui_operations": [*previous_operations, *operations]},
|
|
1342
|
+
}
|
|
1343
|
+
return list(activities.values())
|
|
1344
|
+
|
|
1345
|
+
@staticmethod
|
|
1346
|
+
def _request_controls(payload: dict[str, Any]) -> tuple[str, str, str, str]:
|
|
1347
|
+
"""Read turn controls from both legacy and shared-Web request shapes."""
|
|
1348
|
+
|
|
1349
|
+
metadata = payload.get("Metadata") or payload.get("metadata")
|
|
1350
|
+
metadata = metadata if isinstance(metadata, dict) else {}
|
|
1351
|
+
agentengine = metadata.get("agentengine")
|
|
1352
|
+
agentengine = agentengine if isinstance(agentengine, dict) else {}
|
|
1353
|
+
model_options = payload.get("ModelOptions") or payload.get("model_options")
|
|
1354
|
+
model_options = model_options if isinstance(model_options, dict) else {}
|
|
1355
|
+
|
|
1356
|
+
approval_mode = (
|
|
1357
|
+
str(
|
|
1358
|
+
payload.get("ApprovalMode")
|
|
1359
|
+
or payload.get("approval_mode")
|
|
1360
|
+
or metadata.get("approval_mode")
|
|
1361
|
+
or metadata.get("approvalMode")
|
|
1362
|
+
or agentengine.get("tool_approval_mode")
|
|
1363
|
+
or agentengine.get("approval_mode")
|
|
1364
|
+
or ""
|
|
1365
|
+
)
|
|
1366
|
+
.strip()
|
|
1367
|
+
.lower()
|
|
1368
|
+
)
|
|
1369
|
+
collaboration_mode = (
|
|
1370
|
+
str(
|
|
1371
|
+
payload.get("CollaborationMode")
|
|
1372
|
+
or payload.get("collaboration_mode")
|
|
1373
|
+
or metadata.get("collaboration_mode")
|
|
1374
|
+
or metadata.get("collaborationMode")
|
|
1375
|
+
or agentengine.get("collaboration_mode")
|
|
1376
|
+
or ""
|
|
1377
|
+
)
|
|
1378
|
+
.strip()
|
|
1379
|
+
.lower()
|
|
1380
|
+
)
|
|
1381
|
+
goal_objective = str(
|
|
1382
|
+
payload.get("GoalObjective")
|
|
1383
|
+
or payload.get("goal_objective")
|
|
1384
|
+
or metadata.get("goal_objective")
|
|
1385
|
+
or metadata.get("goalObjective")
|
|
1386
|
+
or agentengine.get("goal_objective")
|
|
1387
|
+
or ""
|
|
1388
|
+
).strip()
|
|
1389
|
+
reasoning_effort = (
|
|
1390
|
+
str(
|
|
1391
|
+
payload.get("ReasoningEffort")
|
|
1392
|
+
or payload.get("reasoning_effort")
|
|
1393
|
+
or model_options.get("reasoning_effort")
|
|
1394
|
+
or model_options.get("reasoningEffort")
|
|
1395
|
+
or ""
|
|
1396
|
+
)
|
|
1397
|
+
.strip()
|
|
1398
|
+
.lower()
|
|
1399
|
+
)
|
|
1400
|
+
return approval_mode, collaboration_mode, goal_objective, reasoning_effort
|
|
894
1401
|
|
|
895
1402
|
@staticmethod
|
|
896
1403
|
def _input_text(payload: dict[str, Any]) -> str:
|
|
@@ -939,7 +1446,7 @@ class StudioSharedWebBridge:
|
|
|
939
1446
|
if not isinstance(content, list):
|
|
940
1447
|
continue
|
|
941
1448
|
items: list[dict[str, str]] = []
|
|
942
|
-
|
|
1449
|
+
has_attachment = False
|
|
943
1450
|
for part in content:
|
|
944
1451
|
if not isinstance(part, dict):
|
|
945
1452
|
continue
|
|
@@ -954,14 +1461,25 @@ class StudioSharedWebBridge:
|
|
|
954
1461
|
)
|
|
955
1462
|
if url:
|
|
956
1463
|
items.append({"type": "image", "url": url})
|
|
957
|
-
|
|
958
|
-
|
|
1464
|
+
has_attachment = True
|
|
1465
|
+
elif kind == "input_file":
|
|
1466
|
+
data = str(part.get("file_data") or part.get("file_url") or "")
|
|
1467
|
+
if data:
|
|
1468
|
+
items.append(
|
|
1469
|
+
{
|
|
1470
|
+
"type": "input_file",
|
|
1471
|
+
"file_data": data,
|
|
1472
|
+
"filename": str(part.get("filename") or "attachment"),
|
|
1473
|
+
}
|
|
1474
|
+
)
|
|
1475
|
+
has_attachment = True
|
|
1476
|
+
if items and has_attachment:
|
|
959
1477
|
return items
|
|
960
1478
|
return []
|
|
961
1479
|
|
|
962
1480
|
@staticmethod
|
|
963
1481
|
def _active_status(status: RunStatus) -> str:
|
|
964
|
-
return "running" if status
|
|
1482
|
+
return "running" if status in {RunStatus.RUNNING, RunStatus.WAITING_INPUT} else ""
|
|
965
1483
|
|
|
966
1484
|
@staticmethod
|
|
967
1485
|
def _run_output(run: RunRecord) -> str:
|
|
@@ -969,7 +1487,8 @@ class StudioSharedWebBridge:
|
|
|
969
1487
|
return run.output
|
|
970
1488
|
if run.error:
|
|
971
1489
|
return str(run.error.get("message") or "Agent 运行失败")
|
|
972
|
-
|
|
1490
|
+
status = run.status.value if isinstance(run.status, RunStatus) else str(run.status)
|
|
1491
|
+
return f"运行状态:{status}"
|
|
973
1492
|
|
|
974
1493
|
@staticmethod
|
|
975
1494
|
def _short_title(value: str, limit: int = 36) -> str:
|
|
@@ -977,8 +1496,12 @@ class StudioSharedWebBridge:
|
|
|
977
1496
|
return text if len(text) <= limit else f"{text[:limit]}..."
|
|
978
1497
|
|
|
979
1498
|
@staticmethod
|
|
980
|
-
def _timestamp(value: datetime | None) -> str:
|
|
981
|
-
|
|
1499
|
+
def _timestamp(value: datetime | float | int | None) -> str:
|
|
1500
|
+
if isinstance(value, datetime):
|
|
1501
|
+
return value.isoformat()
|
|
1502
|
+
if isinstance(value, (float, int)):
|
|
1503
|
+
return datetime.fromtimestamp(value, tz=timezone.utc).isoformat()
|
|
1504
|
+
return datetime.now(timezone.utc).isoformat()
|
|
982
1505
|
|
|
983
1506
|
@staticmethod
|
|
984
1507
|
def _sse(event: str, payload: dict[str, Any]) -> str:
|