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.
Files changed (563) hide show
  1. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/METADATA +22 -28
  2. agentengine_sdk_python-0.8.4.dist-info/RECORD +1070 -0
  3. ksadk/_build_provenance.json +1 -0
  4. ksadk/agui/_agent_helpers.py +4 -0
  5. ksadk/api/client.py +108 -91
  6. ksadk/builders/code_builder.py +36 -9
  7. ksadk/builders/framework_requirements.py +2 -1
  8. ksadk/builders/ks3_uploader.py +36 -7
  9. ksadk/builders/managed_runtime_builder.py +4 -0
  10. ksadk/cli/__init__.py +38 -3
  11. ksadk/cli/cmd_managed_runtime.py +13 -1
  12. ksadk/cli/cmd_plugin.py +662 -0
  13. ksadk/cli/cmd_web.py +2 -5
  14. ksadk/cli/runtime_bootstrap.py +23 -1
  15. ksadk/codex/client.py +424 -96
  16. ksadk/codex/projection.py +24 -0
  17. ksadk/codex/runtime.py +83 -283
  18. ksadk/common/auth.py +16 -10
  19. ksadk/configs/env_registry.py +59 -3
  20. ksadk/configs/settings.py +9 -0
  21. ksadk/context_engine/contributors.py +73 -8
  22. ksadk/conversations/__init__.py +19 -0
  23. ksadk/conversations/context.py +104 -24
  24. ksadk/conversations/contracts.py +266 -0
  25. ksadk/conversations/message_projection.py +154 -15
  26. ksadk/conversations/projector.py +614 -0
  27. ksadk/conversations/reducer.py +98 -0
  28. ksadk/conversations/runtime_invocation.py +5 -0
  29. ksadk/conversations/runtime_payloads.py +1 -0
  30. ksadk/conversations/runtime_preparation.py +30 -27
  31. ksadk/conversations/runtime_resume.py +50 -2
  32. ksadk/conversations/runtime_stream_events.py +5 -0
  33. ksadk/conversations/runtime_streaming.py +25 -7
  34. ksadk/deployment/env_forward.py +2 -2
  35. ksadk/deployment/providers/serverless.py +1 -1
  36. ksadk/events/_v1_compat/projection.py +2 -0
  37. ksadk/events/adapters/_codex_validators.py +18 -7
  38. ksadk/events/adapters/codex.py +190 -0
  39. ksadk/events/adapters/langgraph.py +15 -1
  40. ksadk/events/canonical_store.py +3 -1
  41. ksadk/events/projections.py +1 -1
  42. ksadk/harness/__init__.py +45 -35
  43. ksadk/harness/config.py +2 -2
  44. ksadk/harness/runtime.py +75 -16
  45. ksadk/harness/tools.py +38 -13
  46. ksadk/interaction/provider.py +1 -0
  47. ksadk/interaction/providers/langgraph.py +1 -0
  48. ksadk/kernel/bootstrap.py +28 -4
  49. ksadk/kernel/contract_fingerprints.py +5 -4
  50. ksadk/kernel/contracts.py +8 -0
  51. ksadk/kernel/control.py +1 -0
  52. ksadk/kernel/ingress.py +36 -2
  53. ksadk/kernel/memory_store.py +1 -0
  54. ksadk/kernel/postgres_store.py +1 -0
  55. ksadk/kernel/sqlite_store.py +28 -0
  56. ksadk/kernel/store.py +3 -0
  57. ksadk/kernel/worker.py +76 -10
  58. ksadk/knowledge_base/client.py +57 -27
  59. ksadk/mcp_runtime/__init__.py +12 -4
  60. ksadk/memory/adk/backends/sdk_ltm_backend.py +161 -41
  61. ksadk/memory/adk/resilient_session_service.py +25 -17
  62. ksadk/memory/adk/short_term_memory.py +26 -9
  63. ksadk/memory/models.py +7 -4
  64. ksadk/memory/provider_resolver.py +3 -0
  65. ksadk/memory/providers/local_sqlite.py +7 -0
  66. ksadk/model_proxy/server.py +10 -5
  67. ksadk/plugins/__init__.py +171 -0
  68. ksadk/plugins/artifacts.py +275 -0
  69. ksadk/plugins/bridges/__init__.py +47 -0
  70. ksadk/plugins/bridges/codex.py +659 -0
  71. ksadk/plugins/bridges/dsh.py +1300 -0
  72. ksadk/plugins/builtins.py +746 -0
  73. ksadk/plugins/bundle.py +246 -0
  74. ksadk/plugins/bundle_security.py +191 -0
  75. ksadk/plugins/codex_manifest.py +983 -0
  76. ksadk/plugins/composition.py +537 -0
  77. ksadk/plugins/context_contributor.py +437 -0
  78. ksadk/plugins/contracts.py +569 -0
  79. ksadk/plugins/delivery.py +153 -0
  80. ksadk/plugins/dsh_installation_digest.py +71 -0
  81. ksadk/plugins/dsh_toolchain.py +1024 -0
  82. ksadk/plugins/ecosystem_bridge.py +1105 -0
  83. ksadk/plugins/ecosystem_probe.py +191 -0
  84. ksadk/plugins/host.py +787 -0
  85. ksadk/plugins/kernel_adapter.py +205 -0
  86. ksadk/plugins/providers/__init__.py +108 -0
  87. ksadk/plugins/providers/bundles/dsh-knowledge/cordis.patch.yml +3 -0
  88. ksadk/plugins/providers/bundles/dsh-knowledge/index.mjs +53 -0
  89. ksadk/plugins/providers/bundles/dsh-knowledge/package.json +16 -0
  90. ksadk/plugins/providers/bundles/dsh-memory/cordis.patch.yml +3 -0
  91. ksadk/plugins/providers/bundles/dsh-memory/index.mjs +175 -0
  92. ksadk/plugins/providers/bundles/dsh-memory/package.json +16 -0
  93. ksadk/plugins/providers/bundles/dsh-platform-resources/client.mjs +166 -0
  94. ksadk/plugins/providers/bundles/dsh-platform-resources/cordis.patch.yml +3 -0
  95. ksadk/plugins/providers/bundles/dsh-platform-resources/index.mjs +9 -0
  96. ksadk/plugins/providers/bundles/dsh-platform-resources/package.json +12 -0
  97. ksadk/plugins/providers/bundles/dsh-skill-center/cordis.patch.yml +3 -0
  98. ksadk/plugins/providers/bundles/dsh-skill-center/index.mjs +125 -0
  99. ksadk/plugins/providers/bundles/dsh-skill-center/package.json +16 -0
  100. ksadk/plugins/providers/bundles/ksadk-codex/cordis.patch.yml +3 -0
  101. ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +18 -0
  102. ksadk/plugins/providers/bundles/ksadk-codex/package.json +19 -0
  103. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/cordis.patch.yml +3 -0
  104. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/index.mjs +870 -0
  105. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +27 -0
  106. ksadk/plugins/providers/bundles/ksadk-dsh-studio/client.js +92 -0
  107. ksadk/plugins/providers/bundles/ksadk-dsh-studio/index.mjs +15 -0
  108. ksadk/plugins/providers/bundles/ksadk-dsh-studio/package.json +7 -0
  109. ksadk/plugins/providers/bundles/ksadk-harness/cordis.patch.yml +3 -0
  110. ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +19 -0
  111. ksadk/plugins/providers/bundles/ksadk-harness/package.json +19 -0
  112. ksadk/plugins/providers/codex.py +988 -0
  113. ksadk/plugins/providers/codex_dsh.py +83 -0
  114. ksadk/plugins/providers/codex_native.py +368 -0
  115. ksadk/plugins/providers/codex_turn.py +301 -0
  116. ksadk/plugins/providers/dsh.py +951 -0
  117. ksadk/plugins/providers/dsh_capabilities.py +1389 -0
  118. ksadk/plugins/providers/dsh_descriptor_host.py +226 -0
  119. ksadk/plugins/providers/dsh_mcp.py +467 -0
  120. ksadk/plugins/providers/harness.py +632 -0
  121. ksadk/plugins/providers/harness_dsh.py +91 -0
  122. ksadk/plugins/providers/legacy.py +215 -0
  123. ksadk/plugins/providers/legacy_catalog.py +100 -0
  124. ksadk/plugins/providers/mcp_projection.py +150 -0
  125. ksadk/plugins/providers/platform_resources.py +657 -0
  126. ksadk/plugins/providers/shipped_dsh.py +370 -0
  127. ksadk/plugins/resolver.py +338 -0
  128. ksadk/plugins/subagent_providers/__init__.py +12 -0
  129. ksadk/plugins/subagent_providers/codex.py +443 -0
  130. ksadk/plugins/subagents.py +333 -0
  131. ksadk/resource_runtime/__init__.py +4 -0
  132. ksadk/resource_runtime/broker.py +616 -0
  133. ksadk/resource_runtime/build_artifacts.py +165 -0
  134. ksadk/resource_runtime/contracts.py +138 -0
  135. ksadk/resource_runtime/discovery_receipts.py +100 -0
  136. ksadk/resource_runtime/discovery_skills.py +172 -0
  137. ksadk/resource_runtime/errors.py +6 -0
  138. ksadk/resource_runtime/ipc.py +142 -0
  139. ksadk/resource_runtime/kernel_approval.py +165 -0
  140. ksadk/resource_runtime/knowledge.py +114 -0
  141. ksadk/resource_runtime/langgraph.py +94 -0
  142. ksadk/resource_runtime/leases.py +191 -0
  143. ksadk/resource_runtime/managed_projection.py +186 -0
  144. ksadk/resource_runtime/mcp_server.py +138 -0
  145. ksadk/resource_runtime/memory_provider.py +318 -0
  146. ksadk/resource_runtime/memory_receipts.py +34 -0
  147. ksadk/resource_runtime/operation_ledger.py +211 -0
  148. ksadk/resource_runtime/plugin_config.py +48 -0
  149. ksadk/resource_runtime/policy_authorization.py +54 -0
  150. ksadk/resource_runtime/process.py +110 -0
  151. ksadk/resource_runtime/skill_artifacts.py +153 -0
  152. ksadk/resource_runtime/skill_runtime.py +42 -0
  153. ksadk/resource_runtime/skill_workspace.py +118 -0
  154. ksadk/resource_runtime/skills.py +215 -0
  155. ksadk/resource_runtime/snapshots.py +180 -0
  156. ksadk/resource_runtime/socket_server.py +103 -0
  157. ksadk/resource_runtime/supervisor.py +380 -0
  158. ksadk/resource_runtime/worker.py +504 -0
  159. ksadk/runners/_langgraph_runner_streams.py +74 -6
  160. ksadk/runners/adk_runner.py +149 -11
  161. ksadk/runners/base_runner.py +29 -1
  162. ksadk/runners/langgraph_runner.py +475 -145
  163. ksadk/runtime/_runner_adapter/stream_mapping.py +193 -60
  164. ksadk/runtime/adapter.py +3 -0
  165. ksadk/runtime/conversation_execution.py +92 -16
  166. ksadk/runtime/executor.py +78 -2
  167. ksadk/runtime/factory.py +30 -200
  168. ksadk/runtime/framework_adapters.py +41 -0
  169. ksadk/runtime/preprocessing.py +10 -2
  170. ksadk/runtime/runner_adapter.py +78 -14
  171. ksadk/runtime_context.py +40 -2
  172. ksadk/sandbox/__init__.py +2 -1
  173. ksadk/sandbox/backends/e2b.py +52 -11
  174. ksadk/sandbox/backends/local_process.py +9 -0
  175. ksadk/sandbox/base.py +2 -0
  176. ksadk/sandbox/e2b_connection.py +66 -0
  177. ksadk/sandbox/factory.py +72 -0
  178. ksadk/scheduler/__init__.py +18 -0
  179. ksadk/scheduler/calendar.py +102 -0
  180. ksadk/scheduler/contracts.py +254 -0
  181. ksadk/scheduler/dispatcher.py +129 -0
  182. ksadk/scheduler/engine.py +416 -0
  183. ksadk/scheduler/sqlite_store.py +581 -0
  184. ksadk/server/composition.py +2 -0
  185. ksadk/server/factory.py +5 -0
  186. ksadk/server/persistence_capability.py +516 -0
  187. ksadk/server/routes/control.py +210 -46
  188. ksadk/server/routes/dependencies.py +15 -0
  189. ksadk/server/routes/models.py +47 -4
  190. ksadk/server/routes/projection.py +252 -12
  191. ksadk/server/routes/sessions.py +284 -107
  192. ksadk/server/routes/streaming.py +43 -9
  193. ksadk/server/static/assets/{ArtifactsPanel-DSU1sWD_.js → ArtifactsPanel-CGbWlMNh.js} +1 -1
  194. ksadk/server/static/assets/{CodeBlock-DOH6MVcn.js → CodeBlock-b4C7upmO.js} +3 -3
  195. ksadk/server/static/assets/{MathMessageMarkdown-BL8my1R2.js → MathMessageMarkdown-DbdW5A4_.js} +4 -4
  196. ksadk/server/static/assets/{MermaidBlock-Dz4IP-Tx.js → MermaidBlock-BEBN4Ksz.js} +6 -6
  197. ksadk/server/static/assets/{NativeTerminalPanel-DUrK0JpZ.js → NativeTerminalPanel-zvL-WpAn.js} +1 -1
  198. ksadk/server/static/assets/{abnfDiagram-VCTEODGH-g20pFzNV.js → abnfDiagram-VCTEODGH-BYafW7Za.js} +1 -1
  199. ksadk/server/static/assets/{arc-C4FzinUA.js → arc-bTohInsS.js} +1 -1
  200. ksadk/server/static/assets/architecture-7GRP2DOG-BW5UtSnx.js +1 -0
  201. ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-DpIqL5h4.js → architectureDiagram-5GKGNRK7-Ch5Lbzsi.js} +1 -1
  202. ksadk/server/static/assets/{blockDiagram-NRAW4CY4-BjkljTNz.js → blockDiagram-NRAW4CY4-kqF4MDOG.js} +1 -1
  203. ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-Dk_ieq2X.js → c4Diagram-UCG6FXSJ-8uSRIODv.js} +1 -1
  204. ksadk/server/static/assets/channel-CF5Up3hQ.js +1 -0
  205. ksadk/server/static/assets/chunk-2Q5K7J3B-KkXX47WI.js +1 -0
  206. ksadk/server/static/assets/{chunk-5VM5RSS4-BVHAchFb.js → chunk-5VM5RSS4-DkhehZDr.js} +1 -1
  207. ksadk/server/static/assets/{chunk-F27PBJKO-C-ipQzuS.js → chunk-F27PBJKO-BdXhtPe9.js} +1 -1
  208. ksadk/server/static/assets/{chunk-G27WJ6UU-C2EyJbIK.js → chunk-G27WJ6UU-DPTpvpwi.js} +1 -1
  209. ksadk/server/static/assets/{chunk-JWPE2WC7-vYvVJb_M.js → chunk-JWPE2WC7-Pqoh38el.js} +1 -1
  210. ksadk/server/static/assets/{chunk-LCL6LL3I-BcI6ysPT.js → chunk-LCL6LL3I-DeU00qC-.js} +1 -1
  211. ksadk/server/static/assets/{chunk-POPQ4Y6H-C030x_Z1.js → chunk-POPQ4Y6H-CzxScFkr.js} +1 -1
  212. ksadk/server/static/assets/{chunk-RHFEMEQ7-yyGpsz4n.js → chunk-RHFEMEQ7-DpqMx-ux.js} +1 -1
  213. ksadk/server/static/assets/{chunk-SVP7TREG-BLTlmMU7.js → chunk-SVP7TREG-C6t0SypQ.js} +1 -1
  214. ksadk/server/static/assets/{chunk-XXDRQBXY-C_32ArgP.js → chunk-XXDRQBXY-DVaeafZk.js} +1 -1
  215. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Cz81acRQ.js +1 -0
  216. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Cz81acRQ.js +1 -0
  217. ksadk/server/static/assets/{cose-bilkent-JH36ORCC-9YQYwdl0.js → cose-bilkent-JH36ORCC-Bf9D3tzJ.js} +1 -1
  218. ksadk/server/static/assets/cynefin-OW5HDTMX-DVWs8a2t.js +1 -0
  219. ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-ErLF5N13.js → cynefinDiagram-5FMLGOSQ-B9cY3iTz.js} +1 -1
  220. ksadk/server/static/assets/{dagre-3AP2YEHR-DFiQF-6f.js → dagre-3AP2YEHR-CSwlx3CB.js} +1 -1
  221. ksadk/server/static/assets/{dagre-BuhGnRI1.js → dagre-UBpgon5q.js} +1 -1
  222. ksadk/server/static/assets/{diagram-S7CK7UJ4-Bt1v8-GC.js → diagram-S7CK7UJ4-C9akhN9a.js} +1 -1
  223. ksadk/server/static/assets/{diagram-UQ7AKVKN-DSCxJdBK.js → diagram-UQ7AKVKN-CgedhTPI.js} +1 -1
  224. ksadk/server/static/assets/{diagram-VSXAHHWV-DHfYwp_9.js → diagram-VSXAHHWV-Cjucz5BY.js} +1 -1
  225. ksadk/server/static/assets/{diagram-VX7I27RA-DdzD-4Le.js → diagram-VX7I27RA-Dd4Vleyn.js} +1 -1
  226. ksadk/server/static/assets/{diagram-Z3DM3KII-Du-nAJ9F.js → diagram-Z3DM3KII-CZ2jGtYW.js} +1 -1
  227. ksadk/server/static/assets/{dist-B7seoj3d.js → dist-B2_CVgKv.js} +1 -1
  228. ksadk/server/static/assets/{dist-CSh_DE14.js → dist-B3FR1SKK.js} +1 -1
  229. ksadk/server/static/assets/{dist-DUX-id_F.js → dist-BIr4DSRq.js} +1 -1
  230. ksadk/server/static/assets/{dist-C_wsv-Qd.js → dist-BgV_owcB.js} +1 -1
  231. ksadk/server/static/assets/{dist-W-TIVntx.js → dist-Bj730Ib4.js} +1 -1
  232. ksadk/server/static/assets/{dist-BytlxIDT.js → dist-BnaTiyzN.js} +1 -1
  233. ksadk/server/static/assets/{dist-CXYYBw3_.js → dist-C1NMAY5a.js} +1 -1
  234. ksadk/server/static/assets/{dist-dDdADKFA.js → dist-C5_ZAZsG.js} +1 -1
  235. ksadk/server/static/assets/{dist-BVDffZ0U.js → dist-CB9iJrvg.js} +1 -1
  236. ksadk/server/static/assets/{dist-Bf2M8m3N.js → dist-CFzsn6BG.js} +1 -1
  237. ksadk/server/static/assets/{dist-ngtN0DJB.js → dist-Cf125P_m.js} +1 -1
  238. ksadk/server/static/assets/{dist-BE7bu-DL.js → dist-ClYUxfeK.js} +1 -1
  239. ksadk/server/static/assets/{dist-DNp6rLRA.js → dist-DFD6Qa6T.js} +1 -1
  240. ksadk/server/static/assets/{dist-BX8z72IC.js → dist-DVCOWtha.js} +1 -1
  241. ksadk/server/static/assets/{dist-dydu68Fl.js → dist-D_ctSS2i.js} +1 -1
  242. ksadk/server/static/assets/{dist-ClxGviKw.js → dist-DiixqL0J.js} +1 -1
  243. ksadk/server/static/assets/{dist-BjU6y-A2.js → dist-DoVSwoDb.js} +1 -1
  244. ksadk/server/static/assets/{dist-Dq9gLD7L.js → dist-DvFK7p5S.js} +1 -1
  245. ksadk/server/static/assets/{dist-8hqcx0sU.js → dist-QfkEHOlb.js} +1 -1
  246. ksadk/server/static/assets/{dist-CttYUqzS.js → dist-btbmmX5O.js} +1 -1
  247. ksadk/server/static/assets/{dist-DmldrHd_.js → dist-fBO2v5Kt.js} +1 -1
  248. ksadk/server/static/assets/{dist-DnfXs8Vn.js → dist-ufY3F5p6.js} +1 -1
  249. ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-Da9C9NO1.js → ebnfDiagram-PWID7BFC-Ci8NqqZu.js} +1 -1
  250. ksadk/server/static/assets/{erDiagram-SSCWMZ5O-EAGqqR79.js → erDiagram-SSCWMZ5O-CCIOhLZG.js} +1 -1
  251. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CQqR2hg3.js +1 -0
  252. ksadk/server/static/assets/flowDiagram-A5DVABFB-DDRRbGPm.js +1 -0
  253. ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-DqJsKb59.js → ganttDiagram-EL5Y4UJY-Cp_r9Hb6.js} +1 -1
  254. ksadk/server/static/assets/gitGraph-4MIJSDKK-fgWEf7UD.js +1 -0
  255. ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-B6g4dtDi.js → gitGraphDiagram-WWUBYQGX-Dlhc8Wr8.js} +1 -1
  256. ksadk/server/static/assets/index-DcTML1Up.css +2 -0
  257. ksadk/server/static/assets/index-Dh2XHqPK.js +244 -0
  258. ksadk/server/static/assets/info-A6RAGUB7-BUecLTdt.js +1 -0
  259. ksadk/server/static/assets/{infoDiagram-RXCK75RN-Djm_nbd5.js → infoDiagram-RXCK75RN-CO0rRTRA.js} +1 -1
  260. ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-DWya9SG2.js → ishikawaDiagram-5VMMS53U-CHiaedSS.js} +1 -1
  261. ksadk/server/static/assets/{journeyDiagram-EYS64GPL-DutxhSNI.js → journeyDiagram-EYS64GPL-CHcCIB09.js} +1 -1
  262. ksadk/server/static/assets/{kanban-definition-3QL26DDD-DJdOF8Fm.js → kanban-definition-3QL26DDD-CJ_ebBZf.js} +1 -1
  263. ksadk/server/static/assets/{katex-vFWytM5c.js → katex-B4weu383.js} +1 -1
  264. ksadk/server/static/assets/{linear-BHjG8b-J.js → linear-V-MgYHW1.js} +1 -1
  265. ksadk/server/static/assets/{mermaid-parser.core-KGSy4jWT.js → mermaid-parser.core-CBijEX_c.js} +2 -2
  266. ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-9-HC88D4.js → mindmap-definition-FBJOCRG2-Bc-pQvpp.js} +1 -1
  267. ksadk/server/static/assets/packet-AYTQ26CC-BeW-btFv.js +1 -0
  268. ksadk/server/static/assets/{pegDiagram-XKGWAZYB-DrEZd4fD.js → pegDiagram-XKGWAZYB-D7genGLl.js} +1 -1
  269. ksadk/server/static/assets/pie-WAS4IAKB-X0xh4SaT.js +1 -0
  270. ksadk/server/static/assets/{pieDiagram-E7YTZNPT-DpjqOFFp.js → pieDiagram-E7YTZNPT-Bxj32zwD.js} +1 -1
  271. ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-BiNhgOXX.js → quadrantDiagram-AXDQQJYC-BURv2mGh.js} +1 -1
  272. ksadk/server/static/assets/radar-RG4KPBEZ-DzRMSqjd.js +1 -0
  273. ksadk/server/static/assets/railroad-74A4TZTK-Cc44icX-.js +1 -0
  274. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-D6S4BdV-.js +1 -0
  275. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-vD3aVE2o.js +1 -0
  276. ksadk/server/static/assets/railroad-peg-WCYAUIDC-CYbW_b4T.js +1 -0
  277. ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-_Y3Ojg6G.js → railroadDiagram-O6MQD6OU-CCsh3avW.js} +1 -1
  278. ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-DeCFdg9K.js → requirementDiagram-EFPCY7ZU-_FRRBKEd.js} +1 -1
  279. ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-CPH75rhw.js → sankeyDiagram-P5KCCOFB-C-gr2o9M.js} +1 -1
  280. ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-OEpQQdr4.js → sequenceDiagram-WJ2MYXX4-D97NmfKg.js} +1 -1
  281. ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-heUErzhI.js → sizeCapture-X5ZJPWSS-DjrPC5FX.js} +1 -1
  282. ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-DvA3jSMB.js → stateDiagram-HBIQ2CUA-DzMNg1hh.js} +1 -1
  283. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BIcjKFhF.js +1 -0
  284. ksadk/server/static/assets/{swimlanes-XN3QIQJK-CR-dfN_t.js → swimlanes-XN3QIQJK-Cssf_CsU.js} +1 -1
  285. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-tq3K3Ybl.js +8 -0
  286. ksadk/server/static/assets/{timeline-definition-24CTP7MA-DAVJf1TX.js → timeline-definition-24CTP7MA-BWTHzyS1.js} +1 -1
  287. ksadk/server/static/assets/treeView-Q6P3EWNA-DBXt3GdU.js +1 -0
  288. ksadk/server/static/assets/treemap-WGGIJYW6-DrCy4E_l.js +1 -0
  289. ksadk/server/static/assets/{vennDiagram-4TSXK5OY-DwM8eDkh.js → vennDiagram-4TSXK5OY-BSKgJsmR.js} +1 -1
  290. ksadk/server/static/assets/wardley-WFR3VGLG-CefhOliM.js +1 -0
  291. ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-DZL-Zz2t.js → wardleyDiagram-VM6X3IG4-eflHNoaZ.js} +1 -1
  292. ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js → xychartDiagram-S5SC5T6Z-eYqrQ-v4.js} +1 -1
  293. ksadk/server/static/index.html +2 -2
  294. ksadk/session_context.py +66 -0
  295. ksadk/sessions/__init__.py +11 -21
  296. ksadk/sessions/_local_service_sync.py +263 -1
  297. ksadk/sessions/base.py +176 -0
  298. ksadk/sessions/errors.py +4 -0
  299. ksadk/sessions/in_memory.py +309 -19
  300. ksadk/sessions/local_service.py +83 -1
  301. ksadk/sessions/persistence.py +275 -0
  302. ksadk/sessions/postgres_service.py +358 -0
  303. ksadk/sessions/resilience.py +8 -0
  304. ksadk/sessions/resilient.py +362 -4
  305. ksadk/sessions/topology.py +135 -0
  306. ksadk/skills/models.py +26 -4
  307. ksadk/skills/package_store.py +186 -38
  308. ksadk/skills/runtime/agent.py +31 -6
  309. ksadk/skills/runtime/artifact_delivery.py +139 -0
  310. ksadk/skills/runtime/backends/e2b.py +98 -6
  311. ksadk/skills/runtime/backends/local.py +73 -8
  312. ksadk/skills/runtime/base.py +3 -0
  313. ksadk/skills/runtime/executor.py +2 -0
  314. ksadk/skills/runtime/loader.py +10 -2
  315. ksadk/skills/runtime/pinned.py +114 -0
  316. ksadk/skills/runtime/request.py +31 -0
  317. ksadk/skills/service_client.py +211 -24
  318. ksadk/studio/agent_lifecycle.py +26 -20
  319. ksadk/studio/api.py +714 -90
  320. ksadk/studio/api_catalog_routes.py +23 -0
  321. ksadk/studio/api_contracts.py +34 -1
  322. ksadk/studio/api_plugin_routes.py +911 -0
  323. ksadk/studio/api_resource_connections.py +183 -0
  324. ksadk/studio/attachment_store.py +187 -0
  325. ksadk/studio/authoring.py +10 -4
  326. ksadk/studio/authoring_coordinator.py +31 -16
  327. ksadk/studio/builder.py +199 -43
  328. ksadk/studio/cloud.py +346 -104
  329. ksadk/studio/cloud_shared_web.py +565 -0
  330. ksadk/studio/codex_agent_service.py +140 -27
  331. ksadk/studio/codex_builder.py +294 -16
  332. ksadk/studio/codex_credentials.py +90 -0
  333. ksadk/studio/codex_manifest.py +51 -4
  334. ksadk/studio/codex_plugin_store.py +746 -0
  335. ksadk/studio/codex_provider_build.py +231 -0
  336. ksadk/studio/codex_run.py +200 -29
  337. ksadk/studio/compatibility_report.py +456 -0
  338. ksadk/studio/compiler.py +84 -15
  339. ksadk/studio/contracts.py +249 -4
  340. ksadk/studio/dsh_application.py +137 -0
  341. ksadk/studio/dsh_capability_service.py +1107 -0
  342. ksadk/studio/dsh_models.py +59 -0
  343. ksadk/studio/dsh_provider_registration.py +1075 -0
  344. ksadk/studio/event_store.py +54 -6
  345. ksadk/studio/framework_run.py +37 -4
  346. ksadk/studio/hosted_kernel.py +89 -14
  347. ksadk/studio/mcp_runtime.py +11 -3
  348. ksadk/studio/model_client.py +2 -2
  349. ksadk/studio/operations.py +12 -2
  350. ksadk/studio/plugin_composition.py +468 -0
  351. ksadk/studio/plugin_kernel_adapter.py +28 -0
  352. ksadk/studio/plugin_runtime.py +831 -0
  353. ksadk/studio/resource_authority.py +637 -0
  354. ksadk/studio/resource_binding_validation.py +77 -0
  355. ksadk/studio/resource_build_admission.py +196 -0
  356. ksadk/studio/resource_build_materializer.py +149 -0
  357. ksadk/studio/resource_catalog.py +149 -3
  358. ksadk/studio/resource_connections.py +220 -0
  359. ksadk/studio/run_service.py +1144 -96
  360. ksadk/studio/runtime_source.py +24 -8
  361. ksadk/studio/scheduler_assistant.py +317 -0
  362. ksadk/studio/scheduler_runtime.py +383 -0
  363. ksadk/studio/scheduler_service.py +214 -0
  364. ksadk/studio/service.py +1131 -95
  365. ksadk/studio/shared_web.py +610 -87
  366. ksadk/studio/soul.py +52 -0
  367. ksadk/studio/static/assets/CodeBlock-DCUUY0PL-BLjA7kbS.js +41 -0
  368. ksadk/studio/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  369. ksadk/studio/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  370. ksadk/studio/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  371. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  372. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  373. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  374. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  375. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  376. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  377. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  378. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  379. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  380. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  381. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  382. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  383. ksadk/studio/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  384. ksadk/studio/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  385. ksadk/studio/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  386. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  387. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  388. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  389. ksadk/studio/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  390. ksadk/studio/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  391. ksadk/studio/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  392. ksadk/studio/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  393. ksadk/studio/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  394. ksadk/studio/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  395. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  396. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  397. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  398. ksadk/studio/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  399. ksadk/studio/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  400. ksadk/studio/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  401. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  402. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  403. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  404. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  405. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  406. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  407. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  408. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  409. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  410. ksadk/studio/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  411. ksadk/studio/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  412. ksadk/studio/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  413. ksadk/studio/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  414. ksadk/studio/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  415. ksadk/studio/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  416. ksadk/studio/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  417. ksadk/studio/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  418. ksadk/studio/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  419. ksadk/studio/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  420. ksadk/studio/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  421. ksadk/studio/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  422. ksadk/studio/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  423. ksadk/studio/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  424. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  425. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  426. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  427. ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--BEOyPC3w.css +1 -0
  428. ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--CUYIXwgI.js +8 -0
  429. ksadk/studio/static/assets/MermaidBlock-DBFTztfQ-BTYKWEbD.js +44 -0
  430. ksadk/studio/static/assets/PrismRenderer-wiXRHURw.js +3 -0
  431. ksadk/studio/static/assets/abnfDiagram-VCTEODGH-CLETGjKq.js +1 -0
  432. ksadk/studio/static/assets/arc-Pry-7G1_.js +1 -0
  433. ksadk/studio/static/assets/architecture-7GRP2DOG-hXMiO_AU.js +1 -0
  434. ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-B5EQysk6.js +36 -0
  435. ksadk/studio/static/assets/array-BifhSqXX.js +1 -0
  436. ksadk/studio/static/assets/blockDiagram-I7D4REHJ-CFmPl1de.js +129 -0
  437. ksadk/studio/static/assets/c4Diagram-7LVT6UL2-BRrGu8qt.js +38 -0
  438. ksadk/studio/static/assets/channel-BqO-gtEw.js +1 -0
  439. ksadk/studio/static/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  440. ksadk/studio/static/assets/chunk-4HAMMTFA-D220vUtq.js +62 -0
  441. ksadk/studio/static/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  442. ksadk/studio/static/assets/chunk-75Z2AOVW-C8lLv_qc.js +2 -0
  443. ksadk/studio/static/assets/chunk-DU6HZSFF-C4DtVpCu.js +128 -0
  444. ksadk/studio/static/assets/chunk-F27PBJKO-Cpw14SNG.js +1 -0
  445. ksadk/studio/static/assets/chunk-FOHPRMQF-DHwB1DNv.js +161 -0
  446. ksadk/studio/static/assets/chunk-GMAD6QVW-DiQA-u2N.js +72 -0
  447. ksadk/studio/static/assets/chunk-GVQU2GXP-DUdNBUCi.js +1 -0
  448. ksadk/studio/static/assets/chunk-IMKFNOWR-BSlbjT_b.js +231 -0
  449. ksadk/studio/static/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  450. ksadk/studio/static/assets/chunk-L3NEJ4N5-Db8Ab22W.js +1 -0
  451. ksadk/studio/static/assets/chunk-OSK3NFVY-M2m6G3j4.js +10 -0
  452. ksadk/studio/static/assets/chunk-P2QGCYS3-DezaQxiK.js +1 -0
  453. ksadk/studio/static/assets/chunk-POPQ4Y6H-DOpufJ3t.js +1 -0
  454. ksadk/studio/static/assets/chunk-PWAF6VOD-CfLb1gSc.js +1 -0
  455. ksadk/studio/static/assets/chunk-SHT3W25Y-DAyIVp5H.js +168 -0
  456. ksadk/studio/static/assets/chunk-SVP7TREG-DulomOrS.js +88 -0
  457. ksadk/studio/static/assets/chunk-TICWLB2K-bHJYoflj.js +206 -0
  458. ksadk/studio/static/assets/chunk-XXDRQBXY-7PcdR2B1.js +1 -0
  459. ksadk/studio/static/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  460. ksadk/studio/static/assets/classDiagram-ZZMXUADV-D_bW8JjA.js +1 -0
  461. ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-D_bW8JjA.js +1 -0
  462. ksadk/studio/static/assets/cose-bilkent-JH36ORCC-snL88wkX.js +1 -0
  463. ksadk/studio/static/assets/cynefin-OW5HDTMX-Bd1YhRo1.js +1 -0
  464. ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-BBrIG_mI.js +62 -0
  465. ksadk/studio/static/assets/cytoscape.esm-CGd-uY3x.js +321 -0
  466. ksadk/studio/static/assets/dagre-GXQ25YYZ-DtF1nGdY.js +4 -0
  467. ksadk/studio/static/assets/dagre-PrKaheQc.js +1 -0
  468. ksadk/studio/static/assets/defaultLocale-BFoDCU3G.js +1 -0
  469. ksadk/studio/static/assets/diagram-S7CK7UJ4-0BZ98mya.js +30 -0
  470. ksadk/studio/static/assets/diagram-UQ7AKVKN-6mLKEo6L.js +41 -0
  471. ksadk/studio/static/assets/diagram-VSXAHHWV-CJBIaiZ2.js +3 -0
  472. ksadk/studio/static/assets/diagram-VX7I27RA-BohLEE1C.js +24 -0
  473. ksadk/studio/static/assets/diagram-Z3DM3KII-D8KIGonG.js +24 -0
  474. ksadk/studio/static/assets/dist-v5Q1xZ2K.js +1 -0
  475. ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-C99HU61t.js +1 -0
  476. ksadk/studio/static/assets/erDiagram-RLTQ6QDP-DLGry2Ap.js +99 -0
  477. ksadk/studio/static/assets/eventmodeling-NTZA5JFV-B1_5Ac8j.js +1 -0
  478. ksadk/studio/static/assets/flowDiagram-HODETNUW-DD5hmicn.js +1 -0
  479. ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BPJrVLSG.js +292 -0
  480. ksadk/studio/static/assets/gitGraph-4MIJSDKK-Cy_ZQBGi.js +1 -0
  481. ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-CZCUz4MT.js +106 -0
  482. ksadk/studio/static/assets/graphlib-DS17s2tU.js +1 -0
  483. ksadk/studio/static/assets/index-CeHL9ARV.css +2 -0
  484. ksadk/studio/static/assets/index-D9QEcVpL.js +320 -0
  485. ksadk/studio/static/assets/info-A6RAGUB7-DBzDQB_I.js +1 -0
  486. ksadk/studio/static/assets/infoDiagram-27XIBGKW-B-sq07Hi.js +2 -0
  487. ksadk/studio/static/assets/init-C-OQMol4.js +1 -0
  488. ksadk/studio/static/assets/ishikawaDiagram-5VMMS53U-CljI2wyf.js +70 -0
  489. ksadk/studio/static/assets/journeyDiagram-3NMN7TZE-D50Fo2sL.js +139 -0
  490. ksadk/studio/static/assets/kanban-definition-UXKFOSKX-DimfOTam.js +89 -0
  491. ksadk/studio/static/assets/katex-DhON-x74.js +257 -0
  492. ksadk/studio/static/assets/line-CX5BOOUP.js +1 -0
  493. ksadk/studio/static/assets/linear-BCxN9JLv.js +1 -0
  494. ksadk/studio/static/assets/mermaid-parser.core-BdCz8fkS.js +7 -0
  495. ksadk/studio/static/assets/mindmap-definition-YA3MSWOX-Bizzqy5R.js +96 -0
  496. ksadk/studio/static/assets/ordinal-BDEzSJ7C.js +1 -0
  497. ksadk/studio/static/assets/packet-AYTQ26CC-gPln-_kG.js +1 -0
  498. ksadk/studio/static/assets/path-fybaL0A-.js +1 -0
  499. ksadk/studio/static/assets/pegDiagram-XKGWAZYB-Dy3fB-gW.js +1 -0
  500. ksadk/studio/static/assets/pie-WAS4IAKB-qZdHMr7B.js +1 -0
  501. ksadk/studio/static/assets/pieDiagram-E7YTZNPT-B9mrFSDF.js +39 -0
  502. ksadk/studio/static/assets/quadrantDiagram-AXDQQJYC-NzUfCbMR.js +7 -0
  503. ksadk/studio/static/assets/radar-RG4KPBEZ-BZlnaea9.js +1 -0
  504. ksadk/studio/static/assets/railroad-74A4TZTK-Ce3__H9c.js +1 -0
  505. ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-DqQn7EzD.js +1 -0
  506. ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-B55kCA8F.js +1 -0
  507. ksadk/studio/static/assets/railroad-peg-WCYAUIDC-DfQnvkHd.js +1 -0
  508. ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-DnhMjZCk.js +1 -0
  509. ksadk/studio/static/assets/requirementDiagram-BXWQKSXE-BF3d103U.js +84 -0
  510. ksadk/studio/static/assets/rolldown-runtime-Dy4uBu1J-DK3Fl9T5.js +1 -0
  511. ksadk/studio/static/assets/rough.esm-Dy-Kn_BL.js +1 -0
  512. ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-Bo-JTwt0.js +40 -0
  513. ksadk/studio/static/assets/sequenceDiagram-WJ2MYXX4-Dh4wZtUm.js +162 -0
  514. ksadk/studio/static/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
  515. ksadk/studio/static/assets/src-SFn9St9H.js +1 -0
  516. ksadk/studio/static/assets/stateDiagram-D77RDMKH-DH774G6d.js +1 -0
  517. ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-DZvVWPBo.js +1 -0
  518. ksadk/studio/static/assets/swimlanes-42K2YHIH-Bl13OvTX.js +1 -0
  519. ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-BnFOTALJ.js +8 -0
  520. ksadk/studio/static/assets/timeline-definition-24CTP7MA-DxmSSjRB.js +120 -0
  521. ksadk/studio/static/assets/treeView-Q6P3EWNA-D5Nn9Swz.js +1 -0
  522. ksadk/studio/static/assets/treemap-WGGIJYW6-CgHgnQhE.js +1 -0
  523. ksadk/studio/static/assets/vennDiagram-4TSXK5OY-B9QEXcJq.js +34 -0
  524. ksadk/studio/static/assets/wardley-WFR3VGLG-DXrK2RRY.js +1 -0
  525. ksadk/studio/static/assets/wardleyDiagram-VM6X3IG4-Ba1AOWoe.js +78 -0
  526. ksadk/studio/static/assets/xychartDiagram-S5SC5T6Z-Cr5pt5Y-.js +7 -0
  527. ksadk/studio/static/index.html +2 -2
  528. ksadk/studio/validator.py +1 -1
  529. ksadk/studio/workspace.py +1 -0
  530. ksadk/version.py +1 -1
  531. ksadk_runtime_common/workspace_files/path_utils.py +41 -0
  532. agentengine_sdk_python-0.8.2.dist-info/RECORD +0 -778
  533. ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +0 -1
  534. ksadk/server/static/assets/channel-4cQHKtx1.js +0 -1
  535. ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +0 -1
  536. ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +0 -1
  537. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +0 -1
  538. ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +0 -1
  539. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +0 -1
  540. ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +0 -1
  541. ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +0 -1
  542. ksadk/server/static/assets/index-8ipRcQ-M.js +0 -240
  543. ksadk/server/static/assets/index-ByFCqjlh.css +0 -2
  544. ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +0 -1
  545. ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +0 -1
  546. ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +0 -1
  547. ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +0 -1
  548. ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +0 -1
  549. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +0 -1
  550. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +0 -1
  551. ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +0 -1
  552. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +0 -1
  553. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +0 -8
  554. ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +0 -1
  555. ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +0 -1
  556. ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +0 -1
  557. ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +0 -3
  558. ksadk/studio/static/assets/index-BLpcdrgW.css +0 -1
  559. ksadk/studio/static/assets/index-CYekR2Xv.js +0 -260
  560. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/WHEEL +0 -0
  561. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/entry_points.txt +0 -0
  562. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/licenses/LICENSE +0 -0
  563. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/top_level.txt +0 -0
ksadk/configs/settings.py CHANGED
@@ -628,3 +628,12 @@ def setup_environment(agent_path: Path | str):
628
628
  setup_proxy_redirect_if_enabled()
629
629
  except Exception: # noqa: BLE001 代理可选,失败不影响主流程(默认关时本就不触发)
630
630
  pass
631
+
632
+ # 5. 沙箱控制面 URL 内网探测:在 Pod 内探测 198 公共服务网内网地址,
633
+ # 可达则覆盖 E2B_API_URL 为内网域名,private_only 节点也能访问沙箱控制面。
634
+ try:
635
+ from ksadk.sandbox import setup_sandbox_api_url_if_needed
636
+
637
+ setup_sandbox_api_url_if_needed()
638
+ except Exception: # noqa: BLE001 沙箱可选,失败不影响主流程
639
+ pass
@@ -24,6 +24,14 @@ logger = logging.getLogger(__name__)
24
24
  ContributorFailureMode = Literal["skip", "warn", "fail"]
25
25
  ContributorCacheability = Literal["stable", "turn", "none"]
26
26
 
27
+ _TRUST_RANK: dict[ContextTrustLevel, int] = {
28
+ "untrusted": 0,
29
+ "user": 1,
30
+ "resource": 2,
31
+ "developer": 3,
32
+ "platform": 4,
33
+ }
34
+
27
35
 
28
36
  @dataclass(frozen=True)
29
37
  class ContributorCapabilities:
@@ -131,13 +139,15 @@ class WorkspaceRulesContributor(ContextContributor):
131
139
  return []
132
140
  items: list[ContextItem] = []
133
141
  for index, section in enumerate(sections):
142
+ raw_tokens = section.metadata.get("tokens", 0)
143
+ tokens = int(raw_tokens) if isinstance(raw_tokens, (int, str)) else 0
134
144
  items.append(
135
145
  _make_item(
136
146
  contributor_id=self.capabilities.contributor_id,
137
147
  trust_level=self.capabilities.trust_level,
138
148
  kind="resource_manifest",
139
149
  content=section.content,
140
- tokens=int(section.metadata.get("tokens", 0)) or 1,
150
+ tokens=tokens or 1,
141
151
  source=section.source,
142
152
  metadata={"path": section.metadata.get("path"), "kind": "rule_file"},
143
153
  )
@@ -267,6 +277,60 @@ class ContributionResult:
267
277
  warnings: tuple[str, ...]
268
278
 
269
279
 
280
+ def _admit_contribution_items(
281
+ contributor: ContextContributor,
282
+ items: object,
283
+ ) -> tuple[list[ContextItem], str | None]:
284
+ """Validate one Contributor result and enforce its declared token ceiling.
285
+
286
+ A Contributor is an untrusted capability boundary. It cannot promote an
287
+ item above the trust level granted at registration, mark context as
288
+ required, return duplicate identities, or make the Host confuse token
289
+ counts with list indexes. Items that do not fit the declared budget are
290
+ deterministically omitted while later, smaller items may still fit.
291
+ """
292
+
293
+ if not isinstance(items, list) or not all(isinstance(item, ContextItem) for item in items):
294
+ raise TypeError("ContextContributor must return a list of ContextItem values")
295
+
296
+ capabilities = contributor.capabilities
297
+ if capabilities.max_tokens < 0:
298
+ raise ValueError("ContextContributor max_tokens cannot be negative")
299
+ if capabilities.timeout_ms <= 0:
300
+ raise ValueError("ContextContributor timeout_ms must be positive")
301
+
302
+ admitted: list[ContextItem] = []
303
+ seen_ids: set[str] = set()
304
+ used_tokens = 0
305
+ omitted = 0
306
+ maximum_trust = _TRUST_RANK[capabilities.trust_level]
307
+ for item in items:
308
+ if not item.item_id or item.item_id in seen_ids:
309
+ raise ValueError("ContextContributor item ids must be non-empty and unique")
310
+ seen_ids.add(item.item_id)
311
+ if item.required:
312
+ raise ValueError("ContextContributor cannot mark context as required")
313
+ if _TRUST_RANK[item.trust_level] > maximum_trust:
314
+ raise ValueError(
315
+ "ContextContributor cannot elevate item trust above its registered level"
316
+ )
317
+ if item.estimated_tokens < 0:
318
+ raise ValueError("ContextContributor estimated_tokens cannot be negative")
319
+ if used_tokens + item.estimated_tokens > capabilities.max_tokens:
320
+ omitted += 1
321
+ continue
322
+ admitted.append(item)
323
+ used_tokens += item.estimated_tokens
324
+
325
+ warning = None
326
+ if omitted:
327
+ warning = (
328
+ f"{contributor.id()}: omitted {omitted} context item(s) that exceeded "
329
+ f"the {capabilities.max_tokens}-token contributor budget"
330
+ )
331
+ return admitted, warning
332
+
333
+
270
334
  async def run_contributors(
271
335
  contributors: Sequence[ContextContributor],
272
336
  request: ContextContributionRequest,
@@ -284,24 +348,25 @@ async def run_contributors(
284
348
  async def _run_one(c: ContextContributor) -> tuple[str, list[ContextItem], str, str | None]:
285
349
  timeout = max(c.capabilities.timeout_ms, 1) / 1000.0
286
350
  try:
287
- items = await asyncio.wait_for(c.contribute(request), timeout=timeout)
351
+ raw_items = await asyncio.wait_for(c.contribute(request), timeout=timeout)
352
+ items, budget_warning = _admit_contribution_items(c, raw_items)
288
353
  except asyncio.TimeoutError:
289
354
  return c.id(), [], "timeout", f"{c.id()}: timeout"
290
355
  except Exception as exc: # noqa: BLE001
291
356
  if c.capabilities.failure_mode == "fail":
292
357
  raise
293
- return c.id(), [], "error", f"{c.id()}: {exc}"
294
- # 单 Contributor 总 token 约束
295
- if items and sum(i.estimated_tokens for i in items) > c.capabilities.max_tokens:
296
- items = items[: c.capabilities.max_tokens] # best-effort 限条数
297
- return c.id(), items, "ok", None
358
+ warning = f"{c.id()}: {exc}" if c.capabilities.failure_mode == "warn" else None
359
+ return c.id(), [], "error", warning
360
+ return c.id(), items, "ok", budget_warning
298
361
 
299
362
  results = await asyncio.gather(*[_run_one(c) for c in contributors], return_exceptions=True)
300
363
  all_items: list[ContextItem] = []
301
364
  status: dict[str, str] = {}
302
365
  warnings: list[str] = []
303
366
  for contributor, r in zip(contributors, results):
304
- if isinstance(r, Exception):
367
+ if isinstance(r, BaseException):
368
+ if isinstance(r, asyncio.CancelledError):
369
+ raise r
305
370
  if contributor.capabilities.failure_mode == "fail":
306
371
  raise r
307
372
  warnings.append(f"{contributor.id()}: {r}")
@@ -11,6 +11,25 @@ def _exports(module: str, *names: str) -> dict[str, tuple[str, str]]:
11
11
 
12
12
 
13
13
  _EXPORTS = {
14
+ **_exports(
15
+ "ksadk.conversations.contracts",
16
+ "ConversationCapability",
17
+ "ConversationInput",
18
+ "ConversationAttachmentPart",
19
+ "ConversationItem",
20
+ "ConversationSurface",
21
+ "ConversationTextPart",
22
+ "validate_conversation_input",
23
+ "validate_surface_input",
24
+ ),
25
+ **_exports(
26
+ "ksadk.conversations.projector",
27
+ "project_conversation_item",
28
+ ),
29
+ **_exports(
30
+ "ksadk.conversations.reducer",
31
+ "ConversationItemReducer",
32
+ ),
14
33
  **_exports(
15
34
  "ksadk.conversations.attachments",
16
35
  "decode_inline_data",
@@ -5,6 +5,8 @@ import re
5
5
  from collections.abc import Mapping, Sequence
6
6
  from typing import Any, Dict, Iterable, List
7
7
 
8
+ from ksadk.events.canonical import ItemCompleted, parse_runtime_event
9
+ from ksadk.events.content import TextContent
8
10
  from ksadk.sessions.base import SessionEvent
9
11
  from ksadk.tools.result_budget import (
10
12
  ToolResultBudget,
@@ -99,6 +101,60 @@ def extract_event_text(event: SessionEvent) -> str:
99
101
  )
100
102
 
101
103
 
104
+ def _canonical_completed_message(
105
+ event: SessionEvent,
106
+ ) -> tuple[str, str, tuple[str, str]] | None:
107
+ """Return one canonical assistant message without flattening its identity.
108
+
109
+ Canonical RuntimeEvents are persisted inside the existing ``SessionEvent``
110
+ carrier. Legacy transcript projection only inspects carrier-level fields,
111
+ so an ``item.completed`` message otherwise disappears from the next turn's
112
+ history. The canonical event id and ``(scope_id, item_id)`` are both kept:
113
+ replays are idempotent, while equal text from different items remains
114
+ distinct.
115
+ """
116
+
117
+ raw = (event.content or {}).get("runtime_event")
118
+ if not isinstance(raw, Mapping):
119
+ return None
120
+ try:
121
+ canonical = parse_runtime_event(dict(raw))
122
+ except (TypeError, ValueError):
123
+ return None
124
+ if (
125
+ not isinstance(canonical, ItemCompleted)
126
+ or canonical.item_kind != "message"
127
+ or event.event_type != canonical.event_type
128
+ ):
129
+ return None
130
+ text = sanitize_event_text_for_context(
131
+ "".join(
132
+ part.text for part in canonical.snapshot.parts if isinstance(part, TextContent)
133
+ )
134
+ )
135
+ if not text:
136
+ return None
137
+ return canonical.event_id, text, (canonical.scope_id, canonical.item_id)
138
+
139
+
140
+ def _transcript_event_projection(
141
+ event: SessionEvent,
142
+ ) -> tuple[str, str, tuple[str, tuple[str, str]] | None]:
143
+ canonical_message = _canonical_completed_message(event)
144
+ if canonical_message is not None:
145
+ event_id, text, item_identity = canonical_message
146
+ return "assistant_message", text, (event_id, item_identity)
147
+ return (
148
+ canonical_event_type(
149
+ event.event_type,
150
+ author=event.author,
151
+ role=str((event.content or {}).get("role") or ""),
152
+ ),
153
+ extract_event_text(event),
154
+ None,
155
+ )
156
+
157
+
102
158
  def canonical_event_type(
103
159
  event_type: str | None,
104
160
  *,
@@ -276,6 +332,8 @@ def summarize_event_groups(
276
332
  因此跨消息提取修正,并在预算上限内保留最新长指令首尾(方案 §9.4)。
277
333
  """
278
334
  lines: List[str] = []
335
+ seen_canonical_event_ids: set[str] = set()
336
+ seen_canonical_items: set[tuple[str, str]] = set()
279
337
  if previous_summary:
280
338
  lines.append(previous_summary)
281
339
  lines.append("Earlier conversation summary:")
@@ -284,14 +342,18 @@ def summarize_event_groups(
284
342
  for group in groups:
285
343
  snippets: List[str] = []
286
344
  for event in group:
287
- event_type = canonical_event_type(
288
- event.event_type,
289
- author=event.author,
290
- role=str((event.content or {}).get("role") or ""),
291
- )
345
+ event_type, text, canonical_identity = _transcript_event_projection(event)
346
+ if canonical_identity is not None:
347
+ event_id, item_identity = canonical_identity
348
+ if (
349
+ event_id in seen_canonical_event_ids
350
+ or item_identity in seen_canonical_items
351
+ ):
352
+ continue
353
+ seen_canonical_event_ids.add(event_id)
354
+ seen_canonical_items.add(item_identity)
292
355
  if event_type not in TRANSCRIPT_EVENT_TYPES or event_type == "context_checkpoint":
293
356
  continue
294
- text = extract_event_text(event)
295
357
  if not text:
296
358
  continue
297
359
  if event_type in {"assistant_message", "tool_call"}:
@@ -343,6 +405,9 @@ def project_model_messages(
343
405
  """
344
406
  projected: List[Dict[str, str]] = []
345
407
  placeholder_flags: list[bool] = []
408
+ identity_boundary_flags: list[bool] = []
409
+ seen_canonical_event_ids: set[str] = set()
410
+ seen_canonical_items: set[tuple[str, str]] = set()
346
411
  compacted_until = compacted_until_seq_id(events)
347
412
  checkpoint = next(
348
413
  (
@@ -362,21 +427,26 @@ def project_model_messages(
362
427
  }
363
428
  )
364
429
  placeholder_flags.append(False)
430
+ identity_boundary_flags.append(False)
365
431
 
366
432
  for event in events:
367
- event_type = canonical_event_type(
368
- event.event_type,
369
- author=event.author,
370
- role=str((event.content or {}).get("role") or ""),
371
- )
433
+ event_type, text, canonical_identity = _transcript_event_projection(event)
372
434
  if event.seq_id <= compacted_until and event_type != "context_checkpoint":
373
435
  continue
374
436
  if event_type not in TRANSCRIPT_EVENT_TYPES:
375
437
  continue
376
438
  if event_type in {"context_checkpoint", "compaction_boundary"}:
377
439
  continue
440
+ if canonical_identity is not None:
441
+ event_id, item_identity = canonical_identity
442
+ if (
443
+ event_id in seen_canonical_event_ids
444
+ or item_identity in seen_canonical_items
445
+ ):
446
+ continue
447
+ seen_canonical_event_ids.add(event_id)
448
+ seen_canonical_items.add(item_identity)
378
449
 
379
- text = extract_event_text(event)
380
450
  if not text:
381
451
  continue
382
452
 
@@ -405,12 +475,15 @@ def project_model_messages(
405
475
  projected
406
476
  and projected[-1]["role"] == role
407
477
  and not placeholder_flags[-1]
478
+ and not identity_boundary_flags[-1]
408
479
  and not is_placeholder
480
+ and canonical_identity is None
409
481
  ):
410
482
  projected[-1]["content"] = f"{projected[-1]['content']}\n{text}".strip()
411
483
  else:
412
484
  projected.append({"role": role, "content": text})
413
485
  placeholder_flags.append(is_placeholder)
486
+ identity_boundary_flags.append(canonical_identity is not None)
414
487
 
415
488
  return projected
416
489
 
@@ -553,6 +626,8 @@ def project_responses_history(events: List[SessionEvent]) -> List[dict[str, Any]
553
626
  """
554
627
  projected: List[dict[str, Any]] = []
555
628
  projected_call_ids: set[str] = set()
629
+ seen_canonical_event_ids: set[str] = set()
630
+ seen_canonical_items: set[tuple[str, str]] = set()
556
631
  compacted_until = compacted_until_seq_id(events)
557
632
  checkpoint = next(
558
633
  (
@@ -568,17 +643,22 @@ def project_responses_history(events: List[SessionEvent]) -> List[dict[str, Any]
568
643
  projected.append(summary_message)
569
644
 
570
645
  for event in events:
571
- event_type = canonical_event_type(
572
- event.event_type,
573
- author=event.author,
574
- role=str((event.content or {}).get("role") or ""),
575
- )
646
+ event_type, text, canonical_identity = _transcript_event_projection(event)
576
647
  if event.seq_id <= compacted_until and event_type != "context_checkpoint":
577
648
  continue
578
649
  if event_type not in TRANSCRIPT_EVENT_TYPES:
579
650
  continue
580
651
  if event_type in {"context_checkpoint", "compaction_boundary"}:
581
652
  continue
653
+ if canonical_identity is not None:
654
+ event_id, item_identity = canonical_identity
655
+ if (
656
+ event_id in seen_canonical_event_ids
657
+ or item_identity in seen_canonical_items
658
+ ):
659
+ continue
660
+ seen_canonical_event_ids.add(event_id)
661
+ seen_canonical_items.add(item_identity)
582
662
 
583
663
  if event_type == "tool_call":
584
664
  item = _response_tool_call_item(event)
@@ -586,25 +666,25 @@ def project_responses_history(events: List[SessionEvent]) -> List[dict[str, Any]
586
666
  projected.append(item)
587
667
  projected_call_ids.add(str(item["call_id"]))
588
668
  continue
589
- message = _responses_message("assistant", f"[tool_call] {extract_event_text(event)}")
669
+ message = _responses_message("assistant", f"[tool_call] {text}")
590
670
  elif event_type == "tool_result":
591
671
  item = _response_tool_output_item(event)
592
672
  if item and str(item["call_id"]) in projected_call_ids:
593
673
  projected.append(item)
594
674
  continue
595
- message = _responses_message("user", f"[tool_result] {extract_event_text(event)}")
675
+ message = _responses_message("user", f"[tool_result] {text}")
596
676
  elif event_type == "assistant_message":
597
- message = _responses_message("assistant", extract_event_text(event))
677
+ message = _responses_message("assistant", text)
598
678
  elif event_type == "approval_request":
599
679
  message = _responses_message(
600
- "assistant", f"[approval_request] {extract_event_text(event)}"
680
+ "assistant", f"[approval_request] {text}"
601
681
  )
602
682
  elif event_type == "approval_response":
603
- message = _responses_message("user", f"[approval_response] {extract_event_text(event)}")
683
+ message = _responses_message("user", f"[approval_response] {text}")
604
684
  elif event_type == "attachment_ref":
605
- message = _responses_message("user", f"[attachment] {extract_event_text(event)}")
685
+ message = _responses_message("user", f"[attachment] {text}")
606
686
  else:
607
- message = _responses_message("user", extract_event_text(event))
687
+ message = _responses_message("user", text)
608
688
  if message:
609
689
  projected.append(message)
610
690
 
@@ -0,0 +1,266 @@
1
+ """Additive, provider-neutral conversation presentation contracts (v1)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+ from typing import Any, Literal
7
+
8
+ from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
9
+
10
+
11
+ def _to_camel(value: str) -> str:
12
+ head, *tail = value.split("_")
13
+ return head + "".join(part.capitalize() for part in tail)
14
+
15
+
16
+ class ConversationContractModel(BaseModel):
17
+ model_config = ConfigDict(
18
+ alias_generator=_to_camel,
19
+ populate_by_name=True,
20
+ extra="forbid",
21
+ frozen=True,
22
+ )
23
+
24
+
25
+ _CAPABILITY = re.compile(r"^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$")
26
+
27
+ # Provider-neutral wire extensions. These keys are deliberately namespaced:
28
+ # the stable ConversationInput/v1 envelope must not grow a top-level field for
29
+ # every control exposed by Codex, DSH, or a future AgentProvider.
30
+ APPROVAL_MODE_EXTENSION = "ksadk.approval"
31
+ COLLABORATION_MODE_EXTENSION = "ksadk.collaboration"
32
+ GOAL_OBJECTIVE_EXTENSION = "ksadk.goal"
33
+
34
+
35
+ class ConversationCapability(ConversationContractModel):
36
+ name: str = Field(min_length=1, max_length=128)
37
+ mode: Literal["native", "translated", "degraded", "unavailable"]
38
+ reason: str | None = Field(default=None, max_length=512)
39
+
40
+ @field_validator("name")
41
+ @classmethod
42
+ def validate_name(cls, value: str) -> str:
43
+ if not _CAPABILITY.fullmatch(value):
44
+ raise ValueError("capability name must be a namespaced identifier")
45
+ return value
46
+
47
+ @model_validator(mode="after")
48
+ def validate_reason(self) -> "ConversationCapability":
49
+ if self.mode in {"degraded", "unavailable"} and not self.reason:
50
+ raise ValueError("degraded or unavailable capability requires a reason")
51
+ return self
52
+
53
+
54
+ class ConversationSurface(ConversationContractModel):
55
+ api_version: Literal["conversation.ksadk.io/v1"] = "conversation.ksadk.io/v1"
56
+ kind: Literal["ConversationSurface"] = "ConversationSurface"
57
+ surface_id: str = Field(min_length=1, max_length=256)
58
+ session_id: str = Field(min_length=1, max_length=256)
59
+ provider_ref: str = Field(min_length=1, max_length=256)
60
+ inputs: tuple[ConversationCapability, ...] = ()
61
+ outputs: tuple[ConversationCapability, ...] = ()
62
+
63
+ @model_validator(mode="after")
64
+ def validate_unique_capabilities(self) -> "ConversationSurface":
65
+ for capabilities, direction in ((self.inputs, "input"), (self.outputs, "output")):
66
+ names = [capability.name for capability in capabilities]
67
+ if len(names) != len(set(names)):
68
+ raise ValueError(
69
+ f"conversation surface must not repeat an {direction} capability"
70
+ )
71
+ return self
72
+
73
+ def permits_input(self, field: str) -> bool:
74
+ return any(
75
+ capability.name == field and capability.mode in {"native", "translated"}
76
+ for capability in self.inputs
77
+ )
78
+
79
+
80
+ class ConversationTextPart(ConversationContractModel):
81
+ kind: Literal["text"] = "text"
82
+ text: str = Field(min_length=1, max_length=131072)
83
+
84
+
85
+ class ConversationAttachmentPart(ConversationContractModel):
86
+ kind: Literal["attachment"] = "attachment"
87
+ attachment_ref: str = Field(min_length=1, max_length=2048)
88
+ media_type: str = Field(min_length=1, max_length=256)
89
+ name: str | None = Field(default=None, max_length=1024)
90
+
91
+
92
+ ConversationInputPart = ConversationTextPart | ConversationAttachmentPart
93
+
94
+
95
+ class ConversationInput(ConversationContractModel):
96
+ """A provider-neutral foreground turn submitted by a conversation client.
97
+
98
+ It deliberately carries only user intent. A Server/Runtime adapter maps
99
+ that intent to a provider-specific request after checking the active
100
+ ConversationSurface; browser clients never forward arbitrary provider
101
+ parameters.
102
+ """
103
+
104
+ api_version: Literal["conversation.ksadk.io/v1"] = "conversation.ksadk.io/v1"
105
+ kind: Literal["ConversationInput"] = "ConversationInput"
106
+ input_id: str = Field(min_length=1, max_length=256)
107
+ session_id: str = Field(min_length=1, max_length=256)
108
+ idempotency_key: str = Field(min_length=1, max_length=512)
109
+ parts: tuple[ConversationInputPart, ...] = Field(min_length=1)
110
+ model_ref: str | None = Field(default=None, min_length=1, max_length=256)
111
+ reasoning: str | None = Field(default=None, min_length=1, max_length=64)
112
+ extensions: dict[str, Any] = Field(default_factory=dict)
113
+
114
+ @field_validator("extensions")
115
+ @classmethod
116
+ def validate_extensions(cls, value: dict[str, Any]) -> dict[str, Any]:
117
+ if any(not _CAPABILITY.fullmatch(key) or "." not in key for key in value):
118
+ raise ValueError("extensions must use namespaced capability keys")
119
+ approval = value.get(APPROVAL_MODE_EXTENSION)
120
+ if approval is not None and approval not in {"ask", "risk", "full"}:
121
+ raise ValueError("ksadk.approval must be ask, risk, or full")
122
+ collaboration = value.get(COLLABORATION_MODE_EXTENSION)
123
+ if collaboration is not None and collaboration not in {"default", "plan"}:
124
+ raise ValueError("ksadk.collaboration must be default or plan")
125
+ goal = value.get(GOAL_OBJECTIVE_EXTENSION)
126
+ if goal is not None and (
127
+ not isinstance(goal, str) or not goal.strip() or len(goal) > 4096
128
+ ):
129
+ raise ValueError("ksadk.goal must be a non-empty string up to 4096 characters")
130
+ return value
131
+
132
+ @property
133
+ def approval_mode(self) -> Literal["ask", "risk", "full"] | None:
134
+ value = self.extensions.get(APPROVAL_MODE_EXTENSION)
135
+ return value if value in {"ask", "risk", "full"} else None
136
+
137
+ @property
138
+ def collaboration_mode(self) -> Literal["default", "plan"] | None:
139
+ value = self.extensions.get(COLLABORATION_MODE_EXTENSION)
140
+ return value if value in {"default", "plan"} else None
141
+
142
+ @property
143
+ def goal_objective(self) -> str | None:
144
+ value = self.extensions.get(GOAL_OBJECTIVE_EXTENSION)
145
+ return value if isinstance(value, str) and value else None
146
+
147
+ def required_capabilities(self) -> tuple[str, ...]:
148
+ required: list[str] = []
149
+ if any(isinstance(part, ConversationTextPart) for part in self.parts):
150
+ required.append("text")
151
+ for part in self.parts:
152
+ if not isinstance(part, ConversationAttachmentPart):
153
+ continue
154
+ required.append(
155
+ "attachment.image"
156
+ if part.media_type.lower().startswith("image/")
157
+ else "attachment.file"
158
+ )
159
+ if self.model_ref:
160
+ required.append("model.select")
161
+ if self.reasoning:
162
+ required.append("reasoning.effort")
163
+ if self.approval_mode:
164
+ required.append("approval")
165
+ if self.collaboration_mode == "plan":
166
+ required.append("plan")
167
+ if self.goal_objective:
168
+ required.append("goal")
169
+ extension_capabilities = {
170
+ APPROVAL_MODE_EXTENSION: "approval",
171
+ COLLABORATION_MODE_EXTENSION: "plan"
172
+ if self.collaboration_mode == "plan"
173
+ else None,
174
+ GOAL_OBJECTIVE_EXTENSION: "goal",
175
+ }
176
+ required.extend(
177
+ extension_capabilities.get(key, key)
178
+ for key in self.extensions
179
+ if extension_capabilities.get(key, key) is not None
180
+ )
181
+ return tuple(dict.fromkeys(required))
182
+
183
+
184
+ class ConversationItem(ConversationContractModel):
185
+ api_version: Literal["conversation.ksadk.io/v1"] = "conversation.ksadk.io/v1"
186
+ kind_version: Literal[1] = 1
187
+ item_id: str = Field(min_length=1, max_length=512)
188
+ parent_item_id: str | None = Field(default=None, min_length=1, max_length=512)
189
+ source_event_ids: tuple[str, ...] = Field(min_length=1)
190
+ session_id: str = Field(min_length=1, max_length=256)
191
+ run_id: str = Field(min_length=1, max_length=256)
192
+ kind: Literal[
193
+ "user_message",
194
+ "assistant_text",
195
+ "reasoning",
196
+ "tool_call",
197
+ "approval",
198
+ "progress",
199
+ "plan",
200
+ "goal",
201
+ "artifact",
202
+ "a2ui",
203
+ "error",
204
+ "unknown",
205
+ ]
206
+ operation: Literal["append", "replace", "completed"]
207
+ lifecycle: Literal["pending", "streaming", "completed", "failed"]
208
+ visibility: Literal["public", "internal", "hidden"] = "public"
209
+ payload_schema_ref: str = Field(min_length=1, max_length=256)
210
+ payload: dict[str, Any] = Field(default_factory=dict)
211
+ capability_ref: str | None = Field(default=None, max_length=256)
212
+ native_ref: dict[str, Any] = Field(default_factory=dict)
213
+
214
+ @field_validator("source_event_ids")
215
+ @classmethod
216
+ def validate_source_event_ids(cls, value: tuple[str, ...]) -> tuple[str, ...]:
217
+ if any(not item for item in value) or len(value) != len(set(value)):
218
+ raise ValueError("sourceEventIds must be non-empty and unique")
219
+ return value
220
+
221
+ @model_validator(mode="after")
222
+ def validate_lifecycle(self) -> "ConversationItem":
223
+ if self.operation == "completed" and self.lifecycle not in {"completed", "failed"}:
224
+ raise ValueError("completed operation requires a terminal lifecycle")
225
+ return self
226
+
227
+
228
+ def validate_surface_input(surface: ConversationSurface, payload: dict[str, Any]) -> None:
229
+ """Reject UI input fields not declared by the active ConversationSurface."""
230
+
231
+ extensions = payload.get("extensions", {})
232
+ if extensions is not None and not isinstance(extensions, dict):
233
+ raise ValueError("extensions must be an object")
234
+ for field in payload:
235
+ if field == "extensions":
236
+ continue
237
+ if not surface.permits_input(field):
238
+ raise ValueError(f"conversation input is not declared by surface: {field}")
239
+
240
+
241
+ def validate_conversation_input(
242
+ surface: ConversationSurface,
243
+ conversation_input: ConversationInput,
244
+ ) -> None:
245
+ """Apply the same capability allowlist before and after the network hop."""
246
+
247
+ if surface.session_id != conversation_input.session_id:
248
+ raise ValueError("conversation input session does not match active surface")
249
+ for capability in conversation_input.required_capabilities():
250
+ if not surface.permits_input(capability):
251
+ raise ValueError(f"conversation input is not declared by surface: {capability}")
252
+
253
+
254
+ __all__ = [
255
+ "APPROVAL_MODE_EXTENSION",
256
+ "COLLABORATION_MODE_EXTENSION",
257
+ "ConversationCapability",
258
+ "ConversationInput",
259
+ "ConversationAttachmentPart",
260
+ "ConversationItem",
261
+ "ConversationSurface",
262
+ "ConversationTextPart",
263
+ "GOAL_OBJECTIVE_EXTENSION",
264
+ "validate_conversation_input",
265
+ "validate_surface_input",
266
+ ]