agentengine-sdk-python 0.8.2__py3-none-any.whl → 0.8.3__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 (250) hide show
  1. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.3.dist-info}/METADATA +18 -25
  2. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.3.dist-info}/RECORD +224 -169
  3. ksadk/_build_provenance.json +1 -0
  4. ksadk/agui/_agent_helpers.py +4 -0
  5. ksadk/api/client.py +3 -0
  6. ksadk/builders/managed_runtime_builder.py +3 -0
  7. ksadk/cli/__init__.py +6 -0
  8. ksadk/cli/cmd_plugin.py +657 -0
  9. ksadk/codex/runtime.py +50 -8
  10. ksadk/configs/env_registry.py +31 -3
  11. ksadk/configs/settings.py +9 -0
  12. ksadk/context_engine/contributors.py +73 -8
  13. ksadk/conversations/__init__.py +19 -0
  14. ksadk/conversations/context.py +104 -24
  15. ksadk/conversations/contracts.py +266 -0
  16. ksadk/conversations/message_projection.py +19 -1
  17. ksadk/conversations/projector.py +616 -0
  18. ksadk/conversations/reducer.py +98 -0
  19. ksadk/events/_v1_compat/projection.py +2 -0
  20. ksadk/events/adapters/codex.py +190 -0
  21. ksadk/harness/__init__.py +45 -35
  22. ksadk/harness/runtime.py +60 -1
  23. ksadk/kernel/contract_fingerprints.py +5 -4
  24. ksadk/kernel/contracts.py +8 -0
  25. ksadk/kernel/control.py +1 -0
  26. ksadk/kernel/ingress.py +21 -0
  27. ksadk/kernel/memory_store.py +1 -0
  28. ksadk/kernel/postgres_store.py +1 -0
  29. ksadk/kernel/sqlite_store.py +1 -0
  30. ksadk/kernel/worker.py +11 -0
  31. ksadk/memory/providers/local_sqlite.py +7 -0
  32. ksadk/plugins/__init__.py +167 -0
  33. ksadk/plugins/bridges/__init__.py +45 -0
  34. ksadk/plugins/bridges/codex.py +552 -0
  35. ksadk/plugins/bridges/dsh.py +1116 -0
  36. ksadk/plugins/builtins.py +747 -0
  37. ksadk/plugins/bundle.py +246 -0
  38. ksadk/plugins/bundle_security.py +167 -0
  39. ksadk/plugins/composition.py +529 -0
  40. ksadk/plugins/context_contributor.py +437 -0
  41. ksadk/plugins/contracts.py +451 -0
  42. ksadk/plugins/dsh_toolchain.py +935 -0
  43. ksadk/plugins/ecosystem_bridge.py +1105 -0
  44. ksadk/plugins/ecosystem_probe.py +191 -0
  45. ksadk/plugins/host.py +724 -0
  46. ksadk/plugins/providers/__init__.py +85 -0
  47. ksadk/plugins/providers/bundles/ksadk-codex/cordis.patch.yml +3 -0
  48. ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +18 -0
  49. ksadk/plugins/providers/bundles/ksadk-codex/package.json +19 -0
  50. ksadk/plugins/providers/bundles/ksadk-harness/cordis.patch.yml +3 -0
  51. ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +19 -0
  52. ksadk/plugins/providers/bundles/ksadk-harness/package.json +19 -0
  53. ksadk/plugins/providers/codex.py +722 -0
  54. ksadk/plugins/providers/codex_dsh.py +83 -0
  55. ksadk/plugins/providers/dsh.py +951 -0
  56. ksadk/plugins/providers/dsh_descriptor_host.py +226 -0
  57. ksadk/plugins/providers/harness.py +627 -0
  58. ksadk/plugins/providers/harness_dsh.py +91 -0
  59. ksadk/plugins/providers/legacy.py +215 -0
  60. ksadk/plugins/providers/legacy_catalog.py +100 -0
  61. ksadk/plugins/providers/shipped_dsh.py +370 -0
  62. ksadk/plugins/resolver.py +331 -0
  63. ksadk/plugins/subagent_providers/__init__.py +12 -0
  64. ksadk/plugins/subagent_providers/codex.py +443 -0
  65. ksadk/plugins/subagents.py +333 -0
  66. ksadk/runtime/_runner_adapter/stream_mapping.py +51 -42
  67. ksadk/runtime/adapter.py +1 -0
  68. ksadk/runtime/factory.py +76 -2
  69. ksadk/runtime/framework_adapters.py +18 -0
  70. ksadk/runtime/runner_adapter.py +5 -0
  71. ksadk/sandbox/__init__.py +2 -1
  72. ksadk/sandbox/factory.py +72 -0
  73. ksadk/scheduler/__init__.py +18 -0
  74. ksadk/scheduler/calendar.py +102 -0
  75. ksadk/scheduler/contracts.py +254 -0
  76. ksadk/scheduler/dispatcher.py +129 -0
  77. ksadk/scheduler/engine.py +416 -0
  78. ksadk/scheduler/sqlite_store.py +563 -0
  79. ksadk/server/static/assets/{ArtifactsPanel-DSU1sWD_.js → ArtifactsPanel-10GPXIJ6.js} +1 -1
  80. ksadk/server/static/assets/{CodeBlock-DOH6MVcn.js → CodeBlock-BXk1l-G1.js} +1 -1
  81. ksadk/server/static/assets/{MathMessageMarkdown-BL8my1R2.js → MathMessageMarkdown-D9uB55Oh.js} +1 -1
  82. ksadk/server/static/assets/{MermaidBlock-Dz4IP-Tx.js → MermaidBlock--OEYoXIJ.js} +6 -6
  83. ksadk/server/static/assets/{NativeTerminalPanel-DUrK0JpZ.js → NativeTerminalPanel-DrEe1syq.js} +1 -1
  84. ksadk/server/static/assets/{abnfDiagram-VCTEODGH-g20pFzNV.js → abnfDiagram-VCTEODGH-eeTFJLvo.js} +1 -1
  85. ksadk/server/static/assets/{arc-C4FzinUA.js → arc-S3ZNbIAd.js} +1 -1
  86. ksadk/server/static/assets/architecture-7GRP2DOG-Dk9nRQ6-.js +1 -0
  87. ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-DpIqL5h4.js → architectureDiagram-5GKGNRK7-CRjgEJDX.js} +1 -1
  88. ksadk/server/static/assets/{blockDiagram-NRAW4CY4-BjkljTNz.js → blockDiagram-NRAW4CY4-C7bsBoNH.js} +1 -1
  89. ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-Dk_ieq2X.js → c4Diagram-UCG6FXSJ-BX3c33Ob.js} +1 -1
  90. ksadk/server/static/assets/channel-s354Yo6o.js +1 -0
  91. ksadk/server/static/assets/chunk-2Q5K7J3B-CDpPpKR5.js +1 -0
  92. ksadk/server/static/assets/{chunk-5VM5RSS4-BVHAchFb.js → chunk-5VM5RSS4-bZ7ws-8m.js} +1 -1
  93. ksadk/server/static/assets/{chunk-F27PBJKO-C-ipQzuS.js → chunk-F27PBJKO-D2r0pvhY.js} +1 -1
  94. ksadk/server/static/assets/{chunk-G27WJ6UU-C2EyJbIK.js → chunk-G27WJ6UU-CZwF3oUP.js} +1 -1
  95. ksadk/server/static/assets/{chunk-JWPE2WC7-vYvVJb_M.js → chunk-JWPE2WC7-DigFYCML.js} +1 -1
  96. ksadk/server/static/assets/{chunk-LCL6LL3I-BcI6ysPT.js → chunk-LCL6LL3I-CnorGV5q.js} +1 -1
  97. ksadk/server/static/assets/{chunk-POPQ4Y6H-C030x_Z1.js → chunk-POPQ4Y6H-CexntQA-.js} +1 -1
  98. ksadk/server/static/assets/{chunk-RHFEMEQ7-yyGpsz4n.js → chunk-RHFEMEQ7-CHTC7UxA.js} +1 -1
  99. ksadk/server/static/assets/{chunk-SVP7TREG-BLTlmMU7.js → chunk-SVP7TREG-BC1EWt_-.js} +1 -1
  100. ksadk/server/static/assets/{chunk-XXDRQBXY-C_32ArgP.js → chunk-XXDRQBXY-BTG24xN0.js} +1 -1
  101. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Dd0nucl9.js +1 -0
  102. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Dd0nucl9.js +1 -0
  103. ksadk/server/static/assets/{cose-bilkent-JH36ORCC-9YQYwdl0.js → cose-bilkent-JH36ORCC-CkonRdAS.js} +1 -1
  104. ksadk/server/static/assets/cynefin-OW5HDTMX-BBlT4uMf.js +1 -0
  105. ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-ErLF5N13.js → cynefinDiagram-5FMLGOSQ-DEOCBe15.js} +1 -1
  106. ksadk/server/static/assets/{dagre-3AP2YEHR-DFiQF-6f.js → dagre-3AP2YEHR-DBThPuLa.js} +1 -1
  107. ksadk/server/static/assets/{dagre-BuhGnRI1.js → dagre-ClTPrTht.js} +1 -1
  108. ksadk/server/static/assets/{diagram-S7CK7UJ4-Bt1v8-GC.js → diagram-S7CK7UJ4-DsZHrnpJ.js} +1 -1
  109. ksadk/server/static/assets/{diagram-UQ7AKVKN-DSCxJdBK.js → diagram-UQ7AKVKN-BJR4nhVr.js} +1 -1
  110. ksadk/server/static/assets/{diagram-VSXAHHWV-DHfYwp_9.js → diagram-VSXAHHWV-xzcERX0a.js} +1 -1
  111. ksadk/server/static/assets/{diagram-VX7I27RA-DdzD-4Le.js → diagram-VX7I27RA-tn2xM1xu.js} +1 -1
  112. ksadk/server/static/assets/{diagram-Z3DM3KII-Du-nAJ9F.js → diagram-Z3DM3KII-BZPGBkw5.js} +1 -1
  113. ksadk/server/static/assets/{dist-ClxGviKw.js → dist-4zN1_tq5.js} +1 -1
  114. ksadk/server/static/assets/{dist-BE7bu-DL.js → dist-8VWI-2bZ.js} +1 -1
  115. ksadk/server/static/assets/{dist-BX8z72IC.js → dist-B-46q3Hk.js} +1 -1
  116. ksadk/server/static/assets/{dist-BjU6y-A2.js → dist-B0gdk4rl.js} +1 -1
  117. ksadk/server/static/assets/{dist-C_wsv-Qd.js → dist-B1oWRmrH.js} +1 -1
  118. ksadk/server/static/assets/{dist-ngtN0DJB.js → dist-BI1qQH4n.js} +1 -1
  119. ksadk/server/static/assets/{dist-dydu68Fl.js → dist-BJLUwH6W.js} +1 -1
  120. ksadk/server/static/assets/{dist-Dq9gLD7L.js → dist-Bbwqa8TG.js} +1 -1
  121. ksadk/server/static/assets/{dist-CttYUqzS.js → dist-Btyo4vX4.js} +1 -1
  122. ksadk/server/static/assets/{dist-CXYYBw3_.js → dist-C71CsujO.js} +1 -1
  123. ksadk/server/static/assets/{dist-dDdADKFA.js → dist-CXpH_Rdd.js} +1 -1
  124. ksadk/server/static/assets/{dist-CSh_DE14.js → dist-Cq4OL6nO.js} +1 -1
  125. ksadk/server/static/assets/{dist-8hqcx0sU.js → dist-D1V3f1B4.js} +1 -1
  126. ksadk/server/static/assets/{dist-BVDffZ0U.js → dist-DJmCPRVB.js} +1 -1
  127. ksadk/server/static/assets/{dist-DnfXs8Vn.js → dist-DQAB0qn_.js} +1 -1
  128. ksadk/server/static/assets/{dist-DNp6rLRA.js → dist-DUwKa_l6.js} +1 -1
  129. ksadk/server/static/assets/{dist-B7seoj3d.js → dist-DdRBIceA.js} +1 -1
  130. ksadk/server/static/assets/{dist-BytlxIDT.js → dist-DfGFrb0v.js} +1 -1
  131. ksadk/server/static/assets/{dist-Bf2M8m3N.js → dist-DjhwGUgZ.js} +1 -1
  132. ksadk/server/static/assets/{dist-W-TIVntx.js → dist-DyqV4fL4.js} +1 -1
  133. ksadk/server/static/assets/{dist-DUX-id_F.js → dist-M67Hwu0n.js} +1 -1
  134. ksadk/server/static/assets/{dist-DmldrHd_.js → dist-u8tVH5Ak.js} +1 -1
  135. ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-Da9C9NO1.js → ebnfDiagram-PWID7BFC-DVfMsLge.js} +1 -1
  136. ksadk/server/static/assets/{erDiagram-SSCWMZ5O-EAGqqR79.js → erDiagram-SSCWMZ5O-CWEZSYaw.js} +1 -1
  137. ksadk/server/static/assets/eventmodeling-NTZA5JFV-Dr5okd8V.js +1 -0
  138. ksadk/server/static/assets/flowDiagram-A5DVABFB-VEO-cVcO.js +1 -0
  139. ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-DqJsKb59.js → ganttDiagram-EL5Y4UJY-TWIxoyYL.js} +1 -1
  140. ksadk/server/static/assets/gitGraph-4MIJSDKK-CKiKY9Cf.js +1 -0
  141. ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-B6g4dtDi.js → gitGraphDiagram-WWUBYQGX-DDh2hd2S.js} +1 -1
  142. ksadk/server/static/assets/index-B2k_urY8.js +241 -0
  143. ksadk/server/static/assets/index-ILPt6IWF.css +2 -0
  144. ksadk/server/static/assets/info-A6RAGUB7-ubA4Nm_p.js +1 -0
  145. ksadk/server/static/assets/{infoDiagram-RXCK75RN-Djm_nbd5.js → infoDiagram-RXCK75RN-CgoyWiDR.js} +1 -1
  146. ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-DWya9SG2.js → ishikawaDiagram-5VMMS53U-CyRIu_om.js} +1 -1
  147. ksadk/server/static/assets/{journeyDiagram-EYS64GPL-DutxhSNI.js → journeyDiagram-EYS64GPL-DN5JXHzN.js} +1 -1
  148. ksadk/server/static/assets/{kanban-definition-3QL26DDD-DJdOF8Fm.js → kanban-definition-3QL26DDD-CNP3ui66.js} +1 -1
  149. ksadk/server/static/assets/{katex-vFWytM5c.js → katex-DWEzQy1d.js} +1 -1
  150. ksadk/server/static/assets/{linear-BHjG8b-J.js → linear-C-qHp7d2.js} +1 -1
  151. ksadk/server/static/assets/{mermaid-parser.core-KGSy4jWT.js → mermaid-parser.core-Cl-K943T.js} +2 -2
  152. ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-9-HC88D4.js → mindmap-definition-FBJOCRG2-D5DB5mYm.js} +1 -1
  153. ksadk/server/static/assets/packet-AYTQ26CC-C7R3NUlK.js +1 -0
  154. ksadk/server/static/assets/{pegDiagram-XKGWAZYB-DrEZd4fD.js → pegDiagram-XKGWAZYB-BQVc9ia_.js} +1 -1
  155. ksadk/server/static/assets/pie-WAS4IAKB-BIT6qjr3.js +1 -0
  156. ksadk/server/static/assets/{pieDiagram-E7YTZNPT-DpjqOFFp.js → pieDiagram-E7YTZNPT-B6UCAvtY.js} +1 -1
  157. ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-BiNhgOXX.js → quadrantDiagram-AXDQQJYC-mIr2d3eb.js} +1 -1
  158. ksadk/server/static/assets/radar-RG4KPBEZ-l5noef9X.js +1 -0
  159. ksadk/server/static/assets/railroad-74A4TZTK-Baea6ZvM.js +1 -0
  160. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-OKn8zZnU.js +1 -0
  161. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-DdKAKC4l.js +1 -0
  162. ksadk/server/static/assets/railroad-peg-WCYAUIDC-Bds8udlG.js +1 -0
  163. ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-_Y3Ojg6G.js → railroadDiagram-O6MQD6OU-Dt3FFDmK.js} +1 -1
  164. ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-DeCFdg9K.js → requirementDiagram-EFPCY7ZU-Cz_vQtgF.js} +1 -1
  165. ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-CPH75rhw.js → sankeyDiagram-P5KCCOFB-wlO1TsH5.js} +1 -1
  166. ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-OEpQQdr4.js → sequenceDiagram-WJ2MYXX4-CHRbElYq.js} +1 -1
  167. ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-heUErzhI.js → sizeCapture-X5ZJPWSS-DXX54iyO.js} +1 -1
  168. ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-DvA3jSMB.js → stateDiagram-HBIQ2CUA-Dp_lw9II.js} +1 -1
  169. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-5b-8o2iS.js +1 -0
  170. ksadk/server/static/assets/{swimlanes-XN3QIQJK-CR-dfN_t.js → swimlanes-XN3QIQJK-D8O5UlLG.js} +1 -1
  171. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uf6WPRA4.js +8 -0
  172. ksadk/server/static/assets/{timeline-definition-24CTP7MA-DAVJf1TX.js → timeline-definition-24CTP7MA-8mfKcxvG.js} +1 -1
  173. ksadk/server/static/assets/treeView-Q6P3EWNA-CK5CSrSO.js +1 -0
  174. ksadk/server/static/assets/treemap-WGGIJYW6-Ch2BKgAM.js +1 -0
  175. ksadk/server/static/assets/{vennDiagram-4TSXK5OY-DwM8eDkh.js → vennDiagram-4TSXK5OY-EnNl0DE7.js} +1 -1
  176. ksadk/server/static/assets/wardley-WFR3VGLG-YW3Q0ml_.js +1 -0
  177. ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-DZL-Zz2t.js → wardleyDiagram-VM6X3IG4-DBu5fbYr.js} +1 -1
  178. ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js → xychartDiagram-S5SC5T6Z-BSVXs4IY.js} +1 -1
  179. ksadk/server/static/index.html +2 -2
  180. ksadk/skills/service_client.py +48 -0
  181. ksadk/studio/agent_lifecycle.py +26 -20
  182. ksadk/studio/api.py +513 -71
  183. ksadk/studio/api_catalog_routes.py +5 -0
  184. ksadk/studio/api_contracts.py +34 -1
  185. ksadk/studio/api_plugin_routes.py +480 -0
  186. ksadk/studio/attachment_store.py +187 -0
  187. ksadk/studio/authoring.py +10 -4
  188. ksadk/studio/authoring_coordinator.py +12 -2
  189. ksadk/studio/builder.py +123 -43
  190. ksadk/studio/cloud.py +4 -0
  191. ksadk/studio/codex_agent_service.py +12 -1
  192. ksadk/studio/codex_builder.py +54 -15
  193. ksadk/studio/codex_manifest.py +21 -1
  194. ksadk/studio/codex_run.py +16 -4
  195. ksadk/studio/compatibility_report.py +445 -0
  196. ksadk/studio/compiler.py +6 -1
  197. ksadk/studio/contracts.py +123 -4
  198. ksadk/studio/dsh_provider_registration.py +768 -0
  199. ksadk/studio/event_store.py +54 -6
  200. ksadk/studio/framework_run.py +37 -4
  201. ksadk/studio/hosted_kernel.py +1 -1
  202. ksadk/studio/operations.py +12 -2
  203. ksadk/studio/plugin_composition.py +301 -0
  204. ksadk/studio/plugin_kernel_adapter.py +128 -0
  205. ksadk/studio/plugin_runtime.py +652 -0
  206. ksadk/studio/resource_catalog.py +6 -1
  207. ksadk/studio/run_service.py +713 -75
  208. ksadk/studio/runtime_source.py +9 -1
  209. ksadk/studio/scheduler_runtime.py +374 -0
  210. ksadk/studio/scheduler_service.py +211 -0
  211. ksadk/studio/service.py +672 -82
  212. ksadk/studio/shared_web.py +167 -28
  213. ksadk/studio/soul.py +52 -0
  214. ksadk/studio/static/assets/index-DXs1Eq4M.css +1 -0
  215. ksadk/studio/static/assets/index-DeDqwTsD.js +283 -0
  216. ksadk/studio/static/index.html +2 -2
  217. ksadk/studio/validator.py +1 -1
  218. ksadk/studio/workspace.py +1 -0
  219. ksadk/version.py +1 -1
  220. ksadk_runtime_common/workspace_files/path_utils.py +41 -0
  221. ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +0 -1
  222. ksadk/server/static/assets/channel-4cQHKtx1.js +0 -1
  223. ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +0 -1
  224. ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +0 -1
  225. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +0 -1
  226. ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +0 -1
  227. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +0 -1
  228. ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +0 -1
  229. ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +0 -1
  230. ksadk/server/static/assets/index-8ipRcQ-M.js +0 -240
  231. ksadk/server/static/assets/index-ByFCqjlh.css +0 -2
  232. ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +0 -1
  233. ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +0 -1
  234. ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +0 -1
  235. ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +0 -1
  236. ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +0 -1
  237. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +0 -1
  238. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +0 -1
  239. ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +0 -1
  240. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +0 -1
  241. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +0 -8
  242. ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +0 -1
  243. ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +0 -1
  244. ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +0 -1
  245. ksadk/studio/static/assets/index-BLpcdrgW.css +0 -1
  246. ksadk/studio/static/assets/index-CYekR2Xv.js +0 -260
  247. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.3.dist-info}/WHEEL +0 -0
  248. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.3.dist-info}/entry_points.txt +0 -0
  249. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.3.dist-info}/licenses/LICENSE +0 -0
  250. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,246 @@
1
+ """Resolve the plugin composition embedded in an AgentBundle v2 directory.
2
+
3
+ ``BundleManifest`` remains the single wire contract owned by Studio. This
4
+ module only creates a runtime view after the existing manifest, file digests,
5
+ composition profile, and plugin lock have been checked against one another and
6
+ against the selected :class:`PluginRegistry`.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import hashlib
12
+ import json
13
+ from dataclasses import dataclass
14
+ from pathlib import Path, PurePosixPath
15
+ from types import MappingProxyType
16
+ from typing import Any, Mapping
17
+
18
+ from pydantic import ValidationError
19
+
20
+ from ksadk.plugins.bundle_security import BundleSecurityError, assert_bundle_security
21
+ from ksadk.plugins.contracts import CompositionProfile, PluginLock
22
+ from ksadk.plugins.resolver import PluginRegistry, PluginResolutionError, ResolvedComposition
23
+ from ksadk.studio.contracts import BundleManifest
24
+
25
+
26
+ class PluginBundleError(ValueError):
27
+ """Stable rejection while loading the plugin portion of a Bundle v2."""
28
+
29
+ def __init__(self, code: str, message: str) -> None:
30
+ super().__init__(message)
31
+ self.code = code
32
+
33
+
34
+ @dataclass(frozen=True)
35
+ class ResolvedPluginBundle:
36
+ """Validated runtime view of existing AgentBundle v2 artifacts.
37
+
38
+ This deliberately is not another serializable bundle contract. Providers
39
+ receive the already-resolved composition and the immutable resolved Agent
40
+ spec; they do not re-read mutable Studio state.
41
+ """
42
+
43
+ root: Path
44
+ manifest: BundleManifest
45
+ resolved_agent_spec: Mapping[str, Any]
46
+ composition: ResolvedComposition
47
+
48
+ @property
49
+ def bundle_digest(self) -> str:
50
+ return str(self.manifest.bundle_digest)
51
+
52
+
53
+ class PluginBundleResolver:
54
+ """Load and cross-check the composition artifacts of an AgentBundle v2."""
55
+
56
+ def __init__(self, registry: PluginRegistry) -> None:
57
+ self._registry = registry
58
+
59
+ def resolve(self, root: str | Path) -> ResolvedPluginBundle:
60
+ bundle_root = Path(root).resolve()
61
+ if not bundle_root.is_dir():
62
+ raise PluginBundleError(
63
+ "plugin_bundle_unavailable",
64
+ f"AgentBundle directory does not exist: {bundle_root}",
65
+ )
66
+
67
+ manifest_payload = self._read_json(bundle_root, "manifest.json")
68
+ try:
69
+ manifest = BundleManifest.model_validate(manifest_payload)
70
+ except ValidationError as error:
71
+ raise PluginBundleError("plugin_bundle_manifest_invalid", str(error)) from error
72
+ if manifest.bundle_format != "agentkit.bundle/v2":
73
+ raise PluginBundleError(
74
+ "plugin_bundle_version_unsupported",
75
+ "PluginHost execution requires agentkit.bundle/v2",
76
+ )
77
+ if manifest.execution_profile != "composed":
78
+ raise PluginBundleError(
79
+ "plugin_bundle_legacy_execution",
80
+ "Bundle v2 selects legacy execution and cannot enter PluginHost",
81
+ )
82
+
83
+ self._verify_manifest_digest(manifest)
84
+ self._verify_declared_files(bundle_root, manifest)
85
+ try:
86
+ assert_bundle_security(bundle_root)
87
+ except BundleSecurityError as error:
88
+ raise PluginBundleError(
89
+ error.code,
90
+ "Plugin Bundle contains literal secret material",
91
+ ) from error
92
+
93
+ profile_payload = self._read_json(bundle_root, "composition-profile.json")
94
+ lock_payload = self._read_json(bundle_root, "plugin-lock.json")
95
+ agent_spec = self._read_json(bundle_root, "resolved-agent-spec.json")
96
+ try:
97
+ profile = CompositionProfile.model_validate(profile_payload)
98
+ embedded_lock = PluginLock.model_validate(lock_payload)
99
+ except ValidationError as error:
100
+ raise PluginBundleError("plugin_bundle_composition_invalid", str(error)) from error
101
+
102
+ try:
103
+ composition = self._registry.resolve(profile)
104
+ except PluginResolutionError as error:
105
+ raise PluginBundleError(error.code, str(error)) from error
106
+ if composition.profile_digest != manifest.composition_profile_digest:
107
+ raise PluginBundleError(
108
+ "plugin_bundle_profile_digest_mismatch",
109
+ "composition-profile.json does not match manifest compositionProfileDigest",
110
+ )
111
+ if embedded_lock != composition.plugin_lock:
112
+ raise PluginBundleError(
113
+ "plugin_bundle_lock_mismatch",
114
+ "plugin-lock.json does not match deterministic profile resolution",
115
+ )
116
+ if composition.plugin_lock_digest != manifest.plugin_lock_digest:
117
+ raise PluginBundleError(
118
+ "plugin_bundle_lock_digest_mismatch",
119
+ "plugin-lock.json does not match manifest pluginLockDigest",
120
+ )
121
+
122
+ return ResolvedPluginBundle(
123
+ root=bundle_root,
124
+ manifest=manifest,
125
+ resolved_agent_spec=_deep_freeze(agent_spec),
126
+ composition=composition,
127
+ )
128
+
129
+ @staticmethod
130
+ def _read_json(root: Path, relative: str) -> dict[str, Any]:
131
+ path = root / relative
132
+ try:
133
+ payload = json.loads(path.read_text(encoding="utf-8"))
134
+ except FileNotFoundError as error:
135
+ raise PluginBundleError(
136
+ "plugin_bundle_file_missing", f"Bundle file is missing: {relative}"
137
+ ) from error
138
+ except (OSError, UnicodeError, json.JSONDecodeError) as error:
139
+ raise PluginBundleError(
140
+ "plugin_bundle_file_invalid", f"Bundle file is invalid: {relative}"
141
+ ) from error
142
+ if not isinstance(payload, dict):
143
+ raise PluginBundleError(
144
+ "plugin_bundle_file_invalid", f"Bundle file must be an object: {relative}"
145
+ )
146
+ return payload
147
+
148
+ @staticmethod
149
+ def _verify_manifest_digest(manifest: BundleManifest) -> None:
150
+ payload = manifest.model_dump(
151
+ by_alias=True,
152
+ exclude={"bundle_digest"},
153
+ exclude_none=True,
154
+ mode="json",
155
+ )
156
+ actual = _sha256(_canonical_json(payload))
157
+ if manifest.bundle_digest != actual:
158
+ raise PluginBundleError(
159
+ "plugin_bundle_digest_mismatch",
160
+ "manifest.json does not match its declared bundleDigest",
161
+ )
162
+
163
+ @staticmethod
164
+ def _verify_declared_files(root: Path, manifest: BundleManifest) -> None:
165
+ declared: set[str] = set()
166
+ for entry in manifest.files:
167
+ relative = PurePosixPath(entry.path)
168
+ if relative.is_absolute() or ".." in relative.parts:
169
+ raise PluginBundleError(
170
+ "plugin_bundle_path_invalid",
171
+ f"Bundle manifest contains an unsafe path: {entry.path}",
172
+ )
173
+ path = (root / Path(*relative.parts)).resolve()
174
+ try:
175
+ path.relative_to(root)
176
+ except ValueError as error:
177
+ raise PluginBundleError(
178
+ "plugin_bundle_path_invalid",
179
+ f"Bundle manifest path escapes its root: {entry.path}",
180
+ ) from error
181
+ try:
182
+ content = path.read_bytes()
183
+ except OSError as error:
184
+ raise PluginBundleError(
185
+ "plugin_bundle_file_missing",
186
+ f"Declared Bundle file is missing: {entry.path}",
187
+ ) from error
188
+ if len(content) != entry.size or _sha256(content) != entry.sha256:
189
+ raise PluginBundleError(
190
+ "plugin_bundle_file_digest_mismatch",
191
+ f"Declared Bundle file failed integrity check: {entry.path}",
192
+ )
193
+ declared.add(entry.path)
194
+
195
+ required = {
196
+ "composition-profile.json",
197
+ "plugin-lock.json",
198
+ "resolved-agent-spec.json",
199
+ }
200
+ missing = sorted(required - declared)
201
+ if missing:
202
+ raise PluginBundleError(
203
+ "plugin_bundle_file_missing",
204
+ "Bundle manifest does not declare required plugin artifacts: " + ", ".join(missing),
205
+ )
206
+ actual = {
207
+ path.relative_to(root).as_posix()
208
+ for path in root.rglob("*")
209
+ if path.is_file() and path.name != "manifest.json"
210
+ }
211
+ undeclared = sorted(actual - declared)
212
+ if undeclared:
213
+ raise PluginBundleError(
214
+ "plugin_bundle_file_undeclared",
215
+ "Bundle contains files outside its integrity manifest: " + ", ".join(undeclared),
216
+ )
217
+
218
+
219
+ def _canonical_json(payload: Any) -> bytes:
220
+ return json.dumps(
221
+ payload,
222
+ ensure_ascii=False,
223
+ sort_keys=True,
224
+ separators=(",", ":"),
225
+ ).encode("utf-8")
226
+
227
+
228
+ def _sha256(payload: bytes) -> str:
229
+ return f"sha256:{hashlib.sha256(payload).hexdigest()}"
230
+
231
+
232
+ def _deep_freeze(value: Any) -> Any:
233
+ """Prevent a Provider from mutating any nested resolved-spec value."""
234
+
235
+ if isinstance(value, dict):
236
+ return MappingProxyType({key: _deep_freeze(child) for key, child in value.items()})
237
+ if isinstance(value, list):
238
+ return tuple(_deep_freeze(child) for child in value)
239
+ return value
240
+
241
+
242
+ __all__ = [
243
+ "PluginBundleError",
244
+ "PluginBundleResolver",
245
+ "ResolvedPluginBundle",
246
+ ]
@@ -0,0 +1,167 @@
1
+ """Secret and local-path admission for immutable Agent Bundles.
2
+
3
+ This is deliberately narrower than a generic source-code linter. A Bundle
4
+ may legitimately contain documentation and examples, so we inspect all
5
+ structured deployment inputs and only use high-confidence token signatures in
6
+ runtime source files. The result is suitable for a build/deployment boundary:
7
+ it prevents a resolved Bundle from becoming a durable copy of a credential
8
+ without treating every mention of the word ``token`` as a secret.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import json
14
+ import re
15
+ from dataclasses import dataclass
16
+ from pathlib import Path
17
+ from typing import Any
18
+ from urllib.parse import urlsplit
19
+
20
+ _SENSITIVE_KEY = re.compile(
21
+ r"(?:^|[_-])(?:password|passwd|api[_-]?key|access[_-]?key|secret[_-]?key|"
22
+ r"access[_-]?token|refresh[_-]?token|credential|private[_-]?key)(?:[_-]?ref)?$",
23
+ re.IGNORECASE,
24
+ )
25
+ _REFERENCE_PREFIXES = ("env://", "secret://", "keyring://", "vault://")
26
+ _HIGH_CONFIDENCE_TOKENS: tuple[tuple[str, re.Pattern[str]], ...] = (
27
+ ("private-key", re.compile(r"-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----")),
28
+ ("aws-access-key", re.compile(r"\b(?:AKIA|ASIA)[A-Z0-9]{16}\b")),
29
+ ("openai-style-key", re.compile(r"\bsk-[A-Za-z0-9_-]{20,}\b")),
30
+ ("bearer-token", re.compile(r"\bBearer\s+[A-Za-z0-9._~+/=-]{24,}")),
31
+ )
32
+ _STRUCTURED_SUFFIXES = frozenset({".json", ".yaml", ".yml"})
33
+ _RUNTIME_SOURCE_SUFFIXES = frozenset({".py", ".js", ".mjs", ".cjs", ".ts", ".tsx"})
34
+
35
+
36
+ @dataclass(frozen=True)
37
+ class BundleSecurityFinding:
38
+ """One deterministic admission finding without leaking the matched value."""
39
+
40
+ path: str
41
+ kind: str
42
+ field: str | None = None
43
+
44
+
45
+ class BundleSecurityError(ValueError):
46
+ """Raised when a Bundle would persist a literal credential or host path."""
47
+
48
+ code = "bundle_secret_detected"
49
+
50
+ def __init__(self, findings: tuple[BundleSecurityFinding, ...]) -> None:
51
+ self.findings = findings
52
+ locations = ", ".join(
53
+ f"{finding.path}{f' ({finding.field})' if finding.field else ''}"
54
+ for finding in findings[:3]
55
+ )
56
+ suffix = " …" if len(findings) > 3 else ""
57
+ super().__init__(f"Agent Bundle contains literal secret material: {locations}{suffix}")
58
+
59
+
60
+ def scan_bundle_security(root: str | Path) -> tuple[BundleSecurityFinding, ...]:
61
+ """Return high-confidence security findings for an already materialized Bundle.
62
+
63
+ Structured files receive semantic key/value inspection. Runtime source is
64
+ only searched for credential signatures; user Markdown and arbitrary
65
+ package assets are intentionally outside this detector to avoid false
66
+ positive build failures.
67
+ """
68
+
69
+ bundle_root = Path(root).resolve()
70
+ findings: list[BundleSecurityFinding] = []
71
+ for path in sorted(
72
+ (candidate for candidate in bundle_root.rglob("*") if candidate.is_file()),
73
+ key=lambda candidate: candidate.relative_to(bundle_root).as_posix(),
74
+ ):
75
+ relative = path.relative_to(bundle_root).as_posix()
76
+ suffix = path.suffix.lower()
77
+ if suffix not in _STRUCTURED_SUFFIXES and not (
78
+ relative.startswith("runtime/") and suffix in _RUNTIME_SOURCE_SUFFIXES
79
+ ):
80
+ continue
81
+ try:
82
+ text = path.read_text(encoding="utf-8")
83
+ except (OSError, UnicodeDecodeError):
84
+ continue
85
+ if suffix == ".json":
86
+ try:
87
+ payload = json.loads(text)
88
+ except json.JSONDecodeError:
89
+ findings.append(BundleSecurityFinding(relative, "invalid-structured-input"))
90
+ continue
91
+ _scan_value(payload, relative, "$", findings)
92
+ elif suffix in {".yaml", ".yml"}:
93
+ # Bundle-owned YAML is a narrow runtime launch declaration. It
94
+ # has no credential-bearing fields today, but token patterns still
95
+ # catch accidental inline credentials without introducing a second
96
+ # YAML parser/security grammar.
97
+ _scan_text(text, relative, findings)
98
+ else:
99
+ _scan_text(text, relative, findings)
100
+ return tuple(findings)
101
+
102
+
103
+ def assert_bundle_security(root: str | Path) -> None:
104
+ findings = scan_bundle_security(root)
105
+ if findings:
106
+ raise BundleSecurityError(findings)
107
+
108
+
109
+ def _scan_value(
110
+ value: Any,
111
+ relative: str,
112
+ field: str,
113
+ findings: list[BundleSecurityFinding],
114
+ ) -> None:
115
+ if isinstance(value, dict):
116
+ for key, child in value.items():
117
+ key_text = str(key)
118
+ child_field = f"{field}.{key_text}"
119
+ normalized = key_text.replace("_", "").replace("-", "").lower()
120
+ # Metadata that *names* secret fields is not a secret value.
121
+ if normalized in {"secretfields", "credentialfields"}:
122
+ continue
123
+ if _SENSITIVE_KEY.search(key_text) and _has_literal_secret(child):
124
+ findings.append(
125
+ BundleSecurityFinding(relative, "literal-secret-field", child_field)
126
+ )
127
+ _scan_value(child, relative, child_field, findings)
128
+ return
129
+ if isinstance(value, list):
130
+ for index, child in enumerate(value):
131
+ _scan_value(child, relative, f"{field}[{index}]", findings)
132
+ return
133
+ if isinstance(value, str):
134
+ _scan_text(value, relative, findings, field=field)
135
+ split = urlsplit(value)
136
+ # ``plugin://name@version`` is a pinned package reference, not URL
137
+ # userinfo. Only network endpoint schemes can carry credentials here.
138
+ if split.scheme in {"http", "https"} and (
139
+ split.username is not None or split.password is not None
140
+ ):
141
+ findings.append(BundleSecurityFinding(relative, "url-credentials", field))
142
+ if value.startswith(("/Users/", "/home/", "C:\\Users\\")):
143
+ findings.append(BundleSecurityFinding(relative, "local-home-path", field))
144
+
145
+
146
+ def _has_literal_secret(value: Any) -> bool:
147
+ return isinstance(value, str) and bool(value) and not value.startswith(_REFERENCE_PREFIXES)
148
+
149
+
150
+ def _scan_text(
151
+ text: str,
152
+ relative: str,
153
+ findings: list[BundleSecurityFinding],
154
+ *,
155
+ field: str | None = None,
156
+ ) -> None:
157
+ for kind, pattern in _HIGH_CONFIDENCE_TOKENS:
158
+ if pattern.search(text):
159
+ findings.append(BundleSecurityFinding(relative, kind, field))
160
+
161
+
162
+ __all__ = [
163
+ "BundleSecurityError",
164
+ "BundleSecurityFinding",
165
+ "assert_bundle_security",
166
+ "scan_bundle_security",
167
+ ]