@code-yeongyu/senpi 2026.7.10 → 2026.7.11

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 (311) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +4 -2
  3. package/dist/core/extensions/builtin/bash-timeout/timeout.js +2 -2
  4. package/dist/core/extensions/builtin/bash-timeout/timeout.js.map +1 -1
  5. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  6. package/dist/core/extensions/builtin/compaction/index.js +10 -1
  7. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  8. package/dist/core/extensions/builtin/goal/store.d.ts.map +1 -1
  9. package/dist/core/extensions/builtin/goal/store.js +88 -3
  10. package/dist/core/extensions/builtin/goal/store.js.map +1 -1
  11. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts +3 -0
  12. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts.map +1 -0
  13. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +83 -0
  14. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -0
  15. package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
  16. package/dist/core/extensions/builtin/prompt-preset/presets.js +6 -0
  17. package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
  18. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
  19. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
  20. package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -0
  21. package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
  22. package/dist/core/extensions/builtin/terminal/notify.d.ts +3 -3
  23. package/dist/core/extensions/builtin/terminal/notify.d.ts.map +1 -1
  24. package/dist/core/extensions/builtin/terminal/notify.js +7 -4
  25. package/dist/core/extensions/builtin/terminal/notify.js.map +1 -1
  26. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts +5 -3
  27. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts.map +1 -1
  28. package/dist/core/extensions/builtin/terminal/runtime-session.js +32 -16
  29. package/dist/core/extensions/builtin/terminal/runtime-session.js.map +1 -1
  30. package/dist/core/extensions/builtin/terminal/tools/bash-output.d.ts +1 -1
  31. package/dist/core/extensions/builtin/terminal/tools/bash-output.d.ts.map +1 -1
  32. package/dist/core/extensions/builtin/terminal/tools/bash-output.js +10 -4
  33. package/dist/core/extensions/builtin/terminal/tools/bash-output.js.map +1 -1
  34. package/dist/core/extensions/builtin/todotools/tools/todowrite.d.ts.map +1 -1
  35. package/dist/core/extensions/builtin/todotools/tools/todowrite.js +5 -8
  36. package/dist/core/extensions/builtin/todotools/tools/todowrite.js.map +1 -1
  37. package/dist/core/extensions/runner.d.ts +1 -0
  38. package/dist/core/extensions/runner.d.ts.map +1 -1
  39. package/dist/core/extensions/runner.js +5 -0
  40. package/dist/core/extensions/runner.js.map +1 -1
  41. package/dist/core/extensions/types.d.ts +5 -8
  42. package/dist/core/extensions/types.d.ts.map +1 -1
  43. package/dist/core/extensions/types.js.map +1 -1
  44. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  45. package/dist/core/extensions/wrapper.js +22 -3
  46. package/dist/core/extensions/wrapper.js.map +1 -1
  47. package/dist/core/keybindings.d.ts +8 -3
  48. package/dist/core/keybindings.d.ts.map +1 -1
  49. package/dist/core/keybindings.js +7 -3
  50. package/dist/core/keybindings.js.map +1 -1
  51. package/dist/core/model-registry.d.ts +1 -6
  52. package/dist/core/model-registry.d.ts.map +1 -1
  53. package/dist/core/model-registry.js +19 -6
  54. package/dist/core/model-registry.js.map +1 -1
  55. package/dist/core/settings-manager.d.ts +4 -3
  56. package/dist/core/settings-manager.d.ts.map +1 -1
  57. package/dist/core/settings-manager.js +2 -1
  58. package/dist/core/settings-manager.js.map +1 -1
  59. package/dist/index.d.ts +1 -0
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +1 -0
  62. package/dist/index.js.map +1 -1
  63. package/dist/modes/interactive/components/custom-editor.js +1 -1
  64. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  65. package/dist/modes/interactive/components/login-dialog.d.ts +4 -0
  66. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  67. package/dist/modes/interactive/components/login-dialog.js +9 -2
  68. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  69. package/dist/modes/interactive/components/settings-selector.js +1 -1
  70. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  71. package/dist/modes/interactive/components/thinking-selector.js +1 -1
  72. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  73. package/dist/modes/interactive/components/tool-execution-fallback.d.ts +6 -0
  74. package/dist/modes/interactive/components/tool-execution-fallback.d.ts.map +1 -0
  75. package/dist/modes/interactive/components/tool-execution-fallback.js +40 -0
  76. package/dist/modes/interactive/components/tool-execution-fallback.js.map +1 -0
  77. package/dist/modes/interactive/components/tool-execution-images.d.ts +23 -0
  78. package/dist/modes/interactive/components/tool-execution-images.d.ts.map +1 -0
  79. package/dist/modes/interactive/components/tool-execution-images.js +104 -0
  80. package/dist/modes/interactive/components/tool-execution-images.js.map +1 -0
  81. package/dist/modes/interactive/components/tool-execution-renderer.d.ts +28 -0
  82. package/dist/modes/interactive/components/tool-execution-renderer.d.ts.map +1 -0
  83. package/dist/modes/interactive/components/tool-execution-renderer.js +135 -0
  84. package/dist/modes/interactive/components/tool-execution-renderer.js.map +1 -0
  85. package/dist/modes/interactive/components/tool-execution-types.d.ts +23 -0
  86. package/dist/modes/interactive/components/tool-execution-types.d.ts.map +1 -0
  87. package/dist/modes/interactive/components/tool-execution-types.js +2 -0
  88. package/dist/modes/interactive/components/tool-execution-types.js.map +1 -0
  89. package/dist/modes/interactive/components/tool-execution.d.ts +13 -39
  90. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  91. package/dist/modes/interactive/components/tool-execution.js +51 -294
  92. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  93. package/dist/modes/interactive/components/tool-renderer-boundary.d.ts +17 -0
  94. package/dist/modes/interactive/components/tool-renderer-boundary.d.ts.map +1 -0
  95. package/dist/modes/interactive/components/tool-renderer-boundary.js +75 -0
  96. package/dist/modes/interactive/components/tool-renderer-boundary.js.map +1 -0
  97. package/dist/modes/interactive/components/tree-selector.d.ts +5 -0
  98. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  99. package/dist/modes/interactive/components/tree-selector.js +50 -17
  100. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  101. package/dist/modes/interactive/interactive-mode.d.ts +1 -2
  102. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  103. package/dist/modes/interactive/interactive-mode.js +44 -40
  104. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  105. package/dist/modes/interactive/theme/dark.json +1 -0
  106. package/dist/modes/interactive/theme/light.json +1 -0
  107. package/dist/modes/interactive/theme/theme-schema.json +6 -2
  108. package/dist/modes/interactive/theme/theme.d.ts +3 -2
  109. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  110. package/dist/modes/interactive/theme/theme.js +11 -4
  111. package/dist/modes/interactive/theme/theme.js.map +1 -1
  112. package/dist/utils/clipboard-native.d.ts +1 -0
  113. package/dist/utils/clipboard-native.d.ts.map +1 -1
  114. package/dist/utils/clipboard-native.js.map +1 -1
  115. package/dist/utils/clipboard.d.ts +2 -0
  116. package/dist/utils/clipboard.d.ts.map +1 -1
  117. package/dist/utils/clipboard.js +13 -0
  118. package/dist/utils/clipboard.js.map +1 -1
  119. package/docs/custom-provider.md +4 -3
  120. package/docs/extensions.md +140 -1
  121. package/docs/keybindings.md +1 -0
  122. package/docs/models.md +45 -4
  123. package/docs/providers.md +3 -0
  124. package/docs/quickstart.md +1 -1
  125. package/docs/rpc.md +2 -2
  126. package/docs/sdk.md +1 -1
  127. package/docs/settings.md +3 -3
  128. package/docs/themes.md +5 -3
  129. package/docs/tui.md +1 -1
  130. package/docs/usage.md +2 -1
  131. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  132. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  133. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  134. package/examples/extensions/gondolin/package-lock.json +2 -2
  135. package/examples/extensions/gondolin/package.json +1 -1
  136. package/examples/extensions/sandbox/package-lock.json +2 -2
  137. package/examples/extensions/sandbox/package.json +1 -1
  138. package/examples/extensions/with-deps/package-lock.json +2 -2
  139. package/examples/extensions/with-deps/package.json +1 -1
  140. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +3 -0
  141. package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
  142. package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/protocol.ts +7 -7
  143. package/node_modules/@code-yeongyu/senpi-codemode/src/completion/tool-bridge.ts +3 -0
  144. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/session-manager.ts +69 -8
  145. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +39 -13
  146. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +191 -148
  147. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/inline-worker-entry.js +23 -0
  148. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/inline-worker.ts +4 -175
  149. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-contract.ts +38 -0
  150. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/run-queue.ts +82 -0
  151. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-core.js +7 -3
  152. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-host.ts +117 -0
  153. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel-contract.ts +32 -0
  154. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel.ts +231 -199
  155. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/process.ts +119 -0
  156. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/transport.ts +237 -0
  157. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-contract.ts +22 -0
  158. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-kernel.ts +214 -189
  159. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-process.ts +174 -0
  160. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-queue.ts +100 -0
  161. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-run.ts +98 -0
  162. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-handler.ts +205 -0
  163. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +208 -203
  164. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +215 -25
  165. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +1 -0
  166. package/node_modules/@earendil-works/pi-agent-core/README.md +1 -1
  167. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +2 -0
  168. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  169. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +4 -3
  170. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
  171. package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
  172. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  173. package/node_modules/@earendil-works/pi-ai/README.md +4 -2
  174. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  175. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +89 -40
  176. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  177. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.d.ts +1 -1
  178. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.d.ts.map +1 -1
  179. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js.map +1 -1
  180. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  181. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js +7 -7
  182. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js.map +1 -1
  183. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts +1 -1
  184. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
  185. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +10 -3
  186. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  187. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts +1 -1
  188. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  189. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +5 -1
  190. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  191. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts +3 -1
  192. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
  193. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +35 -4
  194. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
  195. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts +1 -1
  196. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
  197. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +7 -3
  198. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  199. package/node_modules/@earendil-works/pi-ai/dist/api/simple-options.d.ts.map +1 -1
  200. package/node_modules/@earendil-works/pi-ai/dist/api/simple-options.js +8 -3
  201. package/node_modules/@earendil-works/pi-ai/dist/api/simple-options.js.map +1 -1
  202. package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.d.ts.map +1 -1
  203. package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js +4 -3
  204. package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js.map +1 -1
  205. package/node_modules/@earendil-works/pi-ai/dist/compat.d.ts.map +1 -1
  206. package/node_modules/@earendil-works/pi-ai/dist/compat.js +2 -1
  207. package/node_modules/@earendil-works/pi-ai/dist/compat.js.map +1 -1
  208. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  209. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +483 -61
  210. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  211. package/node_modules/@earendil-works/pi-ai/dist/models.js +13 -4
  212. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  213. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
  214. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +5 -1
  215. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  216. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.d.ts +62 -5
  217. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.d.ts.map +1 -1
  218. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.js +32 -20
  219. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.js.map +1 -1
  220. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.d.ts +11 -1
  221. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.d.ts.map +1 -1
  222. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.js +6 -4
  223. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.js.map +1 -1
  224. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.d.ts +7 -8
  225. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.d.ts.map +1 -1
  226. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.js +20 -21
  227. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.js.map +1 -1
  228. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.d.ts +11 -1
  229. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.d.ts.map +1 -1
  230. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.js +6 -4
  231. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.js.map +1 -1
  232. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-auth.d.ts.map +1 -1
  233. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-auth.js +9 -6
  234. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-auth.js.map +1 -1
  235. package/node_modules/@earendil-works/pi-ai/dist/providers/deepseek.models.d.ts +2 -2
  236. package/node_modules/@earendil-works/pi-ai/dist/providers/deepseek.models.d.ts.map +1 -1
  237. package/node_modules/@earendil-works/pi-ai/dist/providers/deepseek.models.js +2 -2
  238. package/node_modules/@earendil-works/pi-ai/dist/providers/deepseek.models.js.map +1 -1
  239. package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.d.ts +2 -2
  240. package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.d.ts.map +1 -1
  241. package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.js +2 -2
  242. package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.js.map +1 -1
  243. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.d.ts +100 -2
  244. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.d.ts.map +1 -1
  245. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.js +64 -5
  246. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.js.map +1 -1
  247. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.d.ts +56 -0
  248. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.d.ts.map +1 -1
  249. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.js +20 -9
  250. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.js.map +1 -1
  251. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.d.ts +77 -8
  252. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.d.ts.map +1 -1
  253. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.js +37 -24
  254. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.js.map +1 -1
  255. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.d.ts +3 -3
  256. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.d.ts.map +1 -1
  257. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.js +3 -3
  258. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.js.map +1 -1
  259. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.d.ts +80 -4
  260. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.d.ts.map +1 -1
  261. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.js +64 -8
  262. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.js.map +1 -1
  263. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts +25 -22
  264. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts.map +1 -1
  265. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js +64 -79
  266. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js.map +1 -1
  267. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts +45 -1
  268. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts.map +1 -1
  269. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js +43 -7
  270. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js.map +1 -1
  271. package/node_modules/@earendil-works/pi-ai/dist/providers/zai-coding-cn.models.d.ts +1 -1
  272. package/node_modules/@earendil-works/pi-ai/dist/providers/zai-coding-cn.models.d.ts.map +1 -1
  273. package/node_modules/@earendil-works/pi-ai/dist/providers/zai-coding-cn.models.js +1 -1
  274. package/node_modules/@earendil-works/pi-ai/dist/providers/zai-coding-cn.models.js.map +1 -1
  275. package/node_modules/@earendil-works/pi-ai/dist/providers/zai.models.d.ts +1 -1
  276. package/node_modules/@earendil-works/pi-ai/dist/providers/zai.models.d.ts.map +1 -1
  277. package/node_modules/@earendil-works/pi-ai/dist/providers/zai.models.js +1 -1
  278. package/node_modules/@earendil-works/pi-ai/dist/providers/zai.models.js.map +1 -1
  279. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +30 -7
  280. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  281. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  282. package/node_modules/@earendil-works/pi-ai/dist/utils/deferred-tools.d.ts +9 -0
  283. package/node_modules/@earendil-works/pi-ai/dist/utils/deferred-tools.d.ts.map +1 -0
  284. package/node_modules/@earendil-works/pi-ai/dist/utils/deferred-tools.js +36 -0
  285. package/node_modules/@earendil-works/pi-ai/dist/utils/deferred-tools.js.map +1 -0
  286. package/node_modules/@earendil-works/pi-ai/dist/utils/estimate.d.ts +3 -3
  287. package/node_modules/@earendil-works/pi-ai/dist/utils/estimate.d.ts.map +1 -1
  288. package/node_modules/@earendil-works/pi-ai/dist/utils/estimate.js +35 -14
  289. package/node_modules/@earendil-works/pi-ai/dist/utils/estimate.js.map +1 -1
  290. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  291. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  292. package/node_modules/@earendil-works/pi-tui/dist/components/image.d.ts.map +1 -1
  293. package/node_modules/@earendil-works/pi-tui/dist/components/image.js +2 -1
  294. package/node_modules/@earendil-works/pi-tui/dist/components/image.js.map +1 -1
  295. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +2 -1
  296. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  297. package/node_modules/@earendil-works/pi-tui/dist/index.js +2 -1
  298. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  299. package/node_modules/@earendil-works/pi-tui/dist/keys.d.ts.map +1 -1
  300. package/node_modules/@earendil-works/pi-tui/dist/keys.js +6 -5
  301. package/node_modules/@earendil-works/pi-tui/dist/keys.js.map +1 -1
  302. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts +0 -1
  303. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts.map +1 -1
  304. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js +0 -9
  305. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js.map +1 -1
  306. package/node_modules/@earendil-works/pi-tui/dist/terminal-text.d.ts +4 -0
  307. package/node_modules/@earendil-works/pi-tui/dist/terminal-text.d.ts.map +1 -0
  308. package/node_modules/@earendil-works/pi-tui/dist/terminal-text.js +18 -0
  309. package/node_modules/@earendil-works/pi-tui/dist/terminal-text.js.map +1 -0
  310. package/node_modules/@earendil-works/pi-tui/package.json +2 -2
  311. package/package.json +6 -6
@@ -1,15 +1,15 @@
1
1
  import type { AgentToolResult, AgentToolUpdateCallback, ExtensionContext, ToolDefinition } from "@code-yeongyu/senpi";
2
- import type { KernelToHostMessage } from "../bridge/protocol.ts";
2
+ import type { HostToKernelMessage, KernelToHostMessage } from "../bridge/protocol.ts";
3
3
  import type { CompletionRequest, CompletionResult } from "../completion/handler.ts";
4
- import { handleCompletionToolCall } from "../completion/tool-bridge.ts";
5
- import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, truncateTail } from "../host-sdk.ts";
6
4
  import { buildEvalPrompt } from "../prompt/eval-prompt.ts";
5
+ import { CellHandler, type CellState } from "./cell-handler.ts";
7
6
  import { renderEvalCall, renderEvalResult } from "./render.ts";
8
7
  import {
9
8
  createEvalInputSchema,
10
9
  type EnabledEvalLanguages,
11
10
  type EvalKernel,
12
11
  type EvalKernelManager,
12
+ type EvalKernelRunInput,
13
13
  type EvalToolDetails,
14
14
  type EvalToolInput,
15
15
  type ExecuteTool,
@@ -18,11 +18,6 @@ import {
18
18
 
19
19
  export type { EnabledEvalLanguages, EvalKernel, EvalKernelManager } from "./types.ts";
20
20
 
21
- type ImageContent = { type: "image"; mimeType: string; data: string };
22
- type ToolContent = AgentToolResult<unknown>["content"][number];
23
- type TextPart = Extract<ToolContent, { type: "text" }>;
24
- type RuntimeImagePart = { type: "image"; mimeType: string; data: string };
25
-
26
21
  export interface CreateEvalToolOptions {
27
22
  readonly enabledLanguages: EnabledEvalLanguages;
28
23
  readonly kernelManager: EvalKernelManager;
@@ -31,18 +26,142 @@ export interface CreateEvalToolOptions {
31
26
  readonly complete?: (request: CompletionRequest, ctx: ExtensionContext) => Promise<CompletionResult>;
32
27
  }
33
28
 
34
- interface CellState {
29
+ interface EvalCellInvocation {
35
30
  readonly cellId: string;
36
- readonly language: EvalToolInput["language"];
37
- readonly title: string | undefined;
31
+ readonly input: EvalToolInput;
38
32
  readonly signal: AbortSignal | undefined;
39
33
  readonly onUpdate: AgentToolUpdateCallback<EvalToolDetails> | undefined;
40
- readonly toolCalls: EvalToolDetails["toolCalls"] extends readonly (infer T)[] ? T[] : never;
41
- readonly images: ImageContent[];
42
- readonly pendingBridgeCalls: Promise<void>[];
43
- output: string;
44
- phase: string | undefined;
45
- durationMs: number;
34
+ readonly ctx: ExtensionContext;
35
+ }
36
+
37
+ type ToolReply = Extract<HostToKernelMessage, { type: "tool-reply" }>;
38
+
39
+ const INTERRUPT_DELIVERY_GRACE_MS = 100;
40
+
41
+ class CellKernel implements EvalKernel {
42
+ readonly #kernel: EvalKernel;
43
+ readonly #state: CellState;
44
+
45
+ constructor(kernel: EvalKernel, state: CellState) {
46
+ this.#kernel = kernel;
47
+ this.#state = state;
48
+ }
49
+
50
+ run(input: EvalKernelRunInput): Promise<Extract<KernelToHostMessage, { type: "result" }>> {
51
+ return this.#kernel.run(input);
52
+ }
53
+
54
+ deliverToolReply(message: ToolReply): void {
55
+ if (this.#state.active) this.#kernel.deliverToolReply(message);
56
+ }
57
+
58
+ interrupt(reason?: string): Promise<void> {
59
+ return this.#kernel.interrupt(reason);
60
+ }
61
+
62
+ reset(): Promise<void> {
63
+ return this.#kernel.reset();
64
+ }
65
+
66
+ close(): Promise<void> {
67
+ return this.#kernel.close();
68
+ }
69
+ }
70
+
71
+ class CellExecution {
72
+ readonly #callerSignal: AbortSignal | undefined;
73
+ readonly #timeoutMs: number;
74
+ readonly #onAbort: (error: Error) => void;
75
+ readonly #abortPromise: Promise<never>;
76
+ #rejectAbort: (reason?: unknown) => void = () => {};
77
+ #kernel: CellKernel | undefined;
78
+ #deadline: ReturnType<typeof setTimeout> | undefined;
79
+ #abortSettled = false;
80
+ #active = true;
81
+
82
+ constructor(callerSignal: AbortSignal | undefined, timeoutMs: number, onAbort: (error: Error) => void) {
83
+ this.#callerSignal = callerSignal;
84
+ this.#timeoutMs = timeoutMs;
85
+ this.#onAbort = onAbort;
86
+ this.#abortPromise = new Promise<never>((_resolve, reject) => {
87
+ this.#rejectAbort = reject;
88
+ });
89
+ callerSignal?.addEventListener("abort", this.#handleCallerAbort, { once: true });
90
+ this.startDeadline();
91
+ }
92
+
93
+ startDeadline(): void {
94
+ this.clearDeadline();
95
+ if (!this.#active) return;
96
+ this.#deadline = setTimeout(() => {
97
+ const error = new Error(`Cell timed out after ${this.#timeoutMs}ms`);
98
+ error.name = "TimeoutError";
99
+ this.#abort(error);
100
+ }, this.#timeoutMs);
101
+ }
102
+
103
+ clearDeadline(): void {
104
+ if (this.#deadline === undefined) return;
105
+ clearTimeout(this.#deadline);
106
+ this.#deadline = undefined;
107
+ }
108
+
109
+ setKernel(kernel: CellKernel): void {
110
+ this.#kernel = kernel;
111
+ }
112
+
113
+ cancel(reason: unknown): void {
114
+ this.#abort(reason);
115
+ }
116
+
117
+ async wait<T>(operation: Promise<T>): Promise<T> {
118
+ const guardedOperation = operation.then(
119
+ (value): T | Promise<never> => (this.#active ? value : this.#abortPromise),
120
+ (reason: unknown): Promise<never> => (this.#active ? Promise.reject(reason) : this.#abortPromise),
121
+ );
122
+ return await Promise.race([guardedOperation, this.#abortPromise]);
123
+ }
124
+
125
+ finish(): void {
126
+ this.#active = false;
127
+ this.#cleanup();
128
+ }
129
+
130
+ readonly #handleCallerAbort = (): void => {
131
+ this.#abort(this.#callerSignal?.reason);
132
+ };
133
+
134
+ #abort(reason: unknown): void {
135
+ if (!this.#active) return;
136
+ this.#active = false;
137
+ this.#cleanup();
138
+ const error = abortError(reason);
139
+ this.#onAbort(error);
140
+ const kernel = this.#kernel;
141
+ if (!kernel) {
142
+ this.#settleAbort(error);
143
+ return;
144
+ }
145
+ this.#deadline = setTimeout(() => this.#settleAbort(error), INTERRUPT_DELIVERY_GRACE_MS);
146
+ void Promise.resolve()
147
+ .then(() => kernel.interrupt(error.message))
148
+ .then(
149
+ () => this.#settleAbort(error),
150
+ (interruptError: unknown) => this.#settleAbort(interruptError),
151
+ );
152
+ }
153
+
154
+ #settleAbort(reason: unknown): void {
155
+ if (this.#abortSettled) return;
156
+ this.#abortSettled = true;
157
+ this.clearDeadline();
158
+ this.#rejectAbort(reason);
159
+ }
160
+
161
+ #cleanup(): void {
162
+ this.#callerSignal?.removeEventListener("abort", this.#handleCallerAbort);
163
+ this.clearDeadline();
164
+ }
46
165
  }
47
166
 
48
167
  export function createEvalTool(
@@ -58,6 +177,7 @@ export function createEvalTool(
58
177
  promptSnippet: prompt.promptSnippet,
59
178
  promptGuidelines: [...prompt.promptGuidelines],
60
179
  parameters,
180
+ executionMode: "sequential",
61
181
  renderCall: renderEvalCall,
62
182
  renderResult: renderEvalResult,
63
183
  async execute(toolCallId, params, signal, onUpdate, ctx) {
@@ -66,199 +186,84 @@ export function createEvalTool(
66
186
  `Unsupported eval language "${params.language}". Enabled languages: ${languages.join(", ")}`,
67
187
  );
68
188
  }
69
- const state: CellState = {
70
- cellId: toolCallId,
71
- language: params.language,
72
- title: params.title,
73
- signal,
74
- onUpdate,
75
- toolCalls: [],
76
- images: [],
77
- pendingBridgeCalls: [],
78
- output: "",
79
- phase: undefined,
80
- durationMs: 0,
81
- };
82
- // `kernel` is referenced by the onMessage closure below. Subprocess kernels
83
- // (py/rb/jl) emit their `ready` frame synchronously from within getKernel's
84
- // await, before the binding is assigned — a `const` here would be in the
85
- // temporal dead zone and throw. A pre-declared `let` yields `undefined` for
86
- // that pre-ready frame instead (which is a control message, never a tool-call,
87
- // so the kernel argument is unused for it).
88
- let kernel!: EvalKernel;
89
- kernel = await options.kernelManager.getKernel(
90
- params.language,
91
- (message) => void handleMessage(message, kernel, state, options.executeTool, options.complete, ctx),
92
- );
93
- if ("setContext" in options.kernelManager && typeof options.kernelManager.setContext === "function") {
94
- options.kernelManager.setContext(ctx);
95
- }
96
- if (params.reset) await kernel.reset();
97
- const timeoutMs = Math.floor((params.timeout ?? options.cellTimeoutSeconds) * 1000);
98
- const result = await kernel.run({ cellId: toolCallId, code: params.code, timeoutMs });
99
- await Promise.all(state.pendingBridgeCalls);
100
- return finalizeResult(result, state);
189
+ return await runEvalCell(options, { cellId: toolCallId, input: params, signal, onUpdate, ctx });
101
190
  },
102
191
  };
103
192
  }
104
193
 
105
- async function handleMessage(
106
- message: KernelToHostMessage,
107
- kernel: EvalKernel,
108
- state: CellState,
109
- executeTool: ExecuteTool,
110
- complete: CreateEvalToolOptions["complete"],
111
- ctx: ExtensionContext,
112
- ): Promise<void> {
113
- if (message.type === "text") {
114
- state.output += message.data;
115
- emitUpdate(state, false);
116
- return;
117
- }
118
- if (message.type === "phase") {
119
- state.phase = message.title;
120
- emitUpdate(state, false);
121
- return;
122
- }
123
- if (message.type === "log") {
124
- state.output += `${message.message}\n`;
125
- emitUpdate(state, false);
126
- return;
127
- }
128
- if (message.type === "display") {
129
- state.images.push({ type: "image", mimeType: message.mimeType, data: message.dataBase64 });
130
- state.output += `[display: ${message.mimeType}]\n`;
131
- emitUpdate(state, false);
132
- return;
133
- }
134
- if (message.type === "tool-call") {
135
- const pending = handleToolCall(message, kernel, state, executeTool, complete, ctx);
136
- state.pendingBridgeCalls.push(pending);
137
- await pending;
138
- }
139
- }
140
-
141
- async function handleToolCall(
142
- message: Extract<KernelToHostMessage, { type: "tool-call" }>,
143
- kernel: EvalKernel,
144
- state: CellState,
145
- executeTool: ExecuteTool,
146
- complete: CreateEvalToolOptions["complete"],
147
- ctx: ExtensionContext,
148
- ): Promise<void> {
149
- if (message.toolName === "eval") {
150
- const error = "recursive eval is not allowed";
151
- state.toolCalls.push({ name: message.toolName, ok: false, error });
152
- kernel.deliverToolReply({ type: "tool-reply", callId: message.callId, ok: false, error: { message: error } });
153
- return;
154
- }
155
- if (message.toolName === "completion" && complete) {
156
- const result = await handleCompletionToolCall({ message, kernel, complete, ctx });
157
- state.toolCalls.push(
158
- result.ok ? { name: message.toolName, ok: true } : { name: message.toolName, ok: false, error: result.error },
159
- );
160
- emitUpdate(state, false);
161
- return;
162
- }
194
+ async function runEvalCell(
195
+ options: CreateEvalToolOptions,
196
+ invocation: EvalCellInvocation,
197
+ ): Promise<AgentToolResult<EvalToolDetails>> {
198
+ if (invocation.signal?.aborted) throw abortError(invocation.signal.reason);
199
+ const timeoutMs = Math.floor((invocation.input.timeout ?? options.cellTimeoutSeconds) * 1000);
200
+ const bridgeAbortController = new AbortController();
201
+ const cellSignal = invocation.signal
202
+ ? AbortSignal.any([invocation.signal, bridgeAbortController.signal])
203
+ : bridgeAbortController.signal;
204
+ const bridgeContext: ExtensionContext = { ...invocation.ctx, signal: cellSignal };
205
+ const state: CellState = {
206
+ cellId: invocation.cellId,
207
+ language: invocation.input.language,
208
+ title: invocation.input.title,
209
+ signal: cellSignal,
210
+ onUpdate: invocation.onUpdate,
211
+ toolCalls: [],
212
+ images: [],
213
+ pendingBridgeCalls: [],
214
+ active: true,
215
+ output: "",
216
+ phase: undefined,
217
+ durationMs: 0,
218
+ };
219
+ const execution = new CellExecution(invocation.signal, timeoutMs, (error) => {
220
+ state.active = false;
221
+ bridgeAbortController.abort(error);
222
+ });
223
+ let handler: CellHandler | undefined;
163
224
  try {
164
- const result = await executeTool(message.toolName, message.args, { signal: state.signal });
165
- state.toolCalls.push({ name: message.toolName, ok: !toolResultIsError(result) });
166
- kernel.deliverToolReply({
167
- type: "tool-reply",
168
- callId: message.callId,
169
- ok: true,
170
- value: marshalToolResult(result),
171
- });
172
- } catch (error) {
173
- const messageText = errorMessage(error);
174
- state.toolCalls.push({ name: message.toolName, ok: false, error: messageText });
175
- kernel.deliverToolReply({
176
- type: "tool-reply",
177
- callId: message.callId,
178
- ok: false,
179
- error: { message: messageText },
225
+ const acquired = await execution.wait(
226
+ options.kernelManager.getKernel(invocation.input.language, (message) => {
227
+ if (!state.active || !handler) return;
228
+ const pending = handler.handle(message);
229
+ void pending.catch((error: unknown) => execution.cancel(error));
230
+ }),
231
+ );
232
+ const kernel = new CellKernel(acquired, state);
233
+ execution.setKernel(kernel);
234
+ execution.clearDeadline();
235
+ handler = new CellHandler(kernel, state, {
236
+ executeTool: options.executeTool,
237
+ complete: options.complete,
238
+ ctx: bridgeContext,
180
239
  });
240
+ if ("setContext" in options.kernelManager && typeof options.kernelManager.setContext === "function") {
241
+ options.kernelManager.setContext(bridgeContext);
242
+ }
243
+ if (invocation.input.reset) {
244
+ execution.startDeadline();
245
+ await execution.wait(kernel.reset());
246
+ execution.clearDeadline();
247
+ }
248
+ const result = await execution.wait(
249
+ kernel.run({ cellId: invocation.cellId, code: invocation.input.code, timeoutMs }),
250
+ );
251
+ if (result.ok && state.pendingBridgeCalls.length > 0) {
252
+ execution.startDeadline();
253
+ await execution.wait(Promise.all(state.pendingBridgeCalls));
254
+ execution.clearDeadline();
255
+ }
256
+ return handler.finalize(result);
257
+ } finally {
258
+ state.active = false;
259
+ bridgeAbortController.abort();
260
+ execution.finish();
181
261
  }
182
- emitUpdate(state, false);
183
- }
184
-
185
- function marshalToolResult(result: AgentToolResult<unknown>): unknown {
186
- const texts: string[] = [];
187
- const images: Array<{ mimeType: string; dataBase64: string }> = [];
188
- for (const part of result.content) {
189
- if (isTextPart(part)) texts.push(part.text);
190
- if (isRuntimeImagePart(part)) images.push({ mimeType: part.mimeType, dataBase64: part.data });
191
- }
192
- const text = texts.join("\n");
193
- const details = isEmptyObject(result.details) ? undefined : result.details;
194
- const hasError = toolResultIsError(result);
195
- if (images.length === 0 && details === undefined && !hasError) return { text };
196
- return { text, details, images, hasError };
197
- }
198
-
199
- function finalizeResult(
200
- result: Extract<KernelToHostMessage, { type: "result" }>,
201
- state: CellState,
202
- ): AgentToolResult<EvalToolDetails> {
203
- state.durationMs = result.durationMs;
204
- if (result.ok && result.valueRepr) state.output += `${result.valueRepr}\n`;
205
- if (!result.ok) state.output += `${result.error.message}\n`;
206
- const truncation = truncateTail(state.output, { maxBytes: DEFAULT_MAX_BYTES, maxLines: DEFAULT_MAX_LINES });
207
- const suffix = truncation.truncated
208
- ? `\n\n[Output truncated: ${truncation.outputLines} of ${truncation.totalLines} lines (${truncation.outputBytes} of ${truncation.totalBytes} bytes).]`
209
- : "";
210
- const details = detailsFor(state, truncation.truncated, !result.ok);
211
- return {
212
- content: [{ type: "text", text: `${truncation.content}${suffix}` }, ...state.images],
213
- details,
214
- };
215
- }
216
-
217
- function detailsFor(state: CellState, truncated: boolean, isError: boolean): EvalToolDetails {
218
- return {
219
- language: state.language,
220
- title: state.title,
221
- durationMs: state.durationMs,
222
- toolCalls: state.toolCalls,
223
- truncated,
224
- isError,
225
- phase: state.phase,
226
- };
227
- }
228
-
229
- function emitUpdate(state: CellState, isError: boolean): void {
230
- state.onUpdate?.({
231
- content: [{ type: "text", text: state.output }],
232
- details: detailsFor(state, false, isError),
233
- });
234
- }
235
-
236
- function errorMessage(error: unknown): string {
237
- return error instanceof Error ? error.message : String(error);
238
- }
239
-
240
- function isEmptyObject(value: unknown): boolean {
241
- return typeof value === "object" && value !== null && !Array.isArray(value) && Object.keys(value).length === 0;
242
- }
243
-
244
- function toolResultIsError(result: AgentToolResult<unknown>): boolean {
245
- const details = result.details;
246
- return typeof details === "object" && details !== null && "isError" in details && details.isError === true;
247
- }
248
-
249
- function isTextPart(part: ToolContent): part is TextPart {
250
- return part.type === "text";
251
262
  }
252
263
 
253
- function isRuntimeImagePart(part: unknown): part is RuntimeImagePart {
254
- return (
255
- typeof part === "object" &&
256
- part !== null &&
257
- "type" in part &&
258
- part.type === "image" &&
259
- "mimeType" in part &&
260
- typeof part.mimeType === "string" &&
261
- "data" in part &&
262
- typeof part.data === "string"
263
- );
264
+ function abortError(reason: unknown): Error {
265
+ if (reason instanceof Error && reason.name !== "AbortError") return reason;
266
+ const error = new Error(typeof reason === "string" ? reason : "Eval interrupted");
267
+ error.name = "AbortError";
268
+ return error;
264
269
  }