@code-yeongyu/senpi 2026.9.15-2 → 2026.9.16-2

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 (249) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +1 -1
  3. package/dist/core/agent-session.d.ts +28 -0
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +111 -13
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/compaction/compaction.d.ts.map +1 -1
  8. package/dist/core/compaction/compaction.js +4 -2
  9. package/dist/core/compaction/compaction.js.map +1 -1
  10. package/dist/core/compaction/stream-watchdog.d.ts +56 -2
  11. package/dist/core/compaction/stream-watchdog.d.ts.map +1 -1
  12. package/dist/core/compaction/stream-watchdog.js +93 -15
  13. package/dist/core/compaction/stream-watchdog.js.map +1 -1
  14. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.d.ts +6 -0
  15. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.d.ts.map +1 -1
  16. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js +17 -0
  17. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js.map +1 -1
  18. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts +4 -1
  19. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts.map +1 -1
  20. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js +31 -0
  21. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js.map +1 -1
  22. package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.d.ts +2 -0
  23. package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.d.ts.map +1 -1
  24. package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js +16 -0
  25. package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js.map +1 -1
  26. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.d.ts.map +1 -1
  27. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.js +19 -8
  28. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.js.map +1 -1
  29. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.d.ts.map +1 -1
  30. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js +2 -1
  31. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js.map +1 -1
  32. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +13 -1
  33. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
  34. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +66 -2
  35. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
  36. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  37. package/dist/core/extensions/builtin/compaction/index.js +16 -10
  38. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  39. package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts.map +1 -1
  40. package/dist/core/extensions/builtin/compaction/speculative-summary.js +4 -2
  41. package/dist/core/extensions/builtin/compaction/speculative-summary.js.map +1 -1
  42. package/dist/core/extensions/builtin/compaction/speculative.d.ts +8 -1
  43. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  44. package/dist/core/extensions/builtin/compaction/speculative.js +31 -7
  45. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  46. package/dist/core/extensions/builtin/compaction/transient-failure.d.ts.map +1 -1
  47. package/dist/core/extensions/builtin/compaction/transient-failure.js +6 -3
  48. package/dist/core/extensions/builtin/compaction/transient-failure.js.map +1 -1
  49. package/dist/core/extensions/kernel-tools-context.d.ts +13 -0
  50. package/dist/core/extensions/kernel-tools-context.d.ts.map +1 -0
  51. package/dist/core/extensions/kernel-tools-context.js +3 -0
  52. package/dist/core/extensions/kernel-tools-context.js.map +1 -0
  53. package/dist/core/extensions/runner.d.ts +19 -0
  54. package/dist/core/extensions/runner.d.ts.map +1 -1
  55. package/dist/core/extensions/runner.js +103 -1
  56. package/dist/core/extensions/runner.js.map +1 -1
  57. package/dist/core/extensions/types.d.ts +21 -0
  58. package/dist/core/extensions/types.d.ts.map +1 -1
  59. package/dist/core/extensions/types.js.map +1 -1
  60. package/dist/core/keybindings.d.ts +5 -0
  61. package/dist/core/keybindings.d.ts.map +1 -1
  62. package/dist/core/keybindings.js +1 -0
  63. package/dist/core/keybindings.js.map +1 -1
  64. package/dist/core/retry-fallback/settings.d.ts +3 -0
  65. package/dist/core/retry-fallback/settings.d.ts.map +1 -1
  66. package/dist/core/retry-fallback/settings.js.map +1 -1
  67. package/dist/core/sdk.d.ts.map +1 -1
  68. package/dist/core/sdk.js +1 -0
  69. package/dist/core/sdk.js.map +1 -1
  70. package/dist/core/session-manager.d.ts +27 -1
  71. package/dist/core/session-manager.d.ts.map +1 -1
  72. package/dist/core/session-manager.js +78 -5
  73. package/dist/core/session-manager.js.map +1 -1
  74. package/dist/core/session-resident-store.d.ts +33 -7
  75. package/dist/core/session-resident-store.d.ts.map +1 -1
  76. package/dist/core/session-resident-store.js +163 -14
  77. package/dist/core/session-resident-store.js.map +1 -1
  78. package/dist/core/session-write-reservation.d.ts +6 -0
  79. package/dist/core/session-write-reservation.d.ts.map +1 -1
  80. package/dist/core/session-write-reservation.js +19 -0
  81. package/dist/core/session-write-reservation.js.map +1 -1
  82. package/dist/core/settings-manager.d.ts +35 -1
  83. package/dist/core/settings-manager.d.ts.map +1 -1
  84. package/dist/core/settings-manager.js +62 -0
  85. package/dist/core/settings-manager.js.map +1 -1
  86. package/dist/core/slash-commands.d.ts.map +1 -1
  87. package/dist/core/slash-commands.js +2 -1
  88. package/dist/core/slash-commands.js.map +1 -1
  89. package/dist/core/tools/index.d.ts +1 -1
  90. package/dist/core/tools/index.d.ts.map +1 -1
  91. package/dist/core/tools/index.js +4 -3
  92. package/dist/core/tools/index.js.map +1 -1
  93. package/dist/core/tools/read.d.ts +3 -1
  94. package/dist/core/tools/read.d.ts.map +1 -1
  95. package/dist/core/tools/read.js +16 -2
  96. package/dist/core/tools/read.js.map +1 -1
  97. package/dist/index.d.ts +1 -0
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +1 -0
  100. package/dist/index.js.map +1 -1
  101. package/dist/modes/interactive/components/assistant-render-descriptors.d.ts.map +1 -1
  102. package/dist/modes/interactive/components/assistant-render-descriptors.js +12 -5
  103. package/dist/modes/interactive/components/assistant-render-descriptors.js.map +1 -1
  104. package/dist/modes/interactive/components/extension-input.d.ts +2 -0
  105. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  106. package/dist/modes/interactive/components/extension-input.js +5 -0
  107. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  108. package/dist/modes/interactive/interactive-mode.d.ts +19 -2
  109. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  110. package/dist/modes/interactive/interactive-mode.js +66 -14
  111. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  112. package/dist/modes/interactive/tips/catalog/session-tips.js +1 -1
  113. package/dist/modes/interactive/tips/catalog/session-tips.js.map +1 -1
  114. package/dist/modes/interactive/working-status.d.ts +3 -2
  115. package/dist/modes/interactive/working-status.d.ts.map +1 -1
  116. package/dist/modes/interactive/working-status.js +17 -4
  117. package/dist/modes/interactive/working-status.js.map +1 -1
  118. package/dist/modes/print-mode.d.ts +1 -1
  119. package/dist/modes/print-mode.d.ts.map +1 -1
  120. package/dist/modes/print-mode.js +5 -1
  121. package/dist/modes/print-mode.js.map +1 -1
  122. package/docs/extensions.md +5 -2
  123. package/docs/keybindings.md +1 -0
  124. package/docs/session-format.md +1 -1
  125. package/docs/sessions.md +3 -3
  126. package/docs/settings.md +31 -1
  127. package/docs/usage.md +1 -1
  128. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +35 -0
  129. package/node_modules/@code-yeongyu/senpi-codemode/README.md +24 -0
  130. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  131. package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/http-server.ts +7 -1
  132. package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/kernel-tools-protocol.ts +85 -0
  133. package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/protocol.ts +6 -0
  134. package/node_modules/@code-yeongyu/senpi-codemode/src/bridges/agent-bridge.ts +30 -11
  135. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/session-manager.ts +11 -0
  136. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +10 -0
  137. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/jl/prelude.jl +46 -0
  138. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/jl/runner.jl +1 -1
  139. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +29 -0
  140. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-contract.ts +12 -0
  141. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-context.d.ts +13 -0
  142. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-context.js +7 -0
  143. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-define.d.ts +10 -0
  144. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-define.js +12 -0
  145. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-errors.js +22 -0
  146. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-errors.ts +26 -0
  147. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-host.ts +134 -0
  148. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-naming.js +28 -0
  149. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-parse.d.ts +5 -0
  150. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-parse.js +255 -0
  151. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-pump.js +105 -0
  152. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-registry.d.ts +27 -0
  153. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-registry.js +127 -0
  154. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-schema.js +69 -0
  155. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-types.ts +42 -0
  156. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/prelude.ts +2 -0
  157. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-core.js +26 -3
  158. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-runtime.js +20 -8
  159. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-slot.ts +6 -1
  160. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-startup.ts +9 -7
  161. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/workpool.js +37 -0
  162. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/kernel-tools-unavailable.ts +5 -0
  163. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel.ts +13 -0
  164. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/prelude.py +57 -3
  165. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/rb/prelude.rb +13 -2
  166. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/rb/workpool.rb +38 -0
  167. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-kernel.ts +13 -0
  168. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-queue.ts +2 -0
  169. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt-template.ts +4 -2
  170. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-handler.ts +31 -3
  171. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/run-eval-cell.ts +52 -30
  172. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +2 -0
  173. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  174. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +30 -3
  175. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  176. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts +5 -0
  177. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
  178. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +2 -0
  179. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
  180. package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.d.ts.map +1 -1
  181. package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js +51 -12
  182. package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js.map +1 -1
  183. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/read.d.ts +3 -0
  184. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/read.d.ts.map +1 -1
  185. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/read.js +18 -3
  186. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/read.js.map +1 -1
  187. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/brace-scanner.d.ts +4 -0
  188. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/brace-scanner.d.ts.map +1 -0
  189. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/brace-scanner.js +268 -0
  190. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/brace-scanner.js.map +1 -0
  191. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/header-protection.d.ts +18 -0
  192. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/header-protection.d.ts.map +1 -0
  193. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/header-protection.js +69 -0
  194. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/header-protection.js.map +1 -0
  195. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/index.d.ts +27 -0
  196. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/index.d.ts.map +1 -0
  197. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/index.js +118 -0
  198. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/index.js.map +1 -0
  199. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-context.d.ts +21 -0
  200. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-context.d.ts.map +1 -0
  201. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-context.js +24 -0
  202. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-context.js.map +1 -0
  203. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-spans.d.ts +12 -0
  204. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-spans.d.ts.map +1 -0
  205. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-spans.js +92 -0
  206. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-spans.js.map +1 -0
  207. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/types.d.ts +47 -0
  208. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/types.d.ts.map +1 -0
  209. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/types.js +8 -0
  210. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/types.js.map +1 -0
  211. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/segmented-read-view.d.ts +52 -0
  212. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/segmented-read-view.d.ts.map +1 -0
  213. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/segmented-read-view.js +155 -0
  214. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/segmented-read-view.js.map +1 -0
  215. package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts +4 -0
  216. package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts.map +1 -1
  217. package/node_modules/@earendil-works/pi-agent-core/dist/index.js +3 -0
  218. package/node_modules/@earendil-works/pi-agent-core/dist/index.js.map +1 -1
  219. package/node_modules/@earendil-works/pi-agent-core/dist/stream-throughput-watchdog.d.ts +101 -0
  220. package/node_modules/@earendil-works/pi-agent-core/dist/stream-throughput-watchdog.d.ts.map +1 -0
  221. package/node_modules/@earendil-works/pi-agent-core/dist/stream-throughput-watchdog.js +178 -0
  222. package/node_modules/@earendil-works/pi-agent-core/dist/stream-throughput-watchdog.js.map +1 -0
  223. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +9 -0
  224. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
  225. package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
  226. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  227. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +1 -0
  228. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
  229. package/node_modules/@earendil-works/pi-ai/dist/index.js +1 -0
  230. package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
  231. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  232. package/node_modules/@earendil-works/pi-ai/dist/providers/data/alibaba-token-plan.json +1 -1
  233. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  234. package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
  235. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  236. package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan.json +1 -1
  237. package/node_modules/@earendil-works/pi-ai/dist/utils/empty-response-errors.d.ts +15 -0
  238. package/node_modules/@earendil-works/pi-ai/dist/utils/empty-response-errors.d.ts.map +1 -0
  239. package/node_modules/@earendil-works/pi-ai/dist/utils/empty-response-errors.js +15 -0
  240. package/node_modules/@earendil-works/pi-ai/dist/utils/empty-response-errors.js.map +1 -0
  241. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts +24 -0
  242. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
  243. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +92 -0
  244. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
  245. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  246. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  247. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  248. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  249. package/package.json +7 -7
@@ -57,8 +57,10 @@ tool_schema(name?) → dict
57
57
  completion(prompt, model?="default", system?=None, schema?=None) → str | dict
58
58
  Oneshot, stateless. \`model\`: \`"smol"\` fast | \`"default"\` session | \`"slow"\` most capable. \`schema\` (JSON-Schema) → parsed structured output.
59
59
  {{#if spawns}}agent(prompt, agent?="{{spawnDefaultAgent}}", model?=None, label?=None, schema?=None, handle?=False) → str | dict
60
- Run a subagent → final output. \`agent\` picks a discovered agent. \`schema\` as in completion(). \`handle\` → workflow node { text, output, handle: \`agent://<id>\`, id, agent } (parsed under \`data\` with \`schema\`).
61
- {{/if}}parallel(thunks) → list
60
+ Run a subagent → final output. \`agent\` picks a discovered agent. \`schema\` as in completion(). \`handle\` → workflow node { text, output, handle: \`agent://<id>\`, id, run_epoch, agent } (parsed under \`data\` with \`schema\`).
61
+ {{/if}}workpool(agent, name, mode?) → { pool_id, push(items), close(), inspect(), cancel() }
62
+ Thin host-tool adapter; agent is a plain-data spec. The host owns scheduling and keyed yields; explicitly close for automatic aggregate delivery. Requires the host workpool tool; omitted mode uses its default.
63
+ parallel(thunks) → list
62
64
  Thunks through a bounded pool (as wide as a \`task\` batch), input order kept; a throwing thunk propagates.
63
65
  pipeline(items, ...stages) → list
64
66
  Map items through one-arg stages with a barrier between stages; each stage receives the previous stage's result.
@@ -1,4 +1,9 @@
1
- import { type AgentToolResult, type ExtensionContext, sanitizeTerminalLabel } from "@code-yeongyu/senpi";
1
+ import {
2
+ type AgentToolResult,
3
+ type ExtensionContext,
4
+ kernelToolsStorage,
5
+ sanitizeTerminalLabel,
6
+ } from "@code-yeongyu/senpi";
2
7
  import type { KernelToHostMessage } from "../bridge/protocol.ts";
3
8
  import { RESERVED_SCHEMA_TOOL } from "../bridge/reserved.ts";
4
9
  import type { AgentExecuteTool } from "../bridges/agent-bridge.ts";
@@ -8,6 +13,7 @@ import { appendSchemaHint } from "../bridges/schema-hint.ts";
8
13
  import type { CompletionRequest, CompletionResult } from "../completion/handler.ts";
9
14
  import { handleCompletionToolCall } from "../completion/tool-bridge.ts";
10
15
  import type { ResolvedCodemodeSettings } from "../config/settings.ts";
16
+ import type { KernelToolsCapability } from "../kernels/js/kernel-tools-types.ts";
11
17
  import {
12
18
  boundToolCallArgs,
13
19
  capCodePoints,
@@ -39,6 +45,8 @@ export interface CellBridgeRuntime {
39
45
  readonly ctx: ExtensionContext;
40
46
  readonly artifactPath?: string;
41
47
  readonly imageResizer?: EvalImageResizer;
48
+ /** This cell's live kernel-tool capability; only a JS kernel has one (#1754). */
49
+ readonly kernelTools?: KernelToolsCapability;
42
50
  }
43
51
 
44
52
  export class CellHandler {
@@ -81,7 +89,7 @@ export class CellHandler {
81
89
  this.#resultBuilder.display(message);
82
90
  return;
83
91
  case "tool-call": {
84
- const pending = this.#handleToolCall(message);
92
+ const pending = this.#dispatchToolCall(message);
85
93
  this.#state.pendingBridgeCalls.push(pending);
86
94
  await pending;
87
95
  return;
@@ -90,6 +98,8 @@ export class CellHandler {
90
98
  case "init-failed":
91
99
  case "result":
92
100
  case "closed":
101
+ case "kernel-tool-describe-reply":
102
+ case "kernel-tool-invoke-reply":
93
103
  return;
94
104
  default:
95
105
  throw new TypeError(`Unhandled kernel message: ${String(message)}`);
@@ -112,6 +122,19 @@ export class CellHandler {
112
122
  return this.#resultBuilder.liveResult();
113
123
  }
114
124
 
125
+ /**
126
+ * The worker's message loop fires outside the async context `run-eval-cell.ts` enters around the
127
+ * awaited run chain, so the capability has to be entered here — around the whole dispatch, including
128
+ * the reserved agent()/output() bridges where a host task tool resolves the parent's kernel tools —
129
+ * for exactly the duration of each host tool call this cell makes (#1754). Without a capability
130
+ * (py/rb/jl) the store stays empty and `ctx.kernelTools` remains undefined.
131
+ */
132
+ async #dispatchToolCall(message: Extract<KernelToHostMessage, { type: "tool-call" }>): Promise<void> {
133
+ const kernelTools = this.#runtime.kernelTools;
134
+ if (kernelTools === undefined) return await this.#handleToolCall(message);
135
+ return await kernelToolsStorage.run(kernelTools, async () => await this.#handleToolCall(message));
136
+ }
137
+
115
138
  async #handleToolCall(message: Extract<KernelToHostMessage, { type: "tool-call" }>): Promise<void> {
116
139
  const startedAt = Date.now();
117
140
  const metric = createToolCallMetric(message.toolName, startedAt);
@@ -223,7 +246,12 @@ export class CellHandler {
223
246
  type: "tool-reply",
224
247
  callId: message.callId,
225
248
  ok: false,
226
- error: { message: text },
249
+ error: {
250
+ message: text,
251
+ ...(error instanceof Error && "code" in error && typeof error.code === "string"
252
+ ? { code: error.code }
253
+ : {}),
254
+ },
227
255
  });
228
256
  }
229
257
  this.#resultBuilder.emitUpdate(false);
@@ -1,7 +1,8 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { join } from "node:path";
3
- import type { AgentToolResult, ExtensionContext } from "@code-yeongyu/senpi";
3
+ import { type AgentToolResult, type ExtensionContext, kernelToolsStorage } from "@code-yeongyu/senpi";
4
4
  import { DEFAULT_FOREGROUND_WINDOW_SECONDS, defaultCodemodeSettings } from "../config/settings.ts";
5
+ import type { KernelToolsCapability } from "../kernels/js/kernel-tools-types.ts";
5
6
  import { TIMEOUT_PAUSE_OP, TIMEOUT_RESUME_OP } from "../timeouts/bridge-timeout.ts";
6
7
  import { abortError, CellExecution, defaultTimeoutFactory } from "./cell-execution.ts";
7
8
  import { CellHandler, type CellState } from "./cell-handler.ts";
@@ -11,7 +12,7 @@ import { buildEvalExecutionEventPayload, type EvalExecutionSettleOutcome } from
11
12
  import { evalTimeoutBehavior } from "./eval-request.ts";
12
13
  import type { CreateEvalToolOptions, EvalCellInvocation } from "./eval-tool-options.ts";
13
14
  import { describeTimeoutState } from "./interrupt-note.ts";
14
- import type { EvalToolDetails } from "./types.ts";
15
+ import type { EvalKernel, EvalToolDetails } from "./types.ts";
15
16
 
16
17
  export async function runEvalCell(
17
18
  options: CreateEvalToolOptions,
@@ -166,34 +167,42 @@ async function executeCell(
166
167
  void pending.catch((error: unknown) => execution.cancel(error));
167
168
  }),
168
169
  );
169
- execution.setKernel(kernel);
170
- const activeHandler = new CellHandler(kernel, state, {
171
- executeTool: options.executeTool,
172
- ...(options.listTools === undefined ? {} : { listTools: options.listTools }),
173
- settings: options.settings ?? defaultCodemodeSettings,
174
- ...(options.complete === undefined ? {} : { complete: options.complete }),
175
- ctx: bridgeContext,
176
- ...(options.artifactsDir === undefined
177
- ? {}
178
- : { artifactPath: join(options.artifactsDir, `eval-${randomUUID()}.log`) }),
179
- ...(options.imageResizer === undefined ? {} : { imageResizer: options.imageResizer }),
180
- });
181
- handler = activeHandler;
182
- cellManager.markRunning(
183
- cell,
184
- kernel,
185
- () => activeHandler.liveResult(),
186
- (error) => execution.cancel(error),
187
- );
188
- // Includes a steer already queued at execute start or received while acquiring the kernel.
189
- onReady();
190
- if ("setContext" in options.kernelManager && typeof options.kernelManager.setContext === "function") {
191
- options.kernelManager.setContext(bridgeContext);
192
- }
193
- if (invocation.input.reset) await execution.wait(kernel.reset());
194
- const result = await execution.wait(kernel.run({ cellId: invocation.cellId, code: invocation.input.code }));
195
- if (result.ok && state.pendingBridgeCalls.length > 0) await execution.wait(Promise.all(state.pendingBridgeCalls));
196
- return await handler.finalize(result);
170
+ // Computed before the handler so the cell's capability can be entered per host tool call from the
171
+ // worker's message loop, which runs outside the `kernelToolsStorage.run` context below (#1754).
172
+ const kernelTools = jsKernelTools(kernel, invocation.input.language);
173
+ const runBound = async (): Promise<AgentToolResult<EvalToolDetails>> => {
174
+ execution.setKernel(kernel);
175
+ const activeHandler = new CellHandler(kernel, state, {
176
+ executeTool: options.executeTool,
177
+ ...(options.listTools === undefined ? {} : { listTools: options.listTools }),
178
+ settings: options.settings ?? defaultCodemodeSettings,
179
+ ...(options.complete === undefined ? {} : { complete: options.complete }),
180
+ ctx: bridgeContext,
181
+ ...(options.artifactsDir === undefined
182
+ ? {}
183
+ : { artifactPath: join(options.artifactsDir, `eval-${randomUUID()}.log`) }),
184
+ ...(options.imageResizer === undefined ? {} : { imageResizer: options.imageResizer }),
185
+ ...(kernelTools === undefined ? {} : { kernelTools }),
186
+ });
187
+ handler = activeHandler;
188
+ cellManager.markRunning(
189
+ cell,
190
+ kernel,
191
+ () => activeHandler.liveResult(),
192
+ (error) => execution.cancel(error),
193
+ );
194
+ // Includes a steer already queued at execute start or received while acquiring the kernel.
195
+ onReady();
196
+ if ("setContext" in options.kernelManager && typeof options.kernelManager.setContext === "function") {
197
+ options.kernelManager.setContext(bridgeContext);
198
+ }
199
+ if (invocation.input.reset) await execution.wait(kernel.reset());
200
+ const result = await execution.wait(kernel.run({ cellId: invocation.cellId, code: invocation.input.code }));
201
+ if (result.ok && state.pendingBridgeCalls.length > 0)
202
+ await execution.wait(Promise.all(state.pendingBridgeCalls));
203
+ return await handler.finalize(result);
204
+ };
205
+ return kernelTools ? await kernelToolsStorage.run(kernelTools, runBound) : await runBound();
197
206
  } catch (error) {
198
207
  if (handler && error instanceof Error && error.name === "CodemodeSessionDisposedError")
199
208
  return await handler.finalizeCancellation(error);
@@ -206,3 +215,16 @@ async function executeCell(
206
215
  if (handler) await handler.flushOutput();
207
216
  }
208
217
  }
218
+
219
+ function jsKernelTools(kernel: EvalKernel, language: string): KernelToolsCapability | undefined {
220
+ if (language !== "js") return undefined;
221
+ if (!("describeKernelTools" in kernel) || typeof kernel.describeKernelTools !== "function") return undefined;
222
+ const js = kernel as EvalKernel & {
223
+ describeKernelTools: KernelToolsCapability["describe"];
224
+ invokeKernelTool: KernelToolsCapability["invoke"];
225
+ };
226
+ return {
227
+ describe: (names) => js.describeKernelTools(names),
228
+ invoke: (request, signal) => js.invokeKernelTool(request, signal),
229
+ };
230
+ }
@@ -132,6 +132,8 @@ export interface EvalKernel {
132
132
  deliverToolReply(message: Extract<HostToKernelMessage, { type: "tool-reply" }>): void;
133
133
  reset(): Promise<void>;
134
134
  close(): Promise<void>;
135
+ /** Names this kernel has registered; JS collides with other languages in the same session. */
136
+ listKernelToolNames?(): readonly string[];
135
137
  }
136
138
 
137
139
  export interface EvalKernelManager {
@@ -1 +1 @@
1
- {"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../src/agent-loop.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAIN,KAAK,OAAO,EAEZ,WAAW,EAIX,MAAM,uBAAuB,CAAC;AAW/B,OAAO,KAAK,EACX,YAAY,EACZ,UAAU,EACV,eAAe,EAEf,YAAY,EACZ,SAAS,EACT,aAAa,EAEb,QAAQ,EACR,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEzE;;;GAGG;AACH,wBAAgB,SAAS,CACxB,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,EAAE,QAAQ,GAChB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CAiBzC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,EAAE,QAAQ,GAChB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CAwBzC;AAED,wBAAsB,YAAY,CACjC,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,EAAE,QAAQ,GAChB,OAAO,CAAC,YAAY,EAAE,CAAC,CAgBzB;AAED,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,EAAE,QAAQ,GAChB,OAAO,CAAC,YAAY,EAAE,CAAC,CAiBzB;AAmBD,qBAAa,uBAAwB,SAAQ,KAAK;IACjD,YAAY,SAAS,EAAE,MAAM,EAK5B;CACD;AA2ND,uGAAuG;AACvG,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,cAAc,GAAG,kBAAkB,CAAC,EAClE,MAAM,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,OAAO,CAAC,CAIlB;AA+mBD,MAAM,WAAW,qBAAqB;IACrC,QAAQ,EAAE,aAAa,CAAC;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;CACd;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,GAAG,aAAa,CAYrG;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,GAAG,qBAAqB,CAOpG"}
1
+ {"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../src/agent-loop.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAIN,KAAK,OAAO,EAEZ,WAAW,EAIX,MAAM,uBAAuB,CAAC;AAgB/B,OAAO,KAAK,EACX,YAAY,EACZ,UAAU,EACV,eAAe,EAEf,YAAY,EACZ,SAAS,EACT,aAAa,EAEb,QAAQ,EACR,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEzE;;;GAGG;AACH,wBAAgB,SAAS,CACxB,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,EAAE,QAAQ,GAChB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CAiBzC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,EAAE,QAAQ,GAChB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CAwBzC;AAED,wBAAsB,YAAY,CACjC,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,EAAE,QAAQ,GAChB,OAAO,CAAC,YAAY,EAAE,CAAC,CAgBzB;AAED,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,EAAE,QAAQ,GAChB,OAAO,CAAC,YAAY,EAAE,CAAC,CAiBzB;AAmBD,qBAAa,uBAAwB,SAAQ,KAAK;IACjD,YAAY,SAAS,EAAE,MAAM,EAK5B;CACD;AA2ND,uGAAuG;AACvG,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,cAAc,GAAG,kBAAkB,CAAC,EAClE,MAAM,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,OAAO,CAAC,CAIlB;AA2oBD,MAAM,WAAW,qBAAqB;IACrC,QAAQ,EAAE,aAAa,CAAC;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;CACd;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,GAAG,aAAa,CAYrG;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,GAAG,qBAAqB,CAOpG"}
@@ -5,6 +5,7 @@
5
5
  import { EventStream, isCursorExecResolved, validateToolArguments, } from "@earendil-works/pi-ai";
6
6
  import { createTerminalFailureAssistantMessage, demoteToolUseWithoutToolCalls, isStreamIdleTimeoutError, normalizeTerminalAssistantMessage, promoteStopWithPendingToolCalls, shouldFinalizeIdleAsStop, shouldTerminateAssistantTurn, } from "./assistant-terminal-state.js";
7
7
  import { getDefaultStreamFn, withEmptyAssistantRecovery } from "./stream-fn.js";
8
+ import { createStreamThroughputWatchdog, estimateStreamedUnits, } from "./stream-throughput-watchdog.js";
8
9
  /**
9
10
  * Start an agent loop with a new prompt message.
10
11
  * The prompt is added to the context and events are emitted for it.
@@ -346,7 +347,7 @@ async function streamAssistantResponse(context, config, signal, emit, streamFunc
346
347
  : {}),
347
348
  });
348
349
  const iterator = response[Symbol.asyncIterator]();
349
- const eventReader = createAssistantEventReader(iterator, streamIdleTimeoutMs, requestAbortController.signal, (error) => requestAbortController.abort(error), config.streamStartTimeoutMs, response);
350
+ const eventReader = createAssistantEventReader(iterator, streamIdleTimeoutMs, requestAbortController.signal, (error) => requestAbortController.abort(error), config.streamStartTimeoutMs, response, createStreamThroughputWatchdog(config.streamThroughput));
350
351
  try {
351
352
  while (true) {
352
353
  const next = await eventReader.next();
@@ -496,7 +497,13 @@ function closeAssistantIterator(iterator) {
496
497
  function normalizeTimeoutMs(timeoutMs) {
497
498
  return typeof timeoutMs === "number" && Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : undefined;
498
499
  }
499
- function createAssistantEventReader(iterator, timeoutMs, signal, onIdleTimeout, streamStartTimeoutMs, stream) {
500
+ /** Streamed units carried by one assistant event; only text and thinking count. */
501
+ function streamedUnitsOf(event) {
502
+ if (event.type === "text_delta" || event.type === "thinking_delta")
503
+ return estimateStreamedUnits(event.delta);
504
+ return 0;
505
+ }
506
+ function createAssistantEventReader(iterator, timeoutMs, signal, onIdleTimeout, streamStartTimeoutMs, stream, throughput) {
500
507
  const idleTimeoutMs = normalizeTimeoutMs(timeoutMs);
501
508
  const startTimeoutMs = normalizeTimeoutMs(streamStartTimeoutMs);
502
509
  let sawFirstEvent = false;
@@ -527,9 +534,29 @@ function createAssistantEventReader(iterator, timeoutMs, signal, onIdleTimeout,
527
534
  const makeTimeoutError = useStartBound
528
535
  ? (ms) => new StreamStartTimeoutError(ms)
529
536
  : (ms) => new StreamIdleTimeoutError(ms);
537
+ // A provider executing a server-requested tool locally (Cursor's exec
538
+ // channel) is not streaming; that span must not count against the rate.
539
+ const localWorkPending = throughput !== undefined && stream?.hasPendingLocalWork?.() === true;
540
+ const waitStartedAt = localWorkPending ? Date.now() : 0;
530
541
  const result = await readNextAssistantEvent(iterator, readTimeoutMs, makeTimeoutError, abortPromise, onIdleTimeout, stream, signal);
531
- if (!result.done)
542
+ if (localWorkPending)
543
+ throughput?.exclude(Date.now() - waitStartedAt);
544
+ if (!result.done) {
532
545
  sawFirstEvent = true;
546
+ if (throughput !== undefined) {
547
+ // The rate clock starts at the first event, exactly where the
548
+ // stream-start bound stops applying.
549
+ throughput.start();
550
+ const degraded = throughput.record(streamedUnitsOf(result.value));
551
+ if (degraded !== undefined) {
552
+ closeAssistantIterator(iterator);
553
+ // Abort before rejecting: the caller inspects the request signal's
554
+ // reason, and the crawling upstream must be torn down either way.
555
+ onIdleTimeout?.(degraded);
556
+ throw degraded;
557
+ }
558
+ }
559
+ }
533
560
  return result;
534
561
  },
535
562
  dispose: () => removeAbortListener?.(),