agentengine-sdk-python 0.8.3__py3-none-any.whl → 0.8.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (509) hide show
  1. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/METADATA +9 -8
  2. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/RECORD +482 -245
  3. ksadk/_build_provenance.json +1 -1
  4. ksadk/api/client.py +105 -91
  5. ksadk/builders/code_builder.py +36 -9
  6. ksadk/builders/framework_requirements.py +2 -1
  7. ksadk/builders/ks3_uploader.py +36 -7
  8. ksadk/builders/managed_runtime_builder.py +1 -0
  9. ksadk/cli/__init__.py +32 -3
  10. ksadk/cli/cmd_managed_runtime.py +13 -1
  11. ksadk/cli/cmd_plugin.py +6 -1
  12. ksadk/cli/cmd_web.py +2 -5
  13. ksadk/cli/runtime_bootstrap.py +23 -1
  14. ksadk/codex/client.py +424 -96
  15. ksadk/codex/projection.py +24 -0
  16. ksadk/codex/runtime.py +56 -298
  17. ksadk/common/auth.py +16 -10
  18. ksadk/configs/env_registry.py +29 -1
  19. ksadk/conversations/message_projection.py +135 -14
  20. ksadk/conversations/projector.py +4 -6
  21. ksadk/conversations/runtime_invocation.py +5 -0
  22. ksadk/conversations/runtime_payloads.py +1 -0
  23. ksadk/conversations/runtime_preparation.py +30 -27
  24. ksadk/conversations/runtime_resume.py +50 -2
  25. ksadk/conversations/runtime_stream_events.py +5 -0
  26. ksadk/conversations/runtime_streaming.py +25 -7
  27. ksadk/deployment/env_forward.py +2 -2
  28. ksadk/deployment/providers/serverless.py +1 -1
  29. ksadk/events/adapters/_codex_validators.py +18 -7
  30. ksadk/events/adapters/langgraph.py +15 -1
  31. ksadk/events/canonical_store.py +3 -1
  32. ksadk/events/projections.py +1 -1
  33. ksadk/harness/config.py +2 -2
  34. ksadk/harness/runtime.py +27 -27
  35. ksadk/harness/tools.py +38 -13
  36. ksadk/interaction/provider.py +1 -0
  37. ksadk/interaction/providers/langgraph.py +1 -0
  38. ksadk/kernel/bootstrap.py +28 -4
  39. ksadk/kernel/ingress.py +15 -2
  40. ksadk/kernel/sqlite_store.py +27 -0
  41. ksadk/kernel/store.py +3 -0
  42. ksadk/kernel/worker.py +65 -10
  43. ksadk/knowledge_base/client.py +57 -27
  44. ksadk/mcp_runtime/__init__.py +12 -4
  45. ksadk/memory/adk/backends/sdk_ltm_backend.py +161 -41
  46. ksadk/memory/adk/resilient_session_service.py +25 -17
  47. ksadk/memory/adk/short_term_memory.py +26 -9
  48. ksadk/memory/models.py +7 -4
  49. ksadk/memory/provider_resolver.py +3 -0
  50. ksadk/model_proxy/server.py +10 -5
  51. ksadk/plugins/__init__.py +4 -0
  52. ksadk/plugins/artifacts.py +275 -0
  53. ksadk/plugins/bridges/__init__.py +4 -2
  54. ksadk/plugins/bridges/codex.py +120 -13
  55. ksadk/plugins/bridges/dsh.py +340 -156
  56. ksadk/plugins/builtins.py +35 -36
  57. ksadk/plugins/bundle_security.py +28 -4
  58. ksadk/plugins/codex_manifest.py +983 -0
  59. ksadk/plugins/composition.py +8 -0
  60. ksadk/plugins/contracts.py +118 -0
  61. ksadk/plugins/delivery.py +153 -0
  62. ksadk/plugins/dsh_installation_digest.py +71 -0
  63. ksadk/plugins/dsh_toolchain.py +110 -21
  64. ksadk/plugins/ecosystem_probe.py +6 -6
  65. ksadk/plugins/host.py +102 -39
  66. ksadk/plugins/kernel_adapter.py +205 -0
  67. ksadk/plugins/providers/__init__.py +23 -0
  68. ksadk/plugins/providers/bundles/dsh-knowledge/cordis.patch.yml +3 -0
  69. ksadk/plugins/providers/bundles/dsh-knowledge/index.mjs +53 -0
  70. ksadk/plugins/providers/bundles/dsh-knowledge/package.json +16 -0
  71. ksadk/plugins/providers/bundles/dsh-memory/cordis.patch.yml +3 -0
  72. ksadk/plugins/providers/bundles/dsh-memory/index.mjs +175 -0
  73. ksadk/plugins/providers/bundles/dsh-memory/package.json +16 -0
  74. ksadk/plugins/providers/bundles/dsh-platform-resources/client.mjs +166 -0
  75. ksadk/plugins/providers/bundles/dsh-platform-resources/cordis.patch.yml +3 -0
  76. ksadk/plugins/providers/bundles/dsh-platform-resources/index.mjs +9 -0
  77. ksadk/plugins/providers/bundles/dsh-platform-resources/package.json +12 -0
  78. ksadk/plugins/providers/bundles/dsh-skill-center/cordis.patch.yml +3 -0
  79. ksadk/plugins/providers/bundles/dsh-skill-center/index.mjs +125 -0
  80. ksadk/plugins/providers/bundles/dsh-skill-center/package.json +16 -0
  81. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/cordis.patch.yml +3 -0
  82. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/index.mjs +870 -0
  83. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +27 -0
  84. ksadk/plugins/providers/bundles/ksadk-dsh-studio/client.js +92 -0
  85. ksadk/plugins/providers/bundles/ksadk-dsh-studio/index.mjs +15 -0
  86. ksadk/plugins/providers/bundles/ksadk-dsh-studio/package.json +7 -0
  87. ksadk/plugins/providers/codex.py +335 -69
  88. ksadk/plugins/providers/codex_native.py +368 -0
  89. ksadk/plugins/providers/codex_turn.py +301 -0
  90. ksadk/plugins/providers/dsh_capabilities.py +1389 -0
  91. ksadk/plugins/providers/dsh_mcp.py +467 -0
  92. ksadk/plugins/providers/harness.py +118 -113
  93. ksadk/plugins/providers/mcp_projection.py +150 -0
  94. ksadk/plugins/providers/platform_resources.py +657 -0
  95. ksadk/plugins/resolver.py +8 -1
  96. ksadk/resource_runtime/__init__.py +4 -0
  97. ksadk/resource_runtime/broker.py +616 -0
  98. ksadk/resource_runtime/build_artifacts.py +165 -0
  99. ksadk/resource_runtime/contracts.py +138 -0
  100. ksadk/resource_runtime/discovery_receipts.py +100 -0
  101. ksadk/resource_runtime/discovery_skills.py +172 -0
  102. ksadk/resource_runtime/errors.py +6 -0
  103. ksadk/resource_runtime/ipc.py +142 -0
  104. ksadk/resource_runtime/kernel_approval.py +165 -0
  105. ksadk/resource_runtime/knowledge.py +114 -0
  106. ksadk/resource_runtime/langgraph.py +94 -0
  107. ksadk/resource_runtime/leases.py +191 -0
  108. ksadk/resource_runtime/managed_projection.py +186 -0
  109. ksadk/resource_runtime/mcp_server.py +138 -0
  110. ksadk/resource_runtime/memory_provider.py +318 -0
  111. ksadk/resource_runtime/memory_receipts.py +34 -0
  112. ksadk/resource_runtime/operation_ledger.py +211 -0
  113. ksadk/resource_runtime/plugin_config.py +48 -0
  114. ksadk/resource_runtime/policy_authorization.py +54 -0
  115. ksadk/resource_runtime/process.py +110 -0
  116. ksadk/resource_runtime/skill_artifacts.py +153 -0
  117. ksadk/resource_runtime/skill_runtime.py +42 -0
  118. ksadk/resource_runtime/skill_workspace.py +118 -0
  119. ksadk/resource_runtime/skills.py +215 -0
  120. ksadk/resource_runtime/snapshots.py +180 -0
  121. ksadk/resource_runtime/socket_server.py +103 -0
  122. ksadk/resource_runtime/supervisor.py +380 -0
  123. ksadk/resource_runtime/worker.py +504 -0
  124. ksadk/runners/_langgraph_runner_streams.py +74 -6
  125. ksadk/runners/adk_runner.py +149 -11
  126. ksadk/runners/base_runner.py +29 -1
  127. ksadk/runners/langgraph_runner.py +475 -145
  128. ksadk/runtime/_runner_adapter/stream_mapping.py +142 -18
  129. ksadk/runtime/adapter.py +2 -0
  130. ksadk/runtime/conversation_execution.py +92 -16
  131. ksadk/runtime/executor.py +78 -2
  132. ksadk/runtime/factory.py +29 -273
  133. ksadk/runtime/framework_adapters.py +23 -0
  134. ksadk/runtime/preprocessing.py +10 -2
  135. ksadk/runtime/runner_adapter.py +73 -14
  136. ksadk/runtime_context.py +40 -2
  137. ksadk/sandbox/backends/e2b.py +52 -11
  138. ksadk/sandbox/backends/local_process.py +9 -0
  139. ksadk/sandbox/base.py +2 -0
  140. ksadk/sandbox/e2b_connection.py +66 -0
  141. ksadk/scheduler/sqlite_store.py +18 -0
  142. ksadk/server/composition.py +2 -0
  143. ksadk/server/factory.py +5 -0
  144. ksadk/server/persistence_capability.py +516 -0
  145. ksadk/server/routes/control.py +210 -46
  146. ksadk/server/routes/dependencies.py +15 -0
  147. ksadk/server/routes/models.py +47 -4
  148. ksadk/server/routes/projection.py +252 -12
  149. ksadk/server/routes/sessions.py +284 -107
  150. ksadk/server/routes/streaming.py +43 -9
  151. ksadk/server/static/assets/{ArtifactsPanel-10GPXIJ6.js → ArtifactsPanel-CGbWlMNh.js} +1 -1
  152. ksadk/server/static/assets/{CodeBlock-BXk1l-G1.js → CodeBlock-b4C7upmO.js} +3 -3
  153. ksadk/server/static/assets/{MathMessageMarkdown-D9uB55Oh.js → MathMessageMarkdown-DbdW5A4_.js} +4 -4
  154. ksadk/server/static/assets/{MermaidBlock--OEYoXIJ.js → MermaidBlock-BEBN4Ksz.js} +6 -6
  155. ksadk/server/static/assets/{NativeTerminalPanel-DrEe1syq.js → NativeTerminalPanel-zvL-WpAn.js} +1 -1
  156. ksadk/server/static/assets/{abnfDiagram-VCTEODGH-eeTFJLvo.js → abnfDiagram-VCTEODGH-BYafW7Za.js} +1 -1
  157. ksadk/server/static/assets/{arc-S3ZNbIAd.js → arc-bTohInsS.js} +1 -1
  158. ksadk/server/static/assets/architecture-7GRP2DOG-BW5UtSnx.js +1 -0
  159. ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-CRjgEJDX.js → architectureDiagram-5GKGNRK7-Ch5Lbzsi.js} +1 -1
  160. ksadk/server/static/assets/{blockDiagram-NRAW4CY4-C7bsBoNH.js → blockDiagram-NRAW4CY4-kqF4MDOG.js} +1 -1
  161. ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-BX3c33Ob.js → c4Diagram-UCG6FXSJ-8uSRIODv.js} +1 -1
  162. ksadk/server/static/assets/channel-CF5Up3hQ.js +1 -0
  163. ksadk/server/static/assets/chunk-2Q5K7J3B-KkXX47WI.js +1 -0
  164. ksadk/server/static/assets/{chunk-5VM5RSS4-bZ7ws-8m.js → chunk-5VM5RSS4-DkhehZDr.js} +1 -1
  165. ksadk/server/static/assets/{chunk-F27PBJKO-D2r0pvhY.js → chunk-F27PBJKO-BdXhtPe9.js} +1 -1
  166. ksadk/server/static/assets/{chunk-G27WJ6UU-CZwF3oUP.js → chunk-G27WJ6UU-DPTpvpwi.js} +1 -1
  167. ksadk/server/static/assets/{chunk-JWPE2WC7-DigFYCML.js → chunk-JWPE2WC7-Pqoh38el.js} +1 -1
  168. ksadk/server/static/assets/{chunk-LCL6LL3I-CnorGV5q.js → chunk-LCL6LL3I-DeU00qC-.js} +1 -1
  169. ksadk/server/static/assets/{chunk-POPQ4Y6H-CexntQA-.js → chunk-POPQ4Y6H-CzxScFkr.js} +1 -1
  170. ksadk/server/static/assets/{chunk-RHFEMEQ7-CHTC7UxA.js → chunk-RHFEMEQ7-DpqMx-ux.js} +1 -1
  171. ksadk/server/static/assets/{chunk-SVP7TREG-BC1EWt_-.js → chunk-SVP7TREG-C6t0SypQ.js} +1 -1
  172. ksadk/server/static/assets/{chunk-XXDRQBXY-BTG24xN0.js → chunk-XXDRQBXY-DVaeafZk.js} +1 -1
  173. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Cz81acRQ.js +1 -0
  174. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Cz81acRQ.js +1 -0
  175. ksadk/server/static/assets/{cose-bilkent-JH36ORCC-CkonRdAS.js → cose-bilkent-JH36ORCC-Bf9D3tzJ.js} +1 -1
  176. ksadk/server/static/assets/cynefin-OW5HDTMX-DVWs8a2t.js +1 -0
  177. ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-DEOCBe15.js → cynefinDiagram-5FMLGOSQ-B9cY3iTz.js} +1 -1
  178. ksadk/server/static/assets/{dagre-3AP2YEHR-DBThPuLa.js → dagre-3AP2YEHR-CSwlx3CB.js} +1 -1
  179. ksadk/server/static/assets/{dagre-ClTPrTht.js → dagre-UBpgon5q.js} +1 -1
  180. ksadk/server/static/assets/{diagram-S7CK7UJ4-DsZHrnpJ.js → diagram-S7CK7UJ4-C9akhN9a.js} +1 -1
  181. ksadk/server/static/assets/{diagram-UQ7AKVKN-BJR4nhVr.js → diagram-UQ7AKVKN-CgedhTPI.js} +1 -1
  182. ksadk/server/static/assets/{diagram-VSXAHHWV-xzcERX0a.js → diagram-VSXAHHWV-Cjucz5BY.js} +1 -1
  183. ksadk/server/static/assets/{diagram-VX7I27RA-tn2xM1xu.js → diagram-VX7I27RA-Dd4Vleyn.js} +1 -1
  184. ksadk/server/static/assets/{diagram-Z3DM3KII-BZPGBkw5.js → diagram-Z3DM3KII-CZ2jGtYW.js} +1 -1
  185. ksadk/server/static/assets/{dist-DdRBIceA.js → dist-B2_CVgKv.js} +1 -1
  186. ksadk/server/static/assets/{dist-Cq4OL6nO.js → dist-B3FR1SKK.js} +1 -1
  187. ksadk/server/static/assets/{dist-M67Hwu0n.js → dist-BIr4DSRq.js} +1 -1
  188. ksadk/server/static/assets/{dist-B1oWRmrH.js → dist-BgV_owcB.js} +1 -1
  189. ksadk/server/static/assets/{dist-DyqV4fL4.js → dist-Bj730Ib4.js} +1 -1
  190. ksadk/server/static/assets/{dist-DfGFrb0v.js → dist-BnaTiyzN.js} +1 -1
  191. ksadk/server/static/assets/{dist-C71CsujO.js → dist-C1NMAY5a.js} +1 -1
  192. ksadk/server/static/assets/{dist-CXpH_Rdd.js → dist-C5_ZAZsG.js} +1 -1
  193. ksadk/server/static/assets/{dist-DJmCPRVB.js → dist-CB9iJrvg.js} +1 -1
  194. ksadk/server/static/assets/{dist-DjhwGUgZ.js → dist-CFzsn6BG.js} +1 -1
  195. ksadk/server/static/assets/{dist-BI1qQH4n.js → dist-Cf125P_m.js} +1 -1
  196. ksadk/server/static/assets/{dist-8VWI-2bZ.js → dist-ClYUxfeK.js} +1 -1
  197. ksadk/server/static/assets/{dist-DUwKa_l6.js → dist-DFD6Qa6T.js} +1 -1
  198. ksadk/server/static/assets/{dist-B-46q3Hk.js → dist-DVCOWtha.js} +1 -1
  199. ksadk/server/static/assets/{dist-BJLUwH6W.js → dist-D_ctSS2i.js} +1 -1
  200. ksadk/server/static/assets/{dist-4zN1_tq5.js → dist-DiixqL0J.js} +1 -1
  201. ksadk/server/static/assets/{dist-B0gdk4rl.js → dist-DoVSwoDb.js} +1 -1
  202. ksadk/server/static/assets/{dist-Bbwqa8TG.js → dist-DvFK7p5S.js} +1 -1
  203. ksadk/server/static/assets/{dist-D1V3f1B4.js → dist-QfkEHOlb.js} +1 -1
  204. ksadk/server/static/assets/{dist-Btyo4vX4.js → dist-btbmmX5O.js} +1 -1
  205. ksadk/server/static/assets/{dist-u8tVH5Ak.js → dist-fBO2v5Kt.js} +1 -1
  206. ksadk/server/static/assets/{dist-DQAB0qn_.js → dist-ufY3F5p6.js} +1 -1
  207. ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-DVfMsLge.js → ebnfDiagram-PWID7BFC-Ci8NqqZu.js} +1 -1
  208. ksadk/server/static/assets/{erDiagram-SSCWMZ5O-CWEZSYaw.js → erDiagram-SSCWMZ5O-CCIOhLZG.js} +1 -1
  209. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CQqR2hg3.js +1 -0
  210. ksadk/server/static/assets/flowDiagram-A5DVABFB-DDRRbGPm.js +1 -0
  211. ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-TWIxoyYL.js → ganttDiagram-EL5Y4UJY-Cp_r9Hb6.js} +1 -1
  212. ksadk/server/static/assets/gitGraph-4MIJSDKK-fgWEf7UD.js +1 -0
  213. ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-DDh2hd2S.js → gitGraphDiagram-WWUBYQGX-Dlhc8Wr8.js} +1 -1
  214. ksadk/server/static/assets/index-DcTML1Up.css +2 -0
  215. ksadk/server/static/assets/index-Dh2XHqPK.js +244 -0
  216. ksadk/server/static/assets/info-A6RAGUB7-BUecLTdt.js +1 -0
  217. ksadk/server/static/assets/{infoDiagram-RXCK75RN-CgoyWiDR.js → infoDiagram-RXCK75RN-CO0rRTRA.js} +1 -1
  218. ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-CyRIu_om.js → ishikawaDiagram-5VMMS53U-CHiaedSS.js} +1 -1
  219. ksadk/server/static/assets/{journeyDiagram-EYS64GPL-DN5JXHzN.js → journeyDiagram-EYS64GPL-CHcCIB09.js} +1 -1
  220. ksadk/server/static/assets/{kanban-definition-3QL26DDD-CNP3ui66.js → kanban-definition-3QL26DDD-CJ_ebBZf.js} +1 -1
  221. ksadk/server/static/assets/{katex-DWEzQy1d.js → katex-B4weu383.js} +1 -1
  222. ksadk/server/static/assets/{linear-C-qHp7d2.js → linear-V-MgYHW1.js} +1 -1
  223. ksadk/server/static/assets/{mermaid-parser.core-Cl-K943T.js → mermaid-parser.core-CBijEX_c.js} +2 -2
  224. ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-D5DB5mYm.js → mindmap-definition-FBJOCRG2-Bc-pQvpp.js} +1 -1
  225. ksadk/server/static/assets/packet-AYTQ26CC-BeW-btFv.js +1 -0
  226. ksadk/server/static/assets/{pegDiagram-XKGWAZYB-BQVc9ia_.js → pegDiagram-XKGWAZYB-D7genGLl.js} +1 -1
  227. ksadk/server/static/assets/pie-WAS4IAKB-X0xh4SaT.js +1 -0
  228. ksadk/server/static/assets/{pieDiagram-E7YTZNPT-B6UCAvtY.js → pieDiagram-E7YTZNPT-Bxj32zwD.js} +1 -1
  229. ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-mIr2d3eb.js → quadrantDiagram-AXDQQJYC-BURv2mGh.js} +1 -1
  230. ksadk/server/static/assets/radar-RG4KPBEZ-DzRMSqjd.js +1 -0
  231. ksadk/server/static/assets/railroad-74A4TZTK-Cc44icX-.js +1 -0
  232. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-D6S4BdV-.js +1 -0
  233. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-vD3aVE2o.js +1 -0
  234. ksadk/server/static/assets/railroad-peg-WCYAUIDC-CYbW_b4T.js +1 -0
  235. ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-Dt3FFDmK.js → railroadDiagram-O6MQD6OU-CCsh3avW.js} +1 -1
  236. ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-Cz_vQtgF.js → requirementDiagram-EFPCY7ZU-_FRRBKEd.js} +1 -1
  237. ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-wlO1TsH5.js → sankeyDiagram-P5KCCOFB-C-gr2o9M.js} +1 -1
  238. ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-CHRbElYq.js → sequenceDiagram-WJ2MYXX4-D97NmfKg.js} +1 -1
  239. ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-DXX54iyO.js → sizeCapture-X5ZJPWSS-DjrPC5FX.js} +1 -1
  240. ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-Dp_lw9II.js → stateDiagram-HBIQ2CUA-DzMNg1hh.js} +1 -1
  241. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BIcjKFhF.js +1 -0
  242. ksadk/server/static/assets/{swimlanes-XN3QIQJK-D8O5UlLG.js → swimlanes-XN3QIQJK-Cssf_CsU.js} +1 -1
  243. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-tq3K3Ybl.js +8 -0
  244. ksadk/server/static/assets/{timeline-definition-24CTP7MA-8mfKcxvG.js → timeline-definition-24CTP7MA-BWTHzyS1.js} +1 -1
  245. ksadk/server/static/assets/treeView-Q6P3EWNA-DBXt3GdU.js +1 -0
  246. ksadk/server/static/assets/treemap-WGGIJYW6-DrCy4E_l.js +1 -0
  247. ksadk/server/static/assets/{vennDiagram-4TSXK5OY-EnNl0DE7.js → vennDiagram-4TSXK5OY-BSKgJsmR.js} +1 -1
  248. ksadk/server/static/assets/wardley-WFR3VGLG-CefhOliM.js +1 -0
  249. ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-DBu5fbYr.js → wardleyDiagram-VM6X3IG4-eflHNoaZ.js} +1 -1
  250. ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-BSVXs4IY.js → xychartDiagram-S5SC5T6Z-eYqrQ-v4.js} +1 -1
  251. ksadk/server/static/index.html +2 -2
  252. ksadk/session_context.py +66 -0
  253. ksadk/sessions/__init__.py +11 -21
  254. ksadk/sessions/_local_service_sync.py +263 -1
  255. ksadk/sessions/base.py +176 -0
  256. ksadk/sessions/errors.py +4 -0
  257. ksadk/sessions/in_memory.py +309 -19
  258. ksadk/sessions/local_service.py +83 -1
  259. ksadk/sessions/persistence.py +275 -0
  260. ksadk/sessions/postgres_service.py +358 -0
  261. ksadk/sessions/resilience.py +8 -0
  262. ksadk/sessions/resilient.py +362 -4
  263. ksadk/sessions/topology.py +135 -0
  264. ksadk/skills/models.py +26 -4
  265. ksadk/skills/package_store.py +186 -38
  266. ksadk/skills/runtime/agent.py +31 -6
  267. ksadk/skills/runtime/artifact_delivery.py +139 -0
  268. ksadk/skills/runtime/backends/e2b.py +98 -6
  269. ksadk/skills/runtime/backends/local.py +73 -8
  270. ksadk/skills/runtime/base.py +3 -0
  271. ksadk/skills/runtime/executor.py +2 -0
  272. ksadk/skills/runtime/loader.py +10 -2
  273. ksadk/skills/runtime/pinned.py +114 -0
  274. ksadk/skills/runtime/request.py +31 -0
  275. ksadk/skills/service_client.py +167 -28
  276. ksadk/studio/api.py +224 -42
  277. ksadk/studio/api_catalog_routes.py +18 -0
  278. ksadk/studio/api_plugin_routes.py +526 -95
  279. ksadk/studio/api_resource_connections.py +183 -0
  280. ksadk/studio/authoring_coordinator.py +19 -14
  281. ksadk/studio/builder.py +76 -0
  282. ksadk/studio/cloud.py +342 -104
  283. ksadk/studio/cloud_shared_web.py +565 -0
  284. ksadk/studio/codex_agent_service.py +128 -26
  285. ksadk/studio/codex_builder.py +241 -2
  286. ksadk/studio/codex_credentials.py +90 -0
  287. ksadk/studio/codex_manifest.py +31 -4
  288. ksadk/studio/codex_plugin_store.py +746 -0
  289. ksadk/studio/codex_provider_build.py +231 -0
  290. ksadk/studio/codex_run.py +184 -25
  291. ksadk/studio/compatibility_report.py +12 -1
  292. ksadk/studio/compiler.py +78 -14
  293. ksadk/studio/contracts.py +132 -6
  294. ksadk/studio/dsh_application.py +137 -0
  295. ksadk/studio/dsh_capability_service.py +1107 -0
  296. ksadk/studio/dsh_models.py +59 -0
  297. ksadk/studio/dsh_provider_registration.py +320 -13
  298. ksadk/studio/hosted_kernel.py +88 -13
  299. ksadk/studio/mcp_runtime.py +11 -3
  300. ksadk/studio/model_client.py +2 -2
  301. ksadk/studio/plugin_composition.py +190 -23
  302. ksadk/studio/plugin_kernel_adapter.py +12 -112
  303. ksadk/studio/plugin_runtime.py +224 -45
  304. ksadk/studio/resource_authority.py +637 -0
  305. ksadk/studio/resource_binding_validation.py +77 -0
  306. ksadk/studio/resource_build_admission.py +196 -0
  307. ksadk/studio/resource_build_materializer.py +149 -0
  308. ksadk/studio/resource_catalog.py +143 -2
  309. ksadk/studio/resource_connections.py +220 -0
  310. ksadk/studio/run_service.py +462 -52
  311. ksadk/studio/runtime_source.py +15 -7
  312. ksadk/studio/scheduler_assistant.py +317 -0
  313. ksadk/studio/scheduler_runtime.py +9 -0
  314. ksadk/studio/scheduler_service.py +3 -0
  315. ksadk/studio/service.py +490 -44
  316. ksadk/studio/shared_web.py +446 -62
  317. ksadk/studio/static/assets/CodeBlock-DCUUY0PL-BLjA7kbS.js +41 -0
  318. ksadk/studio/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  319. ksadk/studio/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  320. ksadk/studio/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  321. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  322. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  323. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  324. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  325. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  326. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  327. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  328. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  329. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  330. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  331. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  332. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  333. ksadk/studio/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  334. ksadk/studio/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  335. ksadk/studio/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  336. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  337. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  338. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  339. ksadk/studio/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  340. ksadk/studio/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  341. ksadk/studio/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  342. ksadk/studio/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  343. ksadk/studio/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  344. ksadk/studio/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  345. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  346. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  347. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  348. ksadk/studio/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  349. ksadk/studio/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  350. ksadk/studio/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  351. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  352. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  353. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  354. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  355. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  356. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  357. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  358. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  359. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  360. ksadk/studio/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  361. ksadk/studio/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  362. ksadk/studio/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  363. ksadk/studio/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  364. ksadk/studio/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  365. ksadk/studio/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  366. ksadk/studio/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  367. ksadk/studio/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  368. ksadk/studio/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  369. ksadk/studio/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  370. ksadk/studio/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  371. ksadk/studio/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  372. ksadk/studio/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  373. ksadk/studio/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  374. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  375. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  376. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  377. ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--BEOyPC3w.css +1 -0
  378. ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--CUYIXwgI.js +8 -0
  379. ksadk/studio/static/assets/MermaidBlock-DBFTztfQ-BTYKWEbD.js +44 -0
  380. ksadk/studio/static/assets/PrismRenderer-wiXRHURw.js +3 -0
  381. ksadk/studio/static/assets/abnfDiagram-VCTEODGH-CLETGjKq.js +1 -0
  382. ksadk/studio/static/assets/arc-Pry-7G1_.js +1 -0
  383. ksadk/studio/static/assets/architecture-7GRP2DOG-hXMiO_AU.js +1 -0
  384. ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-B5EQysk6.js +36 -0
  385. ksadk/studio/static/assets/array-BifhSqXX.js +1 -0
  386. ksadk/studio/static/assets/blockDiagram-I7D4REHJ-CFmPl1de.js +129 -0
  387. ksadk/studio/static/assets/c4Diagram-7LVT6UL2-BRrGu8qt.js +38 -0
  388. ksadk/studio/static/assets/channel-BqO-gtEw.js +1 -0
  389. ksadk/studio/static/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  390. ksadk/studio/static/assets/chunk-4HAMMTFA-D220vUtq.js +62 -0
  391. ksadk/studio/static/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  392. ksadk/studio/static/assets/chunk-75Z2AOVW-C8lLv_qc.js +2 -0
  393. ksadk/studio/static/assets/chunk-DU6HZSFF-C4DtVpCu.js +128 -0
  394. ksadk/studio/static/assets/chunk-F27PBJKO-Cpw14SNG.js +1 -0
  395. ksadk/studio/static/assets/chunk-FOHPRMQF-DHwB1DNv.js +161 -0
  396. ksadk/studio/static/assets/chunk-GMAD6QVW-DiQA-u2N.js +72 -0
  397. ksadk/studio/static/assets/chunk-GVQU2GXP-DUdNBUCi.js +1 -0
  398. ksadk/studio/static/assets/chunk-IMKFNOWR-BSlbjT_b.js +231 -0
  399. ksadk/studio/static/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  400. ksadk/studio/static/assets/chunk-L3NEJ4N5-Db8Ab22W.js +1 -0
  401. ksadk/studio/static/assets/chunk-OSK3NFVY-M2m6G3j4.js +10 -0
  402. ksadk/studio/static/assets/chunk-P2QGCYS3-DezaQxiK.js +1 -0
  403. ksadk/studio/static/assets/chunk-POPQ4Y6H-DOpufJ3t.js +1 -0
  404. ksadk/studio/static/assets/chunk-PWAF6VOD-CfLb1gSc.js +1 -0
  405. ksadk/studio/static/assets/chunk-SHT3W25Y-DAyIVp5H.js +168 -0
  406. ksadk/studio/static/assets/chunk-SVP7TREG-DulomOrS.js +88 -0
  407. ksadk/studio/static/assets/chunk-TICWLB2K-bHJYoflj.js +206 -0
  408. ksadk/studio/static/assets/chunk-XXDRQBXY-7PcdR2B1.js +1 -0
  409. ksadk/studio/static/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  410. ksadk/studio/static/assets/classDiagram-ZZMXUADV-D_bW8JjA.js +1 -0
  411. ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-D_bW8JjA.js +1 -0
  412. ksadk/studio/static/assets/cose-bilkent-JH36ORCC-snL88wkX.js +1 -0
  413. ksadk/studio/static/assets/cynefin-OW5HDTMX-Bd1YhRo1.js +1 -0
  414. ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-BBrIG_mI.js +62 -0
  415. ksadk/studio/static/assets/cytoscape.esm-CGd-uY3x.js +321 -0
  416. ksadk/studio/static/assets/dagre-GXQ25YYZ-DtF1nGdY.js +4 -0
  417. ksadk/studio/static/assets/dagre-PrKaheQc.js +1 -0
  418. ksadk/studio/static/assets/defaultLocale-BFoDCU3G.js +1 -0
  419. ksadk/studio/static/assets/diagram-S7CK7UJ4-0BZ98mya.js +30 -0
  420. ksadk/studio/static/assets/diagram-UQ7AKVKN-6mLKEo6L.js +41 -0
  421. ksadk/studio/static/assets/diagram-VSXAHHWV-CJBIaiZ2.js +3 -0
  422. ksadk/studio/static/assets/diagram-VX7I27RA-BohLEE1C.js +24 -0
  423. ksadk/studio/static/assets/diagram-Z3DM3KII-D8KIGonG.js +24 -0
  424. ksadk/studio/static/assets/dist-v5Q1xZ2K.js +1 -0
  425. ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-C99HU61t.js +1 -0
  426. ksadk/studio/static/assets/erDiagram-RLTQ6QDP-DLGry2Ap.js +99 -0
  427. ksadk/studio/static/assets/eventmodeling-NTZA5JFV-B1_5Ac8j.js +1 -0
  428. ksadk/studio/static/assets/flowDiagram-HODETNUW-DD5hmicn.js +1 -0
  429. ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BPJrVLSG.js +292 -0
  430. ksadk/studio/static/assets/gitGraph-4MIJSDKK-Cy_ZQBGi.js +1 -0
  431. ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-CZCUz4MT.js +106 -0
  432. ksadk/studio/static/assets/graphlib-DS17s2tU.js +1 -0
  433. ksadk/studio/static/assets/index-CeHL9ARV.css +2 -0
  434. ksadk/studio/static/assets/index-D9QEcVpL.js +320 -0
  435. ksadk/studio/static/assets/info-A6RAGUB7-DBzDQB_I.js +1 -0
  436. ksadk/studio/static/assets/infoDiagram-27XIBGKW-B-sq07Hi.js +2 -0
  437. ksadk/studio/static/assets/init-C-OQMol4.js +1 -0
  438. ksadk/studio/static/assets/ishikawaDiagram-5VMMS53U-CljI2wyf.js +70 -0
  439. ksadk/studio/static/assets/journeyDiagram-3NMN7TZE-D50Fo2sL.js +139 -0
  440. ksadk/studio/static/assets/kanban-definition-UXKFOSKX-DimfOTam.js +89 -0
  441. ksadk/studio/static/assets/katex-DhON-x74.js +257 -0
  442. ksadk/studio/static/assets/line-CX5BOOUP.js +1 -0
  443. ksadk/studio/static/assets/linear-BCxN9JLv.js +1 -0
  444. ksadk/studio/static/assets/mermaid-parser.core-BdCz8fkS.js +7 -0
  445. ksadk/studio/static/assets/mindmap-definition-YA3MSWOX-Bizzqy5R.js +96 -0
  446. ksadk/studio/static/assets/ordinal-BDEzSJ7C.js +1 -0
  447. ksadk/studio/static/assets/packet-AYTQ26CC-gPln-_kG.js +1 -0
  448. ksadk/studio/static/assets/path-fybaL0A-.js +1 -0
  449. ksadk/studio/static/assets/pegDiagram-XKGWAZYB-Dy3fB-gW.js +1 -0
  450. ksadk/studio/static/assets/pie-WAS4IAKB-qZdHMr7B.js +1 -0
  451. ksadk/studio/static/assets/pieDiagram-E7YTZNPT-B9mrFSDF.js +39 -0
  452. ksadk/studio/static/assets/quadrantDiagram-AXDQQJYC-NzUfCbMR.js +7 -0
  453. ksadk/studio/static/assets/radar-RG4KPBEZ-BZlnaea9.js +1 -0
  454. ksadk/studio/static/assets/railroad-74A4TZTK-Ce3__H9c.js +1 -0
  455. ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-DqQn7EzD.js +1 -0
  456. ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-B55kCA8F.js +1 -0
  457. ksadk/studio/static/assets/railroad-peg-WCYAUIDC-DfQnvkHd.js +1 -0
  458. ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-DnhMjZCk.js +1 -0
  459. ksadk/studio/static/assets/requirementDiagram-BXWQKSXE-BF3d103U.js +84 -0
  460. ksadk/studio/static/assets/rolldown-runtime-Dy4uBu1J-DK3Fl9T5.js +1 -0
  461. ksadk/studio/static/assets/rough.esm-Dy-Kn_BL.js +1 -0
  462. ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-Bo-JTwt0.js +40 -0
  463. ksadk/studio/static/assets/sequenceDiagram-WJ2MYXX4-Dh4wZtUm.js +162 -0
  464. ksadk/studio/static/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
  465. ksadk/studio/static/assets/src-SFn9St9H.js +1 -0
  466. ksadk/studio/static/assets/stateDiagram-D77RDMKH-DH774G6d.js +1 -0
  467. ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-DZvVWPBo.js +1 -0
  468. ksadk/studio/static/assets/swimlanes-42K2YHIH-Bl13OvTX.js +1 -0
  469. ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-BnFOTALJ.js +8 -0
  470. ksadk/studio/static/assets/timeline-definition-24CTP7MA-DxmSSjRB.js +120 -0
  471. ksadk/studio/static/assets/treeView-Q6P3EWNA-D5Nn9Swz.js +1 -0
  472. ksadk/studio/static/assets/treemap-WGGIJYW6-CgHgnQhE.js +1 -0
  473. ksadk/studio/static/assets/vennDiagram-4TSXK5OY-B9QEXcJq.js +34 -0
  474. ksadk/studio/static/assets/wardley-WFR3VGLG-DXrK2RRY.js +1 -0
  475. ksadk/studio/static/assets/wardleyDiagram-VM6X3IG4-Ba1AOWoe.js +78 -0
  476. ksadk/studio/static/assets/xychartDiagram-S5SC5T6Z-Cr5pt5Y-.js +7 -0
  477. ksadk/studio/static/index.html +2 -2
  478. ksadk/version.py +1 -1
  479. ksadk/server/static/assets/architecture-7GRP2DOG-Dk9nRQ6-.js +0 -1
  480. ksadk/server/static/assets/channel-s354Yo6o.js +0 -1
  481. ksadk/server/static/assets/chunk-2Q5K7J3B-CDpPpKR5.js +0 -1
  482. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Dd0nucl9.js +0 -1
  483. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Dd0nucl9.js +0 -1
  484. ksadk/server/static/assets/cynefin-OW5HDTMX-BBlT4uMf.js +0 -1
  485. ksadk/server/static/assets/eventmodeling-NTZA5JFV-Dr5okd8V.js +0 -1
  486. ksadk/server/static/assets/flowDiagram-A5DVABFB-VEO-cVcO.js +0 -1
  487. ksadk/server/static/assets/gitGraph-4MIJSDKK-CKiKY9Cf.js +0 -1
  488. ksadk/server/static/assets/index-B2k_urY8.js +0 -241
  489. ksadk/server/static/assets/index-ILPt6IWF.css +0 -2
  490. ksadk/server/static/assets/info-A6RAGUB7-ubA4Nm_p.js +0 -1
  491. ksadk/server/static/assets/packet-AYTQ26CC-C7R3NUlK.js +0 -1
  492. ksadk/server/static/assets/pie-WAS4IAKB-BIT6qjr3.js +0 -1
  493. ksadk/server/static/assets/radar-RG4KPBEZ-l5noef9X.js +0 -1
  494. ksadk/server/static/assets/railroad-74A4TZTK-Baea6ZvM.js +0 -1
  495. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-OKn8zZnU.js +0 -1
  496. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-DdKAKC4l.js +0 -1
  497. ksadk/server/static/assets/railroad-peg-WCYAUIDC-Bds8udlG.js +0 -1
  498. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-5b-8o2iS.js +0 -1
  499. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uf6WPRA4.js +0 -8
  500. ksadk/server/static/assets/treeView-Q6P3EWNA-CK5CSrSO.js +0 -1
  501. ksadk/server/static/assets/treemap-WGGIJYW6-Ch2BKgAM.js +0 -1
  502. ksadk/server/static/assets/wardley-WFR3VGLG-YW3Q0ml_.js +0 -1
  503. ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +0 -3
  504. ksadk/studio/static/assets/index-DXs1Eq4M.css +0 -1
  505. ksadk/studio/static/assets/index-DeDqwTsD.js +0 -283
  506. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/WHEEL +0 -0
  507. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/entry_points.txt +0 -0
  508. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/licenses/LICENSE +0 -0
  509. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,637 @@
1
+ """Host-owned platform resource admission for explicit signed connections.
2
+
3
+ The first supported slice verifies a sub-account with IAM and proves read access
4
+ to one exact knowledge-base binding. Browser declarations are comparisons only;
5
+ they never become authority by being well formed or present in a catalogue.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import hashlib
11
+ import json
12
+ import os
13
+ import re
14
+ from dataclasses import dataclass, field
15
+ from datetime import datetime, timedelta, timezone
16
+ from typing import Any, Literal
17
+ from urllib.parse import urlsplit, urlunsplit
18
+
19
+ import requests
20
+ from pydantic import Field, model_validator
21
+
22
+ from ksadk.knowledge_base.client import KnowledgeBaseClient
23
+ from ksadk.memory.adk.backends.sdk_ltm_backend import SdkLTMBackend
24
+ from ksadk.plugins.contracts import PluginContractModel
25
+ from ksadk.resource_runtime.contracts import Identifier, ResourceConfig, ResourceRef
26
+ from ksadk.resource_runtime.ipc import ResourceOperation
27
+ from ksadk.skills.service_client import SkillServiceClient
28
+ from ksadk.studio.errors import StudioError
29
+ from ksadk.studio.resource_connections import (
30
+ ResolvedResourceCredentials,
31
+ ResourceConnectionRepository,
32
+ )
33
+
34
+ _IAM_KRN = re.compile(r"^krn:ksc:iam::([^:]+):user/([^/]+)$")
35
+ _MAX_AUTHORITY_RESPONSE_BYTES = 1024 * 1024
36
+ _KSYUN_INTERNAL_HTTP_HOSTS = frozenset(
37
+ {
38
+ "iam.inner.api.ksyun.com",
39
+ "iam.internal.api.ksyun.com",
40
+ "aicp.inner.api.ksyun.com",
41
+ "aicp.internal.api.ksyun.com",
42
+ }
43
+ )
44
+
45
+
46
+ def _canonical_endpoint(
47
+ value: str,
48
+ *,
49
+ allow_loopback_http: bool,
50
+ allow_ksyun_internal_http: bool,
51
+ ) -> str:
52
+ if any(char.isspace() for char in value) or "\\" in value:
53
+ raise ValueError("Resource authority endpoint is invalid")
54
+ parsed = urlsplit(value)
55
+ parsed.port
56
+ if (
57
+ parsed.scheme not in {"http", "https"}
58
+ or not parsed.hostname
59
+ or parsed.username is not None
60
+ or parsed.password is not None
61
+ or parsed.query
62
+ or parsed.fragment
63
+ ):
64
+ raise ValueError("Resource authority endpoint must be an explicit HTTP service URL")
65
+ host = parsed.hostname.encode("idna").decode("ascii").lower()
66
+ if "%" in host:
67
+ raise ValueError("Resource authority endpoint hostname is invalid")
68
+ loopback_http = allow_loopback_http and host in {"127.0.0.1", "::1", "localhost"}
69
+ internal_http = (
70
+ parsed.scheme == "http"
71
+ and allow_ksyun_internal_http
72
+ and host in _KSYUN_INTERNAL_HTTP_HOSTS
73
+ )
74
+ if parsed.scheme != "https" and not (loopback_http or internal_http):
75
+ raise ValueError("Resource authority endpoints require HTTPS")
76
+ if internal_http and (parsed.port not in {None, 80} or parsed.path.rstrip("/")):
77
+ raise ValueError("Ksyun internal HTTP endpoints must use the service root")
78
+ if ":" in host:
79
+ host = f"[{host}]"
80
+ if parsed.port is not None and (parsed.scheme, parsed.port) not in {
81
+ ("http", 80),
82
+ ("https", 443),
83
+ }:
84
+ host += f":{parsed.port}"
85
+ return urlunsplit((parsed.scheme, host, parsed.path.rstrip("/"), "", ""))
86
+
87
+
88
+ class ResourceAuthorityPolicy(PluginContractModel):
89
+ """Trusted host configuration; it is never populated from a Studio request."""
90
+
91
+ iam_endpoint: str
92
+ iam_region: Identifier = "cn-beijing-6"
93
+ allowed_data_endpoints: tuple[str, ...] = Field(min_length=1, max_length=16)
94
+ allowed_regions: tuple[Identifier, ...] = Field(min_length=1, max_length=32)
95
+ timeout_seconds: float = Field(default=10.0, gt=0, le=30)
96
+ grant_ttl_seconds: int = Field(default=60, strict=True, ge=5, le=600)
97
+ allow_loopback_http_for_tests: bool = Field(default=False, strict=True)
98
+ allow_ksyun_internal_http: bool = Field(default=False, strict=True)
99
+
100
+ @model_validator(mode="after")
101
+ def trusted_targets(self) -> ResourceAuthorityPolicy:
102
+ iam = _canonical_endpoint(
103
+ self.iam_endpoint,
104
+ allow_loopback_http=self.allow_loopback_http_for_tests,
105
+ allow_ksyun_internal_http=self.allow_ksyun_internal_http,
106
+ )
107
+ data = tuple(
108
+ _canonical_endpoint(
109
+ endpoint,
110
+ allow_loopback_http=self.allow_loopback_http_for_tests,
111
+ allow_ksyun_internal_http=self.allow_ksyun_internal_http,
112
+ )
113
+ for endpoint in self.allowed_data_endpoints
114
+ )
115
+ if len(data) != len(set(data)) or len(self.allowed_regions) != len(
116
+ set(self.allowed_regions)
117
+ ):
118
+ raise ValueError("Resource authority targets must be unique")
119
+ object.__setattr__(self, "iam_endpoint", iam)
120
+ object.__setattr__(self, "allowed_data_endpoints", data)
121
+ return self
122
+
123
+
124
+ class VerifiedResourceAuthority(PluginContractModel):
125
+ """Short-lived, credential-free evidence produced only by the trusted host."""
126
+
127
+ schema_version: Literal[1] = 1
128
+ connection_ref: Identifier
129
+ connection_revision: int = Field(strict=True, ge=1)
130
+ tenant_ref: Identifier
131
+ resource_principal_ref: Identifier
132
+ resource: ResourceRef
133
+ allowed_operations: tuple[ResourceOperation, ...] = Field(min_length=1)
134
+ issuer_endpoint: str
135
+ issuer_region: Identifier
136
+ data_endpoint: str
137
+ observed_at: datetime
138
+ expires_at: datetime
139
+ request_id: str = Field(default="", max_length=256)
140
+
141
+ @property
142
+ def digest(self) -> str:
143
+ payload = self.model_dump(by_alias=True, mode="json")
144
+ raw = json.dumps(
145
+ payload, ensure_ascii=False, sort_keys=True, separators=(",", ":")
146
+ ).encode()
147
+ return "sha256:" + hashlib.sha256(raw).hexdigest()
148
+
149
+
150
+ @dataclass(frozen=True)
151
+ class AdmittedResourceAccess:
152
+ """Runtime-only authority proof paired with the exact verified credentials."""
153
+
154
+ authority: VerifiedResourceAuthority
155
+ credentials: ResolvedResourceCredentials = field(repr=False)
156
+
157
+
158
+ @dataclass(frozen=True)
159
+ class _VerifiedIamIdentity:
160
+ tenant_ref: str
161
+ principal_ref: str
162
+
163
+
164
+ class _HardenedSdkTransport:
165
+ """Use the SDK's request serialization/signing with a closed HTTP transport."""
166
+
167
+ def __init__(self, endpoint: str, *, timeout: float):
168
+ self.endpoint = endpoint
169
+ self.timeout = timeout
170
+
171
+ def send_request(self, request: Any):
172
+ from ksyun.common.http.request import ResponseInternal # type: ignore[import-untyped]
173
+
174
+ url = self.endpoint
175
+ path = str(request.uri or "")
176
+ if path not in {"", "/"}:
177
+ url += "/" + path.lstrip("/")
178
+ if request.uri_params:
179
+ url += "?" + request.uri_params
180
+ with requests.Session() as session:
181
+ session.trust_env = False
182
+ with session.request(
183
+ method=request.method,
184
+ url=url,
185
+ data=request.data,
186
+ headers=dict(request.header),
187
+ auth=request.auth,
188
+ timeout=self.timeout,
189
+ verify=True,
190
+ allow_redirects=False,
191
+ stream=True,
192
+ ) as response:
193
+ if 300 <= response.status_code < 400:
194
+ raise RuntimeError("RESOURCE_AUTHORITY_REDIRECT_REFUSED")
195
+ declared_length = response.headers.get("Content-Length")
196
+ if declared_length and int(declared_length) > _MAX_AUTHORITY_RESPONSE_BYTES:
197
+ raise RuntimeError("RESOURCE_AUTHORITY_RESPONSE_TOO_LARGE")
198
+ chunks = []
199
+ size = 0
200
+ for chunk in response.iter_content(chunk_size=65536):
201
+ size += len(chunk)
202
+ if size > _MAX_AUTHORITY_RESPONSE_BYTES:
203
+ raise RuntimeError("RESOURCE_AUTHORITY_RESPONSE_TOO_LARGE")
204
+ chunks.append(chunk)
205
+ content = b"".join(chunks)
206
+ return ResponseInternal(
207
+ status=response.status_code,
208
+ header=dict(response.headers),
209
+ data=content.decode("utf-8", errors="strict"),
210
+ )
211
+
212
+
213
+ def _response_object(value: Any) -> dict[str, Any]:
214
+ if isinstance(value, str):
215
+ if len(value.encode()) > _MAX_AUTHORITY_RESPONSE_BYTES:
216
+ raise ValueError("oversized response")
217
+ value = json.loads(value)
218
+ if not isinstance(value, dict):
219
+ raise ValueError("invalid authority response")
220
+ metadata = value.get("ResponseMetadata", {})
221
+ if not isinstance(metadata, dict) or value.get("Error") or metadata.get("Error"):
222
+ raise ValueError("authority rejected the request")
223
+ code = value.get("Code")
224
+ if "Code" in value and not (
225
+ (type(code) is int and code in {0, 200})
226
+ or (type(code) is str and code in {"0", "200"})
227
+ ):
228
+ raise ValueError("authority rejected the request")
229
+ return value
230
+
231
+
232
+ def _credential_values(credentials: ResolvedResourceCredentials) -> tuple[str, str, str, str]:
233
+ def reveal(value: Any) -> str:
234
+ return value.get_secret_value() if value is not None else ""
235
+
236
+ return (
237
+ reveal(credentials.access_key),
238
+ reveal(credentials.secret_key),
239
+ reveal(credentials.session_token),
240
+ reveal(credentials.token),
241
+ )
242
+
243
+
244
+ class SignedKnowledgeResourceAuthority:
245
+ """Fail-closed admission for signed, read-oriented platform resources."""
246
+
247
+ def __init__(
248
+ self,
249
+ connections: ResourceConnectionRepository,
250
+ policy: ResourceAuthorityPolicy,
251
+ ) -> None:
252
+ self.connections = connections
253
+ self.policy = policy
254
+
255
+ def admit(
256
+ self,
257
+ config: ResourceConfig,
258
+ *,
259
+ expected_connection_revision: int | None = None,
260
+ ) -> VerifiedResourceAuthority:
261
+ return self.admit_runtime(
262
+ config,
263
+ expected_connection_revision=expected_connection_revision,
264
+ ).authority
265
+
266
+ def resolve_signed_identity(self, access_key: str, secret_key: str) -> tuple[str, str]:
267
+ """Resolve the host credential owner for an explicit connection declaration."""
268
+
269
+ identity = self._verify_identity(access_key, secret_key)
270
+ return identity.tenant_ref, identity.principal_ref
271
+
272
+ def admit_runtime(
273
+ self,
274
+ config: ResourceConfig,
275
+ *,
276
+ expected_connection_revision: int | None = None,
277
+ ) -> AdmittedResourceAccess:
278
+ """Return only credentials proven inside this exact admission transaction."""
279
+
280
+ resource = config.binding.resource
281
+ field = "spec.bindings.plugins.config.binding"
282
+ before = self.connections.get(config.binding.connection_ref)
283
+ if (
284
+ expected_connection_revision is not None
285
+ and before.revision != expected_connection_revision
286
+ ):
287
+ raise StudioError(
288
+ "RESOURCE_CONNECTION_CHANGED", "资源连接已变更,请刷新后重试", status_code=409
289
+ )
290
+ target = before.target
291
+ if target.auth_mode != "signed":
292
+ raise StudioError(
293
+ "RESOURCE_AUTHORITY_UNSUPPORTED",
294
+ "当前可信准入首片仅支持签名子账号连接",
295
+ status_code=422,
296
+ field=field + ".connectionRef",
297
+ )
298
+ if target.endpoint not in self.policy.allowed_data_endpoints or (
299
+ resource.region not in self.policy.allowed_regions
300
+ ):
301
+ raise StudioError(
302
+ "RESOURCE_AUTHORITY_TARGET_FORBIDDEN",
303
+ "资源数据面地址或区域未被当前宿主批准",
304
+ status_code=403,
305
+ field=field + ".resource",
306
+ )
307
+
308
+ credentials = self.connections.resolve_credentials(target)
309
+ values = _credential_values(credentials)
310
+ if not values[0] or not values[1] or values[2] or values[3]:
311
+ raise StudioError(
312
+ "RESOURCE_AUTHORITY_UNSUPPORTED",
313
+ "当前可信准入首片需要独立的 AK/SK 签名凭证",
314
+ status_code=422,
315
+ )
316
+ identity = self._verify_identity(values[0], values[1])
317
+ if (
318
+ identity.tenant_ref != target.tenant_ref
319
+ or identity.principal_ref != target.principal_ref
320
+ ):
321
+ raise StudioError(
322
+ "RESOURCE_IDENTITY_MISMATCH",
323
+ "连接声明的租户或主体与当前签名凭证不一致",
324
+ status_code=403,
325
+ field=field + ".connectionRef",
326
+ )
327
+ if resource.kind == "knowledge-base":
328
+ request_id = self._prove_knowledge_read(
329
+ config, target.endpoint, values[0], values[1]
330
+ )
331
+ elif resource.kind == "memory-instance":
332
+ request_id = self._prove_memory_read(
333
+ config, target.endpoint, values[0], values[1]
334
+ )
335
+ else:
336
+ request_id = self._prove_skill_read(
337
+ config, target.endpoint, values[0], values[1]
338
+ )
339
+
340
+ after = self.connections.get(config.binding.connection_ref)
341
+ after_values = _credential_values(self.connections.resolve_credentials(after.target))
342
+ if after != before or after_values != values:
343
+ raise StudioError(
344
+ "RESOURCE_CONNECTION_CHANGED", "资源连接或凭证在准入期间发生变更", status_code=409
345
+ )
346
+ now = datetime.now(timezone.utc)
347
+ return AdmittedResourceAccess(
348
+ authority=VerifiedResourceAuthority(
349
+ connection_ref=target.connection_ref,
350
+ connection_revision=before.revision,
351
+ tenant_ref=identity.tenant_ref,
352
+ resource_principal_ref=identity.principal_ref,
353
+ resource=resource,
354
+ allowed_operations=resource_allowed_operations(config),
355
+ issuer_endpoint=self.policy.iam_endpoint,
356
+ issuer_region=self.policy.iam_region,
357
+ data_endpoint=target.endpoint,
358
+ observed_at=now,
359
+ expires_at=now + timedelta(seconds=self.policy.grant_ttl_seconds),
360
+ request_id=request_id,
361
+ ),
362
+ credentials=credentials,
363
+ )
364
+ def _verify_identity(self, access_key: str, secret_key: str) -> _VerifiedIamIdentity:
365
+ try:
366
+ from ksyun.client.iam.v20151101.client import ( # type: ignore[import-untyped]
367
+ IamClient,
368
+ )
369
+ from ksyun.client.iam.v20151101.models import ( # type: ignore[import-untyped]
370
+ GetUserRequest,
371
+ ListAllUserAccessKeysRequest,
372
+ )
373
+ from ksyun.common.credential import Credential # type: ignore[import-untyped]
374
+ from ksyun.common.profile.client_profile import ( # type: ignore[import-untyped]
375
+ ClientProfile,
376
+ )
377
+ from ksyun.common.profile.http_profile import ( # type: ignore[import-untyped]
378
+ HttpProfile,
379
+ )
380
+
381
+ endpoint = urlsplit(self.policy.iam_endpoint)
382
+ profile = ClientProfile()
383
+ profile.httpProfile = HttpProfile(
384
+ protocol=endpoint.scheme,
385
+ endpoint=endpoint.netloc,
386
+ # The hardened transport owns the configured base path.
387
+ path="/",
388
+ reqMethod="POST",
389
+ reqTimeout=self.policy.timeout_seconds,
390
+ )
391
+ client = IamClient(
392
+ Credential(access_key, secret_key), self.policy.iam_region, profile
393
+ )
394
+ client.request = _HardenedSdkTransport(
395
+ self.policy.iam_endpoint, timeout=self.policy.timeout_seconds
396
+ )
397
+ listed = _response_object(client.ListAllUserAccessKeys(ListAllUserAccessKeysRequest()))
398
+ identity = self._identity_from_iam_listing(listed, access_key)
399
+ request = GetUserRequest()
400
+ request.UserName = identity
401
+ user_response = _response_object(client.GetUser(request))
402
+ return self._identity_from_iam_user(user_response, identity)
403
+ except StudioError:
404
+ raise
405
+ except Exception as error:
406
+ raise StudioError(
407
+ "RESOURCE_IDENTITY_UNVERIFIED",
408
+ "无法使用当前签名凭证验证平台子账号身份",
409
+ status_code=403,
410
+ ) from error
411
+
412
+ @staticmethod
413
+ def _identity_from_iam_listing(response: dict[str, Any], access_key: str) -> str:
414
+ truncated = response.get("IsTruncated", False)
415
+ if type(truncated) is not bool or truncated or response.get("NextMarker"):
416
+ raise ValueError("incomplete access-key listing")
417
+ has_primary = "AccessKeyList" in response
418
+ has_alias = "AccessKeys" in response
419
+ if has_primary == has_alias:
420
+ raise ValueError("ambiguous access-key listing")
421
+ entries = response["AccessKeyList" if has_primary else "AccessKeys"]
422
+ if not isinstance(entries, list):
423
+ raise ValueError("invalid access-key listing")
424
+ matches = []
425
+ for entry in entries:
426
+ if not isinstance(entry, dict):
427
+ raise ValueError("invalid access-key entry")
428
+ has_key = "AccessKey" in entry
429
+ has_alias_key = "AccessKeyId" in entry
430
+ if has_key == has_alias_key:
431
+ raise ValueError("ambiguous access-key entry")
432
+ candidate = entry["AccessKey" if has_key else "AccessKeyId"]
433
+ user_name = entry.get("UserName")
434
+ if (
435
+ not isinstance(candidate, str)
436
+ or not candidate
437
+ or candidate != candidate.strip()
438
+ or not isinstance(user_name, str)
439
+ or not user_name
440
+ or user_name != user_name.strip()
441
+ ):
442
+ raise ValueError("invalid access-key identity")
443
+ if candidate == access_key:
444
+ matches.append(user_name)
445
+ if len(matches) != 1:
446
+ raise ValueError("signed access key has no unique sub-account")
447
+ return matches[0]
448
+
449
+ @staticmethod
450
+ def _identity_from_iam_user(
451
+ response: dict[str, Any], expected_user_name: str
452
+ ) -> _VerifiedIamIdentity:
453
+ result = response.get("GetUserResult")
454
+ user = result.get("User") if isinstance(result, dict) else None
455
+ if not isinstance(user, dict):
456
+ raise ValueError("invalid IAM user response")
457
+ user_id = user.get("UserId")
458
+ user_name = user.get("UserName", expected_user_name)
459
+ krn = user.get("Krn")
460
+ if not all(
461
+ isinstance(value, str) and value and value == value.strip()
462
+ for value in (user_id, user_name, krn)
463
+ ):
464
+ raise ValueError("incomplete IAM user identity")
465
+ match = _IAM_KRN.fullmatch(krn)
466
+ if not match or user_name != expected_user_name or match.group(2) != user_name:
467
+ raise ValueError("IAM user identity is inconsistent")
468
+ return _VerifiedIamIdentity(tenant_ref=match.group(1), principal_ref=user_id)
469
+
470
+ def _prove_knowledge_read(
471
+ self,
472
+ config: ResourceConfig,
473
+ data_endpoint: str,
474
+ access_key: str,
475
+ secret_key: str,
476
+ ) -> str:
477
+ endpoint = urlsplit(data_endpoint)
478
+ client = KnowledgeBaseClient(
479
+ dataset_id=config.binding.resource.id,
480
+ region=config.binding.resource.region,
481
+ endpoint=endpoint.netloc,
482
+ scheme=endpoint.scheme,
483
+ access_key=access_key,
484
+ secret_key=secret_key,
485
+ top_k=1,
486
+ )
487
+ try:
488
+ upstream = client._get_client()
489
+ upstream.request = _HardenedSdkTransport(
490
+ data_endpoint, timeout=self.policy.timeout_seconds
491
+ )
492
+ client.search("ksadk-resource-authority-probe", top_k=1)
493
+ if client.last_http_status != 200 or client.last_error:
494
+ raise ValueError("knowledge access was not proven")
495
+ return client.last_request_id
496
+ except Exception as error:
497
+ raise StudioError(
498
+ "RESOURCE_OPERATION_UNVERIFIED",
499
+ "当前签名主体未通过指定知识库的只读检索校验",
500
+ status_code=403,
501
+ ) from error
502
+
503
+ def _prove_memory_read(
504
+ self,
505
+ config: ResourceConfig,
506
+ data_endpoint: str,
507
+ access_key: str,
508
+ secret_key: str,
509
+ ) -> str:
510
+ endpoint = urlsplit(data_endpoint)
511
+ backend = SdkLTMBackend(
512
+ index="resource-authority",
513
+ memory_collection_id=config.binding.resource.id,
514
+ namespace=config.binding.resource.id,
515
+ agent_id="resource-authority",
516
+ region=config.binding.resource.region,
517
+ endpoint=endpoint.netloc,
518
+ scheme=endpoint.scheme,
519
+ access_key=access_key,
520
+ secret_key=secret_key,
521
+ )
522
+ try:
523
+ upstream = backend._get_client()
524
+ upstream.request = _HardenedSdkTransport(
525
+ data_endpoint, timeout=self.policy.timeout_seconds
526
+ )
527
+ backend.search_memory(
528
+ "ksadk-resource-authority",
529
+ "ksadk-resource-authority-probe",
530
+ top_k=1,
531
+ )
532
+ if backend.last_http_status != 200 or backend.last_error:
533
+ raise ValueError("memory access was not proven")
534
+ return "memory-read-proven"
535
+ except Exception as error:
536
+ raise StudioError(
537
+ "RESOURCE_OPERATION_UNVERIFIED",
538
+ "当前签名主体未通过指定记忆库的只读召回校验",
539
+ status_code=403,
540
+ ) from error
541
+
542
+ def _prove_skill_read(
543
+ self,
544
+ config: ResourceConfig,
545
+ data_endpoint: str,
546
+ access_key: str,
547
+ secret_key: str,
548
+ ) -> str:
549
+ client = SkillServiceClient(
550
+ base_url=data_endpoint,
551
+ access_key=access_key,
552
+ secret_key=secret_key,
553
+ region=config.binding.resource.region,
554
+ allow_env_fallback=False,
555
+ timeout=self.policy.timeout_seconds,
556
+ )
557
+ try:
558
+ listing = client.list_skills_by_space_id(
559
+ config.binding.resource.id, max_pages=1
560
+ )
561
+ if listing.space_id != config.binding.resource.id:
562
+ raise ValueError("skill space access was not proven")
563
+ return "skill-space-read-proven"
564
+ except Exception as error:
565
+ raise StudioError(
566
+ "RESOURCE_OPERATION_UNVERIFIED",
567
+ "当前签名主体未通过指定 Skill Space 的只读目录校验",
568
+ status_code=403,
569
+ ) from error
570
+ finally:
571
+ client.close()
572
+
573
+
574
+ def resource_allowed_operations(config: ResourceConfig) -> tuple[ResourceOperation, ...]:
575
+ """Return the maximum host capability set for one admitted resource kind.
576
+
577
+ Activation policy narrows this set before issuing leases. Memory writes are
578
+ still fail-closed unless that activation also owns a write authorizer.
579
+ """
580
+
581
+ kind = config.binding.resource.kind
582
+ if kind == "knowledge-base":
583
+ return ("search_knowledge_base",)
584
+ if kind == "memory-instance":
585
+ return ("load_memory", "save_memory", "memory_status")
586
+ return ("list_skills", "search_skills", "load_skill", "read_skill_resource")
587
+
588
+
589
+ def resource_authority_policy_from_environment() -> ResourceAuthorityPolicy | None:
590
+ """Build a trusted policy from operator-owned local Studio environment."""
591
+
592
+ access_key = os.environ.get("KSYUN_ACCESS_KEY", "").strip()
593
+ secret_key = os.environ.get("KSYUN_SECRET_KEY", "").strip()
594
+ endpoint = os.environ.get("AGENTENGINE_SERVER_URL", "").strip()
595
+ if not access_key or not secret_key or not endpoint:
596
+ return None
597
+ logical_region = (
598
+ os.environ.get("AGENTENGINE_REGION")
599
+ or os.environ.get("KSYUN_REGION")
600
+ or "cn-beijing-6"
601
+ ).strip()
602
+ region = (
603
+ os.environ.get("AGENTENGINE_PRE_CONTROL_REGION", "cn-beijing-6").strip()
604
+ if logical_region.lower() == "pre-online"
605
+ else logical_region
606
+ )
607
+ iam_endpoint = os.environ.get("KSADK_RESOURCE_IAM_ENDPOINT", "").strip()
608
+ if not iam_endpoint:
609
+ try:
610
+ endpoint_host = (
611
+ (urlsplit(endpoint).hostname or "")
612
+ .encode("idna")
613
+ .decode("ascii")
614
+ .lower()
615
+ .rstrip(".")
616
+ )
617
+ except (UnicodeError, ValueError):
618
+ endpoint_host = ""
619
+ endpoint_labels = endpoint_host.split(".")
620
+ uses_ksyun_internal_dns = endpoint_labels[-4:] == [
621
+ "inner",
622
+ "api",
623
+ "ksyun",
624
+ "com",
625
+ ]
626
+ iam_endpoint = (
627
+ "http://iam.inner.api.ksyun.com"
628
+ if uses_ksyun_internal_dns
629
+ else "https://iam.api.ksyun.com"
630
+ )
631
+ return ResourceAuthorityPolicy(
632
+ iam_endpoint=iam_endpoint,
633
+ iam_region=region,
634
+ allowed_data_endpoints=(endpoint,),
635
+ allowed_regions=(region,),
636
+ allow_ksyun_internal_http=True,
637
+ )