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,627 @@
1
+ """KsADK Harness AgentProvider backed by the canonical RuntimeExecutor.
2
+
3
+ The provider composes locked MCP, Skill, and Context capabilities, then
4
+ delegates every turn to ``HarnessRuntimeAdapter`` through
5
+ ``invoke_runtime_conversation_once``. RuntimeEvent persistence and Session
6
+ history therefore stay on the existing conversation pipeline; this module does
7
+ not create another event stream or transcript store.
8
+ """
9
+ from __future__ import annotations
10
+
11
+ import json
12
+ from collections.abc import Mapping, Sequence
13
+ from dataclasses import dataclass, replace
14
+ from pathlib import Path
15
+ from typing import Any, Protocol, cast, runtime_checkable
16
+
17
+ from ksadk.harness.config import HarnessConfig, McpToolSpec, SandboxPolicy
18
+ from ksadk.harness.reasoner import HarnessReasoner, LiteLLMHarnessReasoner
19
+ from ksadk.harness.runtime import HarnessRuntimeAdapter
20
+ from ksadk.plugins.bundle import ResolvedPluginBundle
21
+ from ksadk.plugins.contracts import CompositionProfile, PluginManifest
22
+ from ksadk.plugins.host import PluginExecutionContext, PluginHostError
23
+ from ksadk.runtime import RuntimeExecutor, RuntimeLaunchContext, RuntimeRegistry, StartRequest
24
+ from ksadk.runtime.conversation_execution import invoke_runtime_conversation_once
25
+ from ksadk.sessions import create_session_service
26
+ from ksadk.sessions.base import BaseSessionService
27
+
28
+ _HISTORY_ENVELOPE_PREFIX = "agentkit.conversation-history/v1:"
29
+
30
+
31
+ @dataclass(frozen=True)
32
+ class HarnessSkillContribution:
33
+ name: str
34
+ instructions: str
35
+
36
+
37
+ @dataclass(frozen=True)
38
+ class HarnessProviderInventory:
39
+ provider: str
40
+ execution_strategy: str
41
+ model: str
42
+ history_owner: str
43
+ mcp_servers: tuple[str, ...]
44
+ skills: tuple[str, ...]
45
+ context_contributors: tuple[str, ...]
46
+
47
+
48
+ @dataclass(frozen=True)
49
+ class HarnessTurnRequest:
50
+ user_id: str
51
+ session_id: str | None
52
+ messages: tuple[Mapping[str, Any], ...]
53
+ model: str | None = None
54
+ request_metadata: Mapping[str, Any] | None = None
55
+ invocation_id: str | None = None
56
+
57
+ @classmethod
58
+ def parse(cls, value: Any) -> "HarnessTurnRequest":
59
+ if isinstance(value, cls):
60
+ return value
61
+ if not isinstance(value, Mapping):
62
+ raise PluginHostError(
63
+ "harness_input_invalid", "Harness input must be an object"
64
+ )
65
+ user_id = str(value.get("user_id") or value.get("userId") or "").strip()
66
+ if not user_id:
67
+ raise PluginHostError(
68
+ "harness_input_invalid", "Harness input requires user_id"
69
+ )
70
+ raw_messages = value.get("messages")
71
+ if raw_messages is None and value.get("input") is not None:
72
+ raw_messages = [{"role": "user", "content": value.get("input")}]
73
+ if not isinstance(raw_messages, Sequence) or isinstance(
74
+ raw_messages, (str, bytes)
75
+ ):
76
+ raise PluginHostError(
77
+ "harness_input_invalid", "Harness input requires messages"
78
+ )
79
+ messages: list[Mapping[str, Any]] = []
80
+ for index, message in enumerate(raw_messages):
81
+ if not isinstance(message, Mapping):
82
+ raise PluginHostError(
83
+ "harness_input_invalid",
84
+ f"Harness messages[{index}] must be an object",
85
+ )
86
+ role = str(message.get("role") or "").strip()
87
+ if role not in {"system", "user", "assistant", "tool"}:
88
+ raise PluginHostError(
89
+ "harness_input_invalid",
90
+ f"Harness messages[{index}] has unsupported role {role!r}",
91
+ )
92
+ messages.append(dict(message))
93
+ if not messages or messages[-1].get("role") != "user":
94
+ raise PluginHostError(
95
+ "harness_input_invalid", "Harness turn must end with a user message"
96
+ )
97
+ session_id = str(
98
+ value.get("session_id") or value.get("sessionId") or ""
99
+ ).strip()
100
+ model = str(value.get("model") or "").strip()
101
+ metadata = value.get("request_metadata") or value.get("requestMetadata")
102
+ if metadata is not None and not isinstance(metadata, Mapping):
103
+ raise PluginHostError(
104
+ "harness_input_invalid", "request_metadata must be an object"
105
+ )
106
+ return cls(
107
+ user_id=user_id,
108
+ session_id=session_id or None,
109
+ messages=tuple(messages),
110
+ model=model or None,
111
+ request_metadata=dict(metadata) if metadata is not None else None,
112
+ invocation_id=str(
113
+ value.get("invocation_id") or value.get("invocationId") or ""
114
+ ).strip()
115
+ or None,
116
+ )
117
+
118
+
119
+ @dataclass(frozen=True)
120
+ class HarnessTurnResult:
121
+ session_id: str
122
+ output_text: str
123
+ usage: Mapping[str, Any]
124
+ metadata: Mapping[str, Any]
125
+ inventory: HarnessProviderInventory
126
+
127
+
128
+ @runtime_checkable
129
+ class HarnessMCPSource(Protocol):
130
+ def harness_mcp_specs(
131
+ self, bundle: ResolvedPluginBundle
132
+ ) -> Sequence[McpToolSpec]: ...
133
+
134
+
135
+ @runtime_checkable
136
+ class HarnessSkillSource(Protocol):
137
+ def harness_skill(
138
+ self, bundle: ResolvedPluginBundle
139
+ ) -> HarnessSkillContribution: ...
140
+
141
+
142
+ @runtime_checkable
143
+ class HarnessContextSource(Protocol):
144
+ async def harness_context(
145
+ self, bundle: ResolvedPluginBundle, request: HarnessTurnRequest
146
+ ) -> str: ...
147
+
148
+
149
+ class _ConversationHistoryReasoner:
150
+ """Restore canonical message roles before calling the Harness reasoner.
151
+
152
+ HarnessRuntimeAdapter currently builds ``system + current user`` itself.
153
+ The provider encodes the canonical conversation input into that user slot;
154
+ this wrapper expands it back into structured roles without reimplementing
155
+ the Harness reasoning/tool loop.
156
+ """
157
+
158
+ def __init__(self, delegate: HarnessReasoner) -> None:
159
+ self._delegate = delegate
160
+
161
+ async def complete(
162
+ self,
163
+ *,
164
+ model: str,
165
+ prompt: str,
166
+ messages: Sequence[dict[str, Any]],
167
+ tools: Sequence[Any],
168
+ ) -> Any:
169
+ expanded = list(messages)
170
+ if len(expanded) >= 2:
171
+ content = expanded[1].get("content")
172
+ if isinstance(content, str) and content.startswith(_HISTORY_ENVELOPE_PREFIX):
173
+ raw = content.removeprefix(_HISTORY_ENVELOPE_PREFIX)
174
+ try:
175
+ history = json.loads(raw)
176
+ except json.JSONDecodeError as error:
177
+ raise RuntimeError("invalid canonical Harness history envelope") from error
178
+ if not isinstance(history, list) or not all(
179
+ isinstance(item, dict) for item in history
180
+ ):
181
+ raise RuntimeError("invalid canonical Harness history payload")
182
+ expanded = [expanded[0], *_chat_history(history), *expanded[2:]]
183
+ return await self._delegate.complete(
184
+ model=model,
185
+ prompt=prompt,
186
+ messages=expanded,
187
+ tools=tools,
188
+ )
189
+
190
+
191
+ class _ConversationHistoryHarnessAdapter(HarnessRuntimeAdapter):
192
+ """Compatibility adapter with SessionService as the only history owner."""
193
+
194
+ async def start(self, request: StartRequest): # type: ignore[no-untyped-def]
195
+ preprocessing = request.conversation_preprocessing()
196
+ if preprocessing is not None and preprocessing.messages:
197
+ request = request.model_copy(
198
+ update={
199
+ "input": _HISTORY_ENVELOPE_PREFIX
200
+ + json.dumps(
201
+ preprocessing.messages,
202
+ ensure_ascii=False,
203
+ sort_keys=True,
204
+ separators=(",", ":"),
205
+ )
206
+ }
207
+ )
208
+ return await super().start(request)
209
+
210
+ async def execute_request(self, request: StartRequest) -> dict[str, Any]:
211
+ # The standalone Harness adapter intentionally offers process-local
212
+ # continuity. PluginHost already prepares the complete canonical
213
+ # SessionService history, so retaining that same turn again inside the
214
+ # adapter would create two history owners and duplicate future turns.
215
+ session = self._session_for(request)
216
+ async with session.lock:
217
+ session.messages.clear()
218
+ try:
219
+ result = await self._execute_session_request(request, session)
220
+ return cast(dict[str, Any], result)
221
+ finally:
222
+ session.messages.clear()
223
+
224
+
225
+ class KsADKHarnessProviderRuntime:
226
+ """PluginHost AgentProvider that owns Harness activation assembly."""
227
+
228
+ def __init__(
229
+ self,
230
+ *,
231
+ plugin_id: str,
232
+ session_service: BaseSessionService,
233
+ reasoner: HarnessReasoner,
234
+ ) -> None:
235
+ self._plugin_id = plugin_id
236
+ self._session_service = session_service
237
+ self._reasoner = reasoner
238
+ self._ready = False
239
+ self._disposed = False
240
+ self._last_inventory: HarnessProviderInventory | None = None
241
+
242
+ @property
243
+ def last_inventory(self) -> HarnessProviderInventory | None:
244
+ return self._last_inventory
245
+
246
+ @property
247
+ def disposed(self) -> bool:
248
+ return self._disposed
249
+
250
+ async def start(self) -> None:
251
+ if self._disposed:
252
+ raise RuntimeError("Harness provider is disposed")
253
+ self._ready = True
254
+
255
+ async def health(self) -> bool:
256
+ return self._ready and not self._disposed
257
+
258
+ async def drain(self) -> None:
259
+ self._ready = False
260
+
261
+ async def dispose(self) -> None:
262
+ self._ready = False
263
+ self._disposed = True
264
+
265
+ async def prepare(
266
+ self,
267
+ bundle: ResolvedPluginBundle,
268
+ *,
269
+ capabilities: PluginExecutionContext,
270
+ ) -> "KsADKHarnessActivation":
271
+ if not self._ready or self._disposed:
272
+ raise PluginHostError(
273
+ "harness_provider_unavailable", "Harness provider is not ready"
274
+ )
275
+
276
+ mcp_specs: list[McpToolSpec] = []
277
+ mcp_owners: list[str] = []
278
+ for binding in capabilities.all("mcp.connector/v1"):
279
+ if not isinstance(binding.runtime, HarnessMCPSource):
280
+ raise PluginHostError(
281
+ "harness_mcp_incompatible",
282
+ f"plugin {binding.plugin_id} cannot project Harness MCP config",
283
+ )
284
+ mcp_specs.extend(binding.runtime.harness_mcp_specs(bundle))
285
+ mcp_owners.append(binding.plugin_id)
286
+
287
+ skills: list[HarnessSkillContribution] = []
288
+ skill_owners: list[str] = []
289
+ for binding in capabilities.all("skill.source/v1"):
290
+ if not isinstance(binding.runtime, HarnessSkillSource):
291
+ raise PluginHostError(
292
+ "harness_skill_incompatible",
293
+ f"plugin {binding.plugin_id} cannot project Harness instructions",
294
+ )
295
+ contribution = binding.runtime.harness_skill(bundle)
296
+ if not contribution.name.strip() or not contribution.instructions.strip():
297
+ raise PluginHostError(
298
+ "harness_skill_invalid",
299
+ f"plugin {binding.plugin_id} returned an empty Skill contribution",
300
+ )
301
+ skills.append(contribution)
302
+ skill_owners.append(binding.plugin_id)
303
+
304
+ context_sources: list[HarnessContextSource] = []
305
+ context_owners: list[str] = []
306
+ for binding in capabilities.all("context.contributor/v1"):
307
+ if not isinstance(binding.runtime, HarnessContextSource):
308
+ raise PluginHostError(
309
+ "harness_context_incompatible",
310
+ f"plugin {binding.plugin_id} cannot contribute Harness context",
311
+ )
312
+ context_sources.append(binding.runtime)
313
+ context_owners.append(binding.plugin_id)
314
+
315
+ execution = bundle.resolved_agent_spec.get("execution")
316
+ strategy = (
317
+ str(execution.get("strategy") or "direct").strip()
318
+ if isinstance(execution, Mapping)
319
+ else "direct"
320
+ )
321
+ if strategy != "direct":
322
+ raise PluginHostError(
323
+ "harness_execution_strategy_unsupported",
324
+ f"KsADK Harness Provider does not support {strategy!r}",
325
+ )
326
+
327
+ model, prompt = _bundle_model_and_prompt(bundle)
328
+ if skills:
329
+ prompt = _append_prompt_sections(
330
+ prompt,
331
+ [f"Skill {item.name}:\n{item.instructions}" for item in skills],
332
+ )
333
+ config = HarnessConfig(
334
+ model=model,
335
+ prompt=prompt,
336
+ mcp_tools=tuple(mcp_specs),
337
+ sandbox=SandboxPolicy(read_only=True),
338
+ runtime="yaml",
339
+ )
340
+ inventory = HarnessProviderInventory(
341
+ provider=self._plugin_id,
342
+ execution_strategy=strategy,
343
+ model=model,
344
+ history_owner="canonical_session_service",
345
+ mcp_servers=tuple(mcp_owners),
346
+ skills=tuple(item.name for item in skills),
347
+ context_contributors=tuple(context_owners),
348
+ )
349
+ self._last_inventory = inventory
350
+ workspace_root = bundle.root / "runtime"
351
+ if not workspace_root.is_dir():
352
+ workspace_root = bundle.root
353
+ return KsADKHarnessActivation(
354
+ bundle=bundle,
355
+ config=config,
356
+ agent_name=bundle.manifest.agent_id,
357
+ workspace_root=workspace_root,
358
+ reasoner=self._reasoner,
359
+ context_sources=tuple(context_sources),
360
+ session_service=self._session_service,
361
+ inventory=inventory,
362
+ )
363
+
364
+
365
+ class KsADKHarnessProviderFactory:
366
+ def __init__(
367
+ self,
368
+ *,
369
+ session_service: BaseSessionService | None = None,
370
+ reasoner: HarnessReasoner | None = None,
371
+ ) -> None:
372
+ self._session_service = session_service
373
+ self._reasoner = reasoner
374
+ self.runtime: KsADKHarnessProviderRuntime | None = None
375
+
376
+ async def stage(
377
+ self,
378
+ manifest: PluginManifest,
379
+ *,
380
+ profile: CompositionProfile,
381
+ services: Mapping[str, Any],
382
+ ) -> KsADKHarnessProviderRuntime:
383
+ del profile
384
+ service = self._session_service or services.get("session_service")
385
+ if service is None:
386
+ service = create_session_service(backend="memory")
387
+ if not isinstance(service, BaseSessionService):
388
+ raise PluginHostError(
389
+ "harness_session_service_invalid",
390
+ "Harness provider requires a BaseSessionService",
391
+ )
392
+ reasoner = self._reasoner or services.get("harness_reasoner")
393
+ if reasoner is None:
394
+ reasoner = LiteLLMHarnessReasoner()
395
+ self.runtime = KsADKHarnessProviderRuntime(
396
+ plugin_id=manifest.metadata.id,
397
+ session_service=service,
398
+ reasoner=reasoner,
399
+ )
400
+ return self.runtime
401
+
402
+
403
+ class KsADKHarnessActivation:
404
+ def __init__(
405
+ self,
406
+ *,
407
+ bundle: ResolvedPluginBundle,
408
+ config: HarnessConfig,
409
+ agent_name: str,
410
+ workspace_root: Path,
411
+ reasoner: HarnessReasoner,
412
+ context_sources: tuple[HarnessContextSource, ...],
413
+ session_service: BaseSessionService,
414
+ inventory: HarnessProviderInventory,
415
+ ) -> None:
416
+ self._bundle = bundle
417
+ self._config = config
418
+ self._agent_name = agent_name
419
+ self._workspace_root = workspace_root
420
+ self._reasoner = reasoner
421
+ self._context_sources = context_sources
422
+ self._session_service = session_service
423
+ self._inventory = inventory
424
+ self._ready = False
425
+ self._disposed = False
426
+ self._executors: list[RuntimeExecutor] = []
427
+ self._kernel_adapter: HarnessRuntimeAdapter | None = None
428
+
429
+ async def start(self) -> None:
430
+ if self._disposed:
431
+ raise RuntimeError("Harness activation is disposed")
432
+ self._ready = True
433
+
434
+ async def health(self) -> bool:
435
+ return self._ready and not self._disposed
436
+
437
+ async def execute(self, request: Any) -> HarnessTurnResult:
438
+ if not self._ready or self._disposed:
439
+ raise PluginHostError(
440
+ "harness_activation_unavailable", "Harness activation is not ready"
441
+ )
442
+ turn = HarnessTurnRequest.parse(request)
443
+ context_sections = [
444
+ text.strip()
445
+ for source in self._context_sources
446
+ if (text := await source.harness_context(self._bundle, turn)).strip()
447
+ ]
448
+ config = replace(
449
+ self._config,
450
+ prompt=_append_prompt_sections(self._config.prompt, context_sections),
451
+ )
452
+ executor, launch_context = _build_direct_backend(
453
+ config,
454
+ agent_name=self._agent_name,
455
+ workspace_root=self._workspace_root,
456
+ reasoner=self._reasoner,
457
+ )
458
+ self._executors.append(executor)
459
+ preparation = await executor.prepare_start(launch_context)
460
+ session_id, result = await invoke_runtime_conversation_once(
461
+ executor=executor,
462
+ launch_context=launch_context,
463
+ agent_id=self._agent_name,
464
+ user_id=turn.user_id,
465
+ messages=[dict(item) for item in turn.messages],
466
+ session_id=turn.session_id,
467
+ model=turn.model or config.model,
468
+ instructions=config.prompt,
469
+ request_metadata=turn.request_metadata,
470
+ invocation_id=turn.invocation_id,
471
+ session_service_provider=lambda: self._session_service,
472
+ runtime_preparation=preparation,
473
+ )
474
+ return HarnessTurnResult(
475
+ session_id=session_id,
476
+ output_text=str(result.get("output_text") or ""),
477
+ usage=dict(result.get("usage") or {}),
478
+ metadata=dict(result.get("metadata") or {}),
479
+ inventory=self._inventory,
480
+ )
481
+
482
+ def runtime_adapter(self) -> HarnessRuntimeAdapter:
483
+ """Return the activation-owned adapter used by AgentKernel Scheduler.
484
+
485
+ The immutable profile has already assembled model instructions, MCP,
486
+ Skills, sandbox and permissions into ``self._config``. Reusing one
487
+ adapter per session activation preserves Harness' honest process-local
488
+ continuity while AgentKernel remains the only event persistence owner.
489
+ """
490
+
491
+ if not self._ready or self._disposed:
492
+ raise PluginHostError(
493
+ "harness_activation_unavailable", "Harness activation is not ready"
494
+ )
495
+ if self._kernel_adapter is None:
496
+ self._kernel_adapter = HarnessRuntimeAdapter(
497
+ self._config,
498
+ agent_name=self._agent_name,
499
+ reasoner=self._reasoner,
500
+ workspace_root=self._workspace_root,
501
+ )
502
+ return self._kernel_adapter
503
+
504
+ async def drain(self) -> None:
505
+ self._ready = False
506
+
507
+ async def dispose(self) -> None:
508
+ self._ready = False
509
+ first_error: BaseException | None = None
510
+ if self._kernel_adapter is not None:
511
+ try:
512
+ await self._kernel_adapter.close_all()
513
+ except BaseException as error: # cleanup must continue
514
+ first_error = error
515
+ self._kernel_adapter = None
516
+ for executor in reversed(self._executors):
517
+ try:
518
+ await executor.close_all()
519
+ except BaseException as error: # cleanup must continue
520
+ if first_error is None:
521
+ first_error = error
522
+ self._executors.clear()
523
+ self._disposed = True
524
+ if first_error is not None:
525
+ raise first_error
526
+
527
+
528
+ def _build_direct_backend(
529
+ config: HarnessConfig,
530
+ *,
531
+ agent_name: str,
532
+ workspace_root: Path,
533
+ reasoner: HarnessReasoner,
534
+ ) -> tuple[RuntimeExecutor, RuntimeLaunchContext]:
535
+ """Internal execution seam; Phase 2 does not expose strategy as a plugin."""
536
+
537
+ history_reasoner = _ConversationHistoryReasoner(reasoner)
538
+ registry = RuntimeRegistry()
539
+ registry.register(
540
+ "harness",
541
+ lambda _context: _ConversationHistoryHarnessAdapter(
542
+ config,
543
+ agent_name=agent_name,
544
+ reasoner=history_reasoner,
545
+ workspace_root=workspace_root,
546
+ ),
547
+ )
548
+ return RuntimeExecutor(registry), RuntimeLaunchContext(
549
+ runtime_type="harness",
550
+ project_dir=workspace_root,
551
+ config={
552
+ "model": config.model,
553
+ "base_instructions": config.prompt,
554
+ "sandbox_read_only": config.sandbox.read_only,
555
+ },
556
+ )
557
+
558
+
559
+ def _bundle_model_and_prompt(bundle: ResolvedPluginBundle) -> tuple[str, str]:
560
+ spec = bundle.resolved_agent_spec
561
+ raw_model = spec.get("model")
562
+ model = (
563
+ str(raw_model.get("model") or "").strip()
564
+ if isinstance(raw_model, Mapping)
565
+ else str(raw_model or "").strip()
566
+ )
567
+ instructions = spec.get("instructions")
568
+ if not isinstance(instructions, Mapping):
569
+ instructions = {}
570
+ system = str(instructions.get("system") or "").strip()
571
+ task = str(instructions.get("task") or "").strip()
572
+ prompt = _append_prompt_sections(system, [task])
573
+ if not model:
574
+ raise PluginHostError(
575
+ "harness_bundle_model_missing", "Bundle resolved Agent spec has no model"
576
+ )
577
+ if not prompt:
578
+ raise PluginHostError(
579
+ "harness_bundle_prompt_missing", "Bundle resolved Agent spec has no instructions"
580
+ )
581
+ return model, prompt
582
+
583
+
584
+ def _append_prompt_sections(base: str, sections: Sequence[str]) -> str:
585
+ values = [base.strip(), *(section.strip() for section in sections)]
586
+ return "\n\n".join(value for value in values if value)
587
+
588
+
589
+ def _chat_history(history: Sequence[Mapping[str, Any]]) -> list[dict[str, Any]]:
590
+ """Translate Responses message content into the Harness chat shape."""
591
+
592
+ normalized: list[dict[str, Any]] = []
593
+ for item in history:
594
+ role = str(item.get("role") or "").strip().lower()
595
+ if role == "model":
596
+ role = "assistant"
597
+ if role not in {"user", "assistant", "tool"}:
598
+ continue
599
+ content = item.get("content")
600
+ if isinstance(content, Sequence) and not isinstance(
601
+ content, (str, bytes, bytearray)
602
+ ):
603
+ segments = [
604
+ str(part.get("text") or "")
605
+ for part in content
606
+ if isinstance(part, Mapping) and part.get("text") is not None
607
+ ]
608
+ content = "\n".join(segment for segment in segments if segment)
609
+ message = {"role": role, "content": str(content or "")}
610
+ for key in ("tool_call_id", "name", "tool_calls"):
611
+ if key in item:
612
+ message[key] = item[key]
613
+ normalized.append(message)
614
+ return normalized
615
+
616
+
617
+ __all__ = [
618
+ "HarnessContextSource",
619
+ "HarnessMCPSource",
620
+ "HarnessProviderInventory",
621
+ "HarnessSkillContribution",
622
+ "HarnessSkillSource",
623
+ "HarnessTurnRequest",
624
+ "HarnessTurnResult",
625
+ "KsADKHarnessProviderFactory",
626
+ "KsADKHarnessProviderRuntime",
627
+ ]