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
ksadk/codex/runtime.py CHANGED
@@ -107,11 +107,13 @@ class CodexRuntimeAdapter(RuntimeAdapter):
107
107
  *,
108
108
  sandbox_read_only: bool = True,
109
109
  turn_timeout_seconds: Optional[float] = None,
110
+ bound_skill_paths: Mapping[str, str] | None = None,
110
111
  ) -> None:
111
112
  super().__init__(_CodexAsBaseRuntime(client))
112
113
  self._client = client
113
114
  self._sandbox_read_only = sandbox_read_only
114
115
  self._turn_timeout_seconds = turn_timeout_seconds
116
+ self._bound_skill_paths = dict(bound_skill_paths or {})
115
117
  self._threads: dict[str, _CodexThread] = {}
116
118
  self._requests: dict[str, StartRequest] = {}
117
119
  self._known_threads: set[str] = set()
@@ -147,6 +149,7 @@ class CodexRuntimeAdapter(RuntimeAdapter):
147
149
  goal=RuntimeCapability(supported=True, mode="native"),
148
150
  loop=_unavailable("codex_loop_requires_run_control_spec"),
149
151
  plan=RuntimeCapability(supported=True, mode="native"),
152
+ interaction_mode="live_submit",
150
153
  )
151
154
 
152
155
  # ---- 六动词 ----
@@ -154,6 +157,25 @@ class CodexRuntimeAdapter(RuntimeAdapter):
154
157
  async def start(self, request: StartRequest) -> RunHandle:
155
158
  # 新 thread 由后端分配真实 thread_id(thread_start);metadata 携带的 thread_id
156
159
  # 表示接入既有 thread(resume 语义,run_turn 时按 resume 接入)。
160
+ if self._bound_skill_paths:
161
+ skills = request.config.get("skills") if request.config else None
162
+ if isinstance(skills, list):
163
+ projected_skills = []
164
+ for item in skills:
165
+ if not isinstance(item, dict):
166
+ continue
167
+ name = str(item.get("name") or "").strip()
168
+ projected_skills.append(
169
+ {
170
+ **item,
171
+ "path": self._bound_skill_paths.get(
172
+ name, str(item.get("path") or "")
173
+ ),
174
+ }
175
+ )
176
+ request = request.model_copy(
177
+ update={"config": {**request.config, "skills": projected_skills}}
178
+ )
157
179
  provided = request.metadata.get("thread_id")
158
180
  if provided:
159
181
  thread_id = str(provided)
@@ -353,23 +375,43 @@ class CodexRuntimeAdapter(RuntimeAdapter):
353
375
  )
354
376
 
355
377
  async def close(self, handle: RunHandle) -> None:
378
+ self._do_not_persist.add(handle.run_id)
379
+ await self.close_all()
380
+
381
+ async def close_all(self) -> None:
382
+ """Dispose every thread and the activation-owned App Server process.
383
+
384
+ One ``CodexRuntimeAdapter`` owns one client transport. Closing any
385
+ attached Kernel handle therefore closes the transport as a unit; this
386
+ additive helper also lets a draining AgentProvider clean up a runtime
387
+ that has been created but not started yet.
388
+ """
389
+
356
390
  if self._closed:
357
391
  return
358
392
  self._closed = True
359
- thread = self._threads.pop(handle.run_id, None)
360
- self._requests.pop(handle.run_id, None)
361
- active = thread is not None and thread.streaming and not thread.done
362
- if active:
393
+ threads = tuple(self._threads.values())
394
+ active_threads = tuple(
395
+ thread for thread in threads if thread.streaming and not thread.done
396
+ )
397
+ for thread in active_threads:
363
398
  thread.interrupt_event.set()
364
399
  try:
365
- if active:
400
+ for thread in active_threads:
366
401
  await self._client.interrupt_active_turn(thread.thread_id)
367
402
  finally:
368
403
  # AsyncCodex.close owns terminate/wait/kill for the app-server child.
369
404
  await self._client.close()
370
- self._do_not_persist.add(handle.run_id)
371
- self._known_threads.discard(handle.run_id)
372
- self._pending_cancels.discard(handle.run_id)
405
+ thread_ids = {
406
+ *self._known_threads,
407
+ *self._threads,
408
+ *self._requests,
409
+ }
410
+ self._do_not_persist.update(thread_ids)
411
+ self._threads.clear()
412
+ self._requests.clear()
413
+ self._known_threads.clear()
414
+ self._pending_cancels.clear()
373
415
 
374
416
  # ---- stream → RuntimeEvent(phase 翻译 + 中断竞速) ----
375
417
 
@@ -232,6 +232,28 @@ _ENV_VAR_REGISTRY_ITEMS: tuple[EnvVarSpec, ...] = (
232
232
  "Isolate native Codex state under the project workspace; set to 0 for debugging only.",
233
233
  "1",
234
234
  ),
235
+ EnvVarSpec(
236
+ "KSADK_DSH_BIN",
237
+ "plugins",
238
+ (
239
+ "Optional absolute path to the managed DSH command; must match the pinned "
240
+ "toolchain version."
241
+ ),
242
+ ),
243
+ EnvVarSpec(
244
+ "KSADK_DSH_HOME",
245
+ "plugins",
246
+ (
247
+ "Directory containing the isolated DSH Profile; defaults to .agentkit/dsh-home "
248
+ "in the workspace."
249
+ ),
250
+ ),
251
+ EnvVarSpec(
252
+ "KSADK_DSH_PROFILE",
253
+ "plugins",
254
+ "DSH Profile name used by Studio and the plugin bridge.",
255
+ "studio",
256
+ ),
235
257
  EnvVarSpec(
236
258
  "KSADK_STUDIO_NO_SECURITY",
237
259
  "studio",
@@ -356,7 +378,10 @@ _ENV_VAR_REGISTRY_ITEMS: tuple[EnvVarSpec, ...] = (
356
378
  EnvVarSpec(
357
379
  "KSADK_LANGGRAPH_AUTO_CHECKPOINT",
358
380
  "sessions",
359
- "Allow a hosted LangGraph runner to rebuild a factory-exported graph with the managed PostgreSQL saver.",
381
+ (
382
+ "Allow a hosted LangGraph runner to rebuild a factory-exported graph with the "
383
+ "managed PostgreSQL saver."
384
+ ),
360
385
  "false",
361
386
  ),
362
387
  EnvVarSpec(
@@ -640,7 +665,10 @@ _ENV_VAR_REGISTRY_ITEMS: tuple[EnvVarSpec, ...] = (
640
665
  EnvVarSpec(
641
666
  "KSADK_AGENT_KERNEL",
642
667
  "kernel",
643
- "Opt in to Agent Kernel ingress locally; managed deployment may use AGENT_KERNEL_ENABLED instead.",
668
+ (
669
+ "Opt in to Agent Kernel ingress locally; managed deployment may use "
670
+ "AGENT_KERNEL_ENABLED instead."
671
+ ),
644
672
  "false",
645
673
  ),
646
674
  EnvVarSpec("KSADK_SESSION_PATH", "sessions", "Conversation local SQLite database path."),
@@ -810,7 +838,7 @@ _ENV_VAR_REGISTRY_ITEMS: tuple[EnvVarSpec, ...] = (
810
838
  "KSADK_WEB_VERSION",
811
839
  "web",
812
840
  "Published KsADK Web npm version used for a reproducible wheel build.",
813
- "0.3.2",
841
+ "0.3.4",
814
842
  ),
815
843
  EnvVarSpec(
816
844
  "KSADK_WORKING_SET_MAX_FILES",
ksadk/configs/settings.py CHANGED
@@ -628,3 +628,12 @@ def setup_environment(agent_path: Path | str):
628
628
  setup_proxy_redirect_if_enabled()
629
629
  except Exception: # noqa: BLE001 代理可选,失败不影响主流程(默认关时本就不触发)
630
630
  pass
631
+
632
+ # 5. 沙箱控制面 URL 内网探测:在 Pod 内探测 198 公共服务网内网地址,
633
+ # 可达则覆盖 E2B_API_URL 为内网域名,private_only 节点也能访问沙箱控制面。
634
+ try:
635
+ from ksadk.sandbox import setup_sandbox_api_url_if_needed
636
+
637
+ setup_sandbox_api_url_if_needed()
638
+ except Exception: # noqa: BLE001 沙箱可选,失败不影响主流程
639
+ pass
@@ -24,6 +24,14 @@ logger = logging.getLogger(__name__)
24
24
  ContributorFailureMode = Literal["skip", "warn", "fail"]
25
25
  ContributorCacheability = Literal["stable", "turn", "none"]
26
26
 
27
+ _TRUST_RANK: dict[ContextTrustLevel, int] = {
28
+ "untrusted": 0,
29
+ "user": 1,
30
+ "resource": 2,
31
+ "developer": 3,
32
+ "platform": 4,
33
+ }
34
+
27
35
 
28
36
  @dataclass(frozen=True)
29
37
  class ContributorCapabilities:
@@ -131,13 +139,15 @@ class WorkspaceRulesContributor(ContextContributor):
131
139
  return []
132
140
  items: list[ContextItem] = []
133
141
  for index, section in enumerate(sections):
142
+ raw_tokens = section.metadata.get("tokens", 0)
143
+ tokens = int(raw_tokens) if isinstance(raw_tokens, (int, str)) else 0
134
144
  items.append(
135
145
  _make_item(
136
146
  contributor_id=self.capabilities.contributor_id,
137
147
  trust_level=self.capabilities.trust_level,
138
148
  kind="resource_manifest",
139
149
  content=section.content,
140
- tokens=int(section.metadata.get("tokens", 0)) or 1,
150
+ tokens=tokens or 1,
141
151
  source=section.source,
142
152
  metadata={"path": section.metadata.get("path"), "kind": "rule_file"},
143
153
  )
@@ -267,6 +277,60 @@ class ContributionResult:
267
277
  warnings: tuple[str, ...]
268
278
 
269
279
 
280
+ def _admit_contribution_items(
281
+ contributor: ContextContributor,
282
+ items: object,
283
+ ) -> tuple[list[ContextItem], str | None]:
284
+ """Validate one Contributor result and enforce its declared token ceiling.
285
+
286
+ A Contributor is an untrusted capability boundary. It cannot promote an
287
+ item above the trust level granted at registration, mark context as
288
+ required, return duplicate identities, or make the Host confuse token
289
+ counts with list indexes. Items that do not fit the declared budget are
290
+ deterministically omitted while later, smaller items may still fit.
291
+ """
292
+
293
+ if not isinstance(items, list) or not all(isinstance(item, ContextItem) for item in items):
294
+ raise TypeError("ContextContributor must return a list of ContextItem values")
295
+
296
+ capabilities = contributor.capabilities
297
+ if capabilities.max_tokens < 0:
298
+ raise ValueError("ContextContributor max_tokens cannot be negative")
299
+ if capabilities.timeout_ms <= 0:
300
+ raise ValueError("ContextContributor timeout_ms must be positive")
301
+
302
+ admitted: list[ContextItem] = []
303
+ seen_ids: set[str] = set()
304
+ used_tokens = 0
305
+ omitted = 0
306
+ maximum_trust = _TRUST_RANK[capabilities.trust_level]
307
+ for item in items:
308
+ if not item.item_id or item.item_id in seen_ids:
309
+ raise ValueError("ContextContributor item ids must be non-empty and unique")
310
+ seen_ids.add(item.item_id)
311
+ if item.required:
312
+ raise ValueError("ContextContributor cannot mark context as required")
313
+ if _TRUST_RANK[item.trust_level] > maximum_trust:
314
+ raise ValueError(
315
+ "ContextContributor cannot elevate item trust above its registered level"
316
+ )
317
+ if item.estimated_tokens < 0:
318
+ raise ValueError("ContextContributor estimated_tokens cannot be negative")
319
+ if used_tokens + item.estimated_tokens > capabilities.max_tokens:
320
+ omitted += 1
321
+ continue
322
+ admitted.append(item)
323
+ used_tokens += item.estimated_tokens
324
+
325
+ warning = None
326
+ if omitted:
327
+ warning = (
328
+ f"{contributor.id()}: omitted {omitted} context item(s) that exceeded "
329
+ f"the {capabilities.max_tokens}-token contributor budget"
330
+ )
331
+ return admitted, warning
332
+
333
+
270
334
  async def run_contributors(
271
335
  contributors: Sequence[ContextContributor],
272
336
  request: ContextContributionRequest,
@@ -284,24 +348,25 @@ async def run_contributors(
284
348
  async def _run_one(c: ContextContributor) -> tuple[str, list[ContextItem], str, str | None]:
285
349
  timeout = max(c.capabilities.timeout_ms, 1) / 1000.0
286
350
  try:
287
- items = await asyncio.wait_for(c.contribute(request), timeout=timeout)
351
+ raw_items = await asyncio.wait_for(c.contribute(request), timeout=timeout)
352
+ items, budget_warning = _admit_contribution_items(c, raw_items)
288
353
  except asyncio.TimeoutError:
289
354
  return c.id(), [], "timeout", f"{c.id()}: timeout"
290
355
  except Exception as exc: # noqa: BLE001
291
356
  if c.capabilities.failure_mode == "fail":
292
357
  raise
293
- return c.id(), [], "error", f"{c.id()}: {exc}"
294
- # 单 Contributor 总 token 约束
295
- if items and sum(i.estimated_tokens for i in items) > c.capabilities.max_tokens:
296
- items = items[: c.capabilities.max_tokens] # best-effort 限条数
297
- return c.id(), items, "ok", None
358
+ warning = f"{c.id()}: {exc}" if c.capabilities.failure_mode == "warn" else None
359
+ return c.id(), [], "error", warning
360
+ return c.id(), items, "ok", budget_warning
298
361
 
299
362
  results = await asyncio.gather(*[_run_one(c) for c in contributors], return_exceptions=True)
300
363
  all_items: list[ContextItem] = []
301
364
  status: dict[str, str] = {}
302
365
  warnings: list[str] = []
303
366
  for contributor, r in zip(contributors, results):
304
- if isinstance(r, Exception):
367
+ if isinstance(r, BaseException):
368
+ if isinstance(r, asyncio.CancelledError):
369
+ raise r
305
370
  if contributor.capabilities.failure_mode == "fail":
306
371
  raise r
307
372
  warnings.append(f"{contributor.id()}: {r}")
@@ -11,6 +11,25 @@ def _exports(module: str, *names: str) -> dict[str, tuple[str, str]]:
11
11
 
12
12
 
13
13
  _EXPORTS = {
14
+ **_exports(
15
+ "ksadk.conversations.contracts",
16
+ "ConversationCapability",
17
+ "ConversationInput",
18
+ "ConversationAttachmentPart",
19
+ "ConversationItem",
20
+ "ConversationSurface",
21
+ "ConversationTextPart",
22
+ "validate_conversation_input",
23
+ "validate_surface_input",
24
+ ),
25
+ **_exports(
26
+ "ksadk.conversations.projector",
27
+ "project_conversation_item",
28
+ ),
29
+ **_exports(
30
+ "ksadk.conversations.reducer",
31
+ "ConversationItemReducer",
32
+ ),
14
33
  **_exports(
15
34
  "ksadk.conversations.attachments",
16
35
  "decode_inline_data",
@@ -5,6 +5,8 @@ import re
5
5
  from collections.abc import Mapping, Sequence
6
6
  from typing import Any, Dict, Iterable, List
7
7
 
8
+ from ksadk.events.canonical import ItemCompleted, parse_runtime_event
9
+ from ksadk.events.content import TextContent
8
10
  from ksadk.sessions.base import SessionEvent
9
11
  from ksadk.tools.result_budget import (
10
12
  ToolResultBudget,
@@ -99,6 +101,60 @@ def extract_event_text(event: SessionEvent) -> str:
99
101
  )
100
102
 
101
103
 
104
+ def _canonical_completed_message(
105
+ event: SessionEvent,
106
+ ) -> tuple[str, str, tuple[str, str]] | None:
107
+ """Return one canonical assistant message without flattening its identity.
108
+
109
+ Canonical RuntimeEvents are persisted inside the existing ``SessionEvent``
110
+ carrier. Legacy transcript projection only inspects carrier-level fields,
111
+ so an ``item.completed`` message otherwise disappears from the next turn's
112
+ history. The canonical event id and ``(scope_id, item_id)`` are both kept:
113
+ replays are idempotent, while equal text from different items remains
114
+ distinct.
115
+ """
116
+
117
+ raw = (event.content or {}).get("runtime_event")
118
+ if not isinstance(raw, Mapping):
119
+ return None
120
+ try:
121
+ canonical = parse_runtime_event(dict(raw))
122
+ except (TypeError, ValueError):
123
+ return None
124
+ if (
125
+ not isinstance(canonical, ItemCompleted)
126
+ or canonical.item_kind != "message"
127
+ or event.event_type != canonical.event_type
128
+ ):
129
+ return None
130
+ text = sanitize_event_text_for_context(
131
+ "".join(
132
+ part.text for part in canonical.snapshot.parts if isinstance(part, TextContent)
133
+ )
134
+ )
135
+ if not text:
136
+ return None
137
+ return canonical.event_id, text, (canonical.scope_id, canonical.item_id)
138
+
139
+
140
+ def _transcript_event_projection(
141
+ event: SessionEvent,
142
+ ) -> tuple[str, str, tuple[str, tuple[str, str]] | None]:
143
+ canonical_message = _canonical_completed_message(event)
144
+ if canonical_message is not None:
145
+ event_id, text, item_identity = canonical_message
146
+ return "assistant_message", text, (event_id, item_identity)
147
+ return (
148
+ canonical_event_type(
149
+ event.event_type,
150
+ author=event.author,
151
+ role=str((event.content or {}).get("role") or ""),
152
+ ),
153
+ extract_event_text(event),
154
+ None,
155
+ )
156
+
157
+
102
158
  def canonical_event_type(
103
159
  event_type: str | None,
104
160
  *,
@@ -276,6 +332,8 @@ def summarize_event_groups(
276
332
  因此跨消息提取修正,并在预算上限内保留最新长指令首尾(方案 §9.4)。
277
333
  """
278
334
  lines: List[str] = []
335
+ seen_canonical_event_ids: set[str] = set()
336
+ seen_canonical_items: set[tuple[str, str]] = set()
279
337
  if previous_summary:
280
338
  lines.append(previous_summary)
281
339
  lines.append("Earlier conversation summary:")
@@ -284,14 +342,18 @@ def summarize_event_groups(
284
342
  for group in groups:
285
343
  snippets: List[str] = []
286
344
  for event in group:
287
- event_type = canonical_event_type(
288
- event.event_type,
289
- author=event.author,
290
- role=str((event.content or {}).get("role") or ""),
291
- )
345
+ event_type, text, canonical_identity = _transcript_event_projection(event)
346
+ if canonical_identity is not None:
347
+ event_id, item_identity = canonical_identity
348
+ if (
349
+ event_id in seen_canonical_event_ids
350
+ or item_identity in seen_canonical_items
351
+ ):
352
+ continue
353
+ seen_canonical_event_ids.add(event_id)
354
+ seen_canonical_items.add(item_identity)
292
355
  if event_type not in TRANSCRIPT_EVENT_TYPES or event_type == "context_checkpoint":
293
356
  continue
294
- text = extract_event_text(event)
295
357
  if not text:
296
358
  continue
297
359
  if event_type in {"assistant_message", "tool_call"}:
@@ -343,6 +405,9 @@ def project_model_messages(
343
405
  """
344
406
  projected: List[Dict[str, str]] = []
345
407
  placeholder_flags: list[bool] = []
408
+ identity_boundary_flags: list[bool] = []
409
+ seen_canonical_event_ids: set[str] = set()
410
+ seen_canonical_items: set[tuple[str, str]] = set()
346
411
  compacted_until = compacted_until_seq_id(events)
347
412
  checkpoint = next(
348
413
  (
@@ -362,21 +427,26 @@ def project_model_messages(
362
427
  }
363
428
  )
364
429
  placeholder_flags.append(False)
430
+ identity_boundary_flags.append(False)
365
431
 
366
432
  for event in events:
367
- event_type = canonical_event_type(
368
- event.event_type,
369
- author=event.author,
370
- role=str((event.content or {}).get("role") or ""),
371
- )
433
+ event_type, text, canonical_identity = _transcript_event_projection(event)
372
434
  if event.seq_id <= compacted_until and event_type != "context_checkpoint":
373
435
  continue
374
436
  if event_type not in TRANSCRIPT_EVENT_TYPES:
375
437
  continue
376
438
  if event_type in {"context_checkpoint", "compaction_boundary"}:
377
439
  continue
440
+ if canonical_identity is not None:
441
+ event_id, item_identity = canonical_identity
442
+ if (
443
+ event_id in seen_canonical_event_ids
444
+ or item_identity in seen_canonical_items
445
+ ):
446
+ continue
447
+ seen_canonical_event_ids.add(event_id)
448
+ seen_canonical_items.add(item_identity)
378
449
 
379
- text = extract_event_text(event)
380
450
  if not text:
381
451
  continue
382
452
 
@@ -405,12 +475,15 @@ def project_model_messages(
405
475
  projected
406
476
  and projected[-1]["role"] == role
407
477
  and not placeholder_flags[-1]
478
+ and not identity_boundary_flags[-1]
408
479
  and not is_placeholder
480
+ and canonical_identity is None
409
481
  ):
410
482
  projected[-1]["content"] = f"{projected[-1]['content']}\n{text}".strip()
411
483
  else:
412
484
  projected.append({"role": role, "content": text})
413
485
  placeholder_flags.append(is_placeholder)
486
+ identity_boundary_flags.append(canonical_identity is not None)
414
487
 
415
488
  return projected
416
489
 
@@ -553,6 +626,8 @@ def project_responses_history(events: List[SessionEvent]) -> List[dict[str, Any]
553
626
  """
554
627
  projected: List[dict[str, Any]] = []
555
628
  projected_call_ids: set[str] = set()
629
+ seen_canonical_event_ids: set[str] = set()
630
+ seen_canonical_items: set[tuple[str, str]] = set()
556
631
  compacted_until = compacted_until_seq_id(events)
557
632
  checkpoint = next(
558
633
  (
@@ -568,17 +643,22 @@ def project_responses_history(events: List[SessionEvent]) -> List[dict[str, Any]
568
643
  projected.append(summary_message)
569
644
 
570
645
  for event in events:
571
- event_type = canonical_event_type(
572
- event.event_type,
573
- author=event.author,
574
- role=str((event.content or {}).get("role") or ""),
575
- )
646
+ event_type, text, canonical_identity = _transcript_event_projection(event)
576
647
  if event.seq_id <= compacted_until and event_type != "context_checkpoint":
577
648
  continue
578
649
  if event_type not in TRANSCRIPT_EVENT_TYPES:
579
650
  continue
580
651
  if event_type in {"context_checkpoint", "compaction_boundary"}:
581
652
  continue
653
+ if canonical_identity is not None:
654
+ event_id, item_identity = canonical_identity
655
+ if (
656
+ event_id in seen_canonical_event_ids
657
+ or item_identity in seen_canonical_items
658
+ ):
659
+ continue
660
+ seen_canonical_event_ids.add(event_id)
661
+ seen_canonical_items.add(item_identity)
582
662
 
583
663
  if event_type == "tool_call":
584
664
  item = _response_tool_call_item(event)
@@ -586,25 +666,25 @@ def project_responses_history(events: List[SessionEvent]) -> List[dict[str, Any]
586
666
  projected.append(item)
587
667
  projected_call_ids.add(str(item["call_id"]))
588
668
  continue
589
- message = _responses_message("assistant", f"[tool_call] {extract_event_text(event)}")
669
+ message = _responses_message("assistant", f"[tool_call] {text}")
590
670
  elif event_type == "tool_result":
591
671
  item = _response_tool_output_item(event)
592
672
  if item and str(item["call_id"]) in projected_call_ids:
593
673
  projected.append(item)
594
674
  continue
595
- message = _responses_message("user", f"[tool_result] {extract_event_text(event)}")
675
+ message = _responses_message("user", f"[tool_result] {text}")
596
676
  elif event_type == "assistant_message":
597
- message = _responses_message("assistant", extract_event_text(event))
677
+ message = _responses_message("assistant", text)
598
678
  elif event_type == "approval_request":
599
679
  message = _responses_message(
600
- "assistant", f"[approval_request] {extract_event_text(event)}"
680
+ "assistant", f"[approval_request] {text}"
601
681
  )
602
682
  elif event_type == "approval_response":
603
- message = _responses_message("user", f"[approval_response] {extract_event_text(event)}")
683
+ message = _responses_message("user", f"[approval_response] {text}")
604
684
  elif event_type == "attachment_ref":
605
- message = _responses_message("user", f"[attachment] {extract_event_text(event)}")
685
+ message = _responses_message("user", f"[attachment] {text}")
606
686
  else:
607
- message = _responses_message("user", extract_event_text(event))
687
+ message = _responses_message("user", text)
608
688
  if message:
609
689
  projected.append(message)
610
690