@code-yeongyu/senpi 2026.7.11 → 2026.7.14-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 (354) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/core/agent-session.d.ts +9 -0
  3. package/dist/core/agent-session.d.ts.map +1 -1
  4. package/dist/core/agent-session.js +56 -15
  5. package/dist/core/agent-session.js.map +1 -1
  6. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts.map +1 -1
  7. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +86 -26
  8. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
  9. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts +1 -1
  10. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts.map +1 -1
  11. package/dist/core/extensions/builtin/terminal/runtime-session.js +3 -2
  12. package/dist/core/extensions/builtin/terminal/runtime-session.js.map +1 -1
  13. package/dist/core/extensions/builtin/websearch/websearch/native.d.ts +1 -1
  14. package/dist/core/extensions/builtin/websearch/websearch/native.d.ts.map +1 -1
  15. package/dist/core/extensions/builtin/websearch/websearch/native.js +83 -33
  16. package/dist/core/extensions/builtin/websearch/websearch/native.js.map +1 -1
  17. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.d.ts.map +1 -1
  18. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.js +2 -1
  19. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.js.map +1 -1
  20. package/dist/core/extensions/builtin/websearch/websearch/tool.d.ts.map +1 -1
  21. package/dist/core/extensions/builtin/websearch/websearch/tool.js +3 -3
  22. package/dist/core/extensions/builtin/websearch/websearch/tool.js.map +1 -1
  23. package/dist/core/model-registry.d.ts.map +1 -1
  24. package/dist/core/model-registry.js +1 -0
  25. package/dist/core/model-registry.js.map +1 -1
  26. package/dist/core/resource-loader.d.ts +1 -0
  27. package/dist/core/resource-loader.d.ts.map +1 -1
  28. package/dist/core/resource-loader.js +20 -2
  29. package/dist/core/resource-loader.js.map +1 -1
  30. package/dist/modes/interactive/compaction-queue-transfer.d.ts +22 -0
  31. package/dist/modes/interactive/compaction-queue-transfer.d.ts.map +1 -0
  32. package/dist/modes/interactive/compaction-queue-transfer.js +82 -0
  33. package/dist/modes/interactive/compaction-queue-transfer.js.map +1 -0
  34. package/dist/modes/interactive/interactive-mode.d.ts +4 -0
  35. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  36. package/dist/modes/interactive/interactive-mode.js +83 -69
  37. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  38. package/node_modules/@babel/helper-string-parser/LICENSE +22 -0
  39. package/node_modules/@babel/helper-string-parser/README.md +19 -0
  40. package/node_modules/@babel/helper-string-parser/lib/index.js +295 -0
  41. package/node_modules/@babel/helper-string-parser/lib/index.js.map +1 -0
  42. package/node_modules/@babel/helper-string-parser/package.json +31 -0
  43. package/node_modules/@babel/helper-validator-identifier/LICENSE +22 -0
  44. package/node_modules/@babel/helper-validator-identifier/README.md +19 -0
  45. package/node_modules/@babel/helper-validator-identifier/lib/identifier.js +70 -0
  46. package/node_modules/@babel/helper-validator-identifier/lib/identifier.js.map +1 -0
  47. package/node_modules/@babel/helper-validator-identifier/lib/index.js +57 -0
  48. package/node_modules/@babel/helper-validator-identifier/lib/index.js.map +1 -0
  49. package/node_modules/@babel/helper-validator-identifier/lib/keyword.js +35 -0
  50. package/node_modules/@babel/helper-validator-identifier/lib/keyword.js.map +1 -0
  51. package/node_modules/@babel/helper-validator-identifier/package.json +31 -0
  52. package/node_modules/@babel/parser/LICENSE +19 -0
  53. package/node_modules/@babel/parser/README.md +19 -0
  54. package/node_modules/@babel/parser/bin/babel-parser.js +15 -0
  55. package/node_modules/@babel/parser/lib/index.js +14599 -0
  56. package/node_modules/@babel/parser/lib/index.js.map +1 -0
  57. package/node_modules/@babel/parser/package.json +50 -0
  58. package/node_modules/@babel/parser/typings/babel-parser.d.ts +262 -0
  59. package/node_modules/@babel/types/LICENSE +22 -0
  60. package/node_modules/@babel/types/README.md +19 -0
  61. package/node_modules/@babel/types/lib/asserts/assertNode.js +16 -0
  62. package/node_modules/@babel/types/lib/asserts/assertNode.js.map +1 -0
  63. package/node_modules/@babel/types/lib/asserts/generated/index.js +1251 -0
  64. package/node_modules/@babel/types/lib/asserts/generated/index.js.map +1 -0
  65. package/node_modules/@babel/types/lib/ast-types/generated/index.js +3 -0
  66. package/node_modules/@babel/types/lib/ast-types/generated/index.js.map +1 -0
  67. package/node_modules/@babel/types/lib/builders/flow/createFlowUnionType.js +18 -0
  68. package/node_modules/@babel/types/lib/builders/flow/createFlowUnionType.js.map +1 -0
  69. package/node_modules/@babel/types/lib/builders/flow/createTypeAnnotationBasedOnTypeof.js +31 -0
  70. package/node_modules/@babel/types/lib/builders/flow/createTypeAnnotationBasedOnTypeof.js.map +1 -0
  71. package/node_modules/@babel/types/lib/builders/generated/index.js +29 -0
  72. package/node_modules/@babel/types/lib/builders/generated/index.js.map +1 -0
  73. package/node_modules/@babel/types/lib/builders/generated/lowercase.js +2902 -0
  74. package/node_modules/@babel/types/lib/builders/generated/lowercase.js.map +1 -0
  75. package/node_modules/@babel/types/lib/builders/generated/uppercase.js +272 -0
  76. package/node_modules/@babel/types/lib/builders/generated/uppercase.js.map +1 -0
  77. package/node_modules/@babel/types/lib/builders/productions.js +12 -0
  78. package/node_modules/@babel/types/lib/builders/productions.js.map +1 -0
  79. package/node_modules/@babel/types/lib/builders/react/buildChildren.js +24 -0
  80. package/node_modules/@babel/types/lib/builders/react/buildChildren.js.map +1 -0
  81. package/node_modules/@babel/types/lib/builders/typescript/createTSUnionType.js +22 -0
  82. package/node_modules/@babel/types/lib/builders/typescript/createTSUnionType.js.map +1 -0
  83. package/node_modules/@babel/types/lib/builders/validateNode.js +21 -0
  84. package/node_modules/@babel/types/lib/builders/validateNode.js.map +1 -0
  85. package/node_modules/@babel/types/lib/clone/clone.js +12 -0
  86. package/node_modules/@babel/types/lib/clone/clone.js.map +1 -0
  87. package/node_modules/@babel/types/lib/clone/cloneDeep.js +12 -0
  88. package/node_modules/@babel/types/lib/clone/cloneDeep.js.map +1 -0
  89. package/node_modules/@babel/types/lib/clone/cloneDeepWithoutLoc.js +12 -0
  90. package/node_modules/@babel/types/lib/clone/cloneDeepWithoutLoc.js.map +1 -0
  91. package/node_modules/@babel/types/lib/clone/cloneNode.js +107 -0
  92. package/node_modules/@babel/types/lib/clone/cloneNode.js.map +1 -0
  93. package/node_modules/@babel/types/lib/clone/cloneWithoutLoc.js +12 -0
  94. package/node_modules/@babel/types/lib/clone/cloneWithoutLoc.js.map +1 -0
  95. package/node_modules/@babel/types/lib/comments/addComment.js +15 -0
  96. package/node_modules/@babel/types/lib/comments/addComment.js.map +1 -0
  97. package/node_modules/@babel/types/lib/comments/addComments.js +22 -0
  98. package/node_modules/@babel/types/lib/comments/addComments.js.map +1 -0
  99. package/node_modules/@babel/types/lib/comments/inheritInnerComments.js +12 -0
  100. package/node_modules/@babel/types/lib/comments/inheritInnerComments.js.map +1 -0
  101. package/node_modules/@babel/types/lib/comments/inheritLeadingComments.js +12 -0
  102. package/node_modules/@babel/types/lib/comments/inheritLeadingComments.js.map +1 -0
  103. package/node_modules/@babel/types/lib/comments/inheritTrailingComments.js +12 -0
  104. package/node_modules/@babel/types/lib/comments/inheritTrailingComments.js.map +1 -0
  105. package/node_modules/@babel/types/lib/comments/inheritsComments.js +17 -0
  106. package/node_modules/@babel/types/lib/comments/inheritsComments.js.map +1 -0
  107. package/node_modules/@babel/types/lib/comments/removeComments.js +15 -0
  108. package/node_modules/@babel/types/lib/comments/removeComments.js.map +1 -0
  109. package/node_modules/@babel/types/lib/constants/generated/index.js +60 -0
  110. package/node_modules/@babel/types/lib/constants/generated/index.js.map +1 -0
  111. package/node_modules/@babel/types/lib/constants/index.js +31 -0
  112. package/node_modules/@babel/types/lib/constants/index.js.map +1 -0
  113. package/node_modules/@babel/types/lib/converters/ensureBlock.js +14 -0
  114. package/node_modules/@babel/types/lib/converters/ensureBlock.js.map +1 -0
  115. package/node_modules/@babel/types/lib/converters/gatherSequenceExpressions.js +65 -0
  116. package/node_modules/@babel/types/lib/converters/gatherSequenceExpressions.js.map +1 -0
  117. package/node_modules/@babel/types/lib/converters/toBindingIdentifierName.js +14 -0
  118. package/node_modules/@babel/types/lib/converters/toBindingIdentifierName.js.map +1 -0
  119. package/node_modules/@babel/types/lib/converters/toBlock.js +29 -0
  120. package/node_modules/@babel/types/lib/converters/toBlock.js.map +1 -0
  121. package/node_modules/@babel/types/lib/converters/toComputedKey.js +14 -0
  122. package/node_modules/@babel/types/lib/converters/toComputedKey.js.map +1 -0
  123. package/node_modules/@babel/types/lib/converters/toExpression.js +28 -0
  124. package/node_modules/@babel/types/lib/converters/toExpression.js.map +1 -0
  125. package/node_modules/@babel/types/lib/converters/toIdentifier.js +25 -0
  126. package/node_modules/@babel/types/lib/converters/toIdentifier.js.map +1 -0
  127. package/node_modules/@babel/types/lib/converters/toKeyAlias.js +38 -0
  128. package/node_modules/@babel/types/lib/converters/toKeyAlias.js.map +1 -0
  129. package/node_modules/@babel/types/lib/converters/toSequenceExpression.js +19 -0
  130. package/node_modules/@babel/types/lib/converters/toSequenceExpression.js.map +1 -0
  131. package/node_modules/@babel/types/lib/converters/toStatement.js +39 -0
  132. package/node_modules/@babel/types/lib/converters/toStatement.js.map +1 -0
  133. package/node_modules/@babel/types/lib/converters/valueToNode.js +89 -0
  134. package/node_modules/@babel/types/lib/converters/valueToNode.js.map +1 -0
  135. package/node_modules/@babel/types/lib/definitions/core.js +1725 -0
  136. package/node_modules/@babel/types/lib/definitions/core.js.map +1 -0
  137. package/node_modules/@babel/types/lib/definitions/deprecated-aliases.js +11 -0
  138. package/node_modules/@babel/types/lib/definitions/deprecated-aliases.js.map +1 -0
  139. package/node_modules/@babel/types/lib/definitions/experimental.js +124 -0
  140. package/node_modules/@babel/types/lib/definitions/experimental.js.map +1 -0
  141. package/node_modules/@babel/types/lib/definitions/flow.js +495 -0
  142. package/node_modules/@babel/types/lib/definitions/flow.js.map +1 -0
  143. package/node_modules/@babel/types/lib/definitions/index.js +106 -0
  144. package/node_modules/@babel/types/lib/definitions/index.js.map +1 -0
  145. package/node_modules/@babel/types/lib/definitions/jsx.js +157 -0
  146. package/node_modules/@babel/types/lib/definitions/jsx.js.map +1 -0
  147. package/node_modules/@babel/types/lib/definitions/misc.js +31 -0
  148. package/node_modules/@babel/types/lib/definitions/misc.js.map +1 -0
  149. package/node_modules/@babel/types/lib/definitions/placeholders.js +27 -0
  150. package/node_modules/@babel/types/lib/definitions/placeholders.js.map +1 -0
  151. package/node_modules/@babel/types/lib/definitions/typescript.js +528 -0
  152. package/node_modules/@babel/types/lib/definitions/typescript.js.map +1 -0
  153. package/node_modules/@babel/types/lib/definitions/utils.js +296 -0
  154. package/node_modules/@babel/types/lib/definitions/utils.js.map +1 -0
  155. package/node_modules/@babel/types/lib/index-legacy.d.ts +2797 -0
  156. package/node_modules/@babel/types/lib/index.d.ts +3617 -0
  157. package/node_modules/@babel/types/lib/index.js +582 -0
  158. package/node_modules/@babel/types/lib/index.js.flow +2650 -0
  159. package/node_modules/@babel/types/lib/index.js.map +1 -0
  160. package/node_modules/@babel/types/lib/modifications/appendToMemberExpression.js +15 -0
  161. package/node_modules/@babel/types/lib/modifications/appendToMemberExpression.js.map +1 -0
  162. package/node_modules/@babel/types/lib/modifications/flow/removeTypeDuplicates.js +65 -0
  163. package/node_modules/@babel/types/lib/modifications/flow/removeTypeDuplicates.js.map +1 -0
  164. package/node_modules/@babel/types/lib/modifications/inherits.js +28 -0
  165. package/node_modules/@babel/types/lib/modifications/inherits.js.map +1 -0
  166. package/node_modules/@babel/types/lib/modifications/prependToMemberExpression.js +17 -0
  167. package/node_modules/@babel/types/lib/modifications/prependToMemberExpression.js.map +1 -0
  168. package/node_modules/@babel/types/lib/modifications/removeProperties.js +24 -0
  169. package/node_modules/@babel/types/lib/modifications/removeProperties.js.map +1 -0
  170. package/node_modules/@babel/types/lib/modifications/removePropertiesDeep.js +14 -0
  171. package/node_modules/@babel/types/lib/modifications/removePropertiesDeep.js.map +1 -0
  172. package/node_modules/@babel/types/lib/modifications/typescript/removeTypeDuplicates.js +66 -0
  173. package/node_modules/@babel/types/lib/modifications/typescript/removeTypeDuplicates.js.map +1 -0
  174. package/node_modules/@babel/types/lib/retrievers/getAssignmentIdentifiers.js +48 -0
  175. package/node_modules/@babel/types/lib/retrievers/getAssignmentIdentifiers.js.map +1 -0
  176. package/node_modules/@babel/types/lib/retrievers/getBindingIdentifiers.js +102 -0
  177. package/node_modules/@babel/types/lib/retrievers/getBindingIdentifiers.js.map +1 -0
  178. package/node_modules/@babel/types/lib/retrievers/getFunctionName.js +63 -0
  179. package/node_modules/@babel/types/lib/retrievers/getFunctionName.js.map +1 -0
  180. package/node_modules/@babel/types/lib/retrievers/getOuterBindingIdentifiers.js +13 -0
  181. package/node_modules/@babel/types/lib/retrievers/getOuterBindingIdentifiers.js.map +1 -0
  182. package/node_modules/@babel/types/lib/traverse/traverse.js +50 -0
  183. package/node_modules/@babel/types/lib/traverse/traverse.js.map +1 -0
  184. package/node_modules/@babel/types/lib/traverse/traverseFast.js +40 -0
  185. package/node_modules/@babel/types/lib/traverse/traverseFast.js.map +1 -0
  186. package/node_modules/@babel/types/lib/utils/deprecationWarning.js +44 -0
  187. package/node_modules/@babel/types/lib/utils/deprecationWarning.js.map +1 -0
  188. package/node_modules/@babel/types/lib/utils/inherit.js +13 -0
  189. package/node_modules/@babel/types/lib/utils/inherit.js.map +1 -0
  190. package/node_modules/@babel/types/lib/utils/react/cleanJSXElementLiteralChild.js +40 -0
  191. package/node_modules/@babel/types/lib/utils/react/cleanJSXElementLiteralChild.js.map +1 -0
  192. package/node_modules/@babel/types/lib/utils/shallowEqual.js +17 -0
  193. package/node_modules/@babel/types/lib/utils/shallowEqual.js.map +1 -0
  194. package/node_modules/@babel/types/lib/validators/buildMatchMemberExpression.js +13 -0
  195. package/node_modules/@babel/types/lib/validators/buildMatchMemberExpression.js.map +1 -0
  196. package/node_modules/@babel/types/lib/validators/generated/index.js +2797 -0
  197. package/node_modules/@babel/types/lib/validators/generated/index.js.map +1 -0
  198. package/node_modules/@babel/types/lib/validators/is.js +27 -0
  199. package/node_modules/@babel/types/lib/validators/is.js.map +1 -0
  200. package/node_modules/@babel/types/lib/validators/isBinding.js +27 -0
  201. package/node_modules/@babel/types/lib/validators/isBinding.js.map +1 -0
  202. package/node_modules/@babel/types/lib/validators/isBlockScoped.js +13 -0
  203. package/node_modules/@babel/types/lib/validators/isBlockScoped.js.map +1 -0
  204. package/node_modules/@babel/types/lib/validators/isImmutable.js +21 -0
  205. package/node_modules/@babel/types/lib/validators/isImmutable.js.map +1 -0
  206. package/node_modules/@babel/types/lib/validators/isLet.js +13 -0
  207. package/node_modules/@babel/types/lib/validators/isLet.js.map +1 -0
  208. package/node_modules/@babel/types/lib/validators/isNode.js +12 -0
  209. package/node_modules/@babel/types/lib/validators/isNode.js.map +1 -0
  210. package/node_modules/@babel/types/lib/validators/isNodesEquivalent.js +57 -0
  211. package/node_modules/@babel/types/lib/validators/isNodesEquivalent.js.map +1 -0
  212. package/node_modules/@babel/types/lib/validators/isPlaceholderType.js +15 -0
  213. package/node_modules/@babel/types/lib/validators/isPlaceholderType.js.map +1 -0
  214. package/node_modules/@babel/types/lib/validators/isReferenced.js +96 -0
  215. package/node_modules/@babel/types/lib/validators/isReferenced.js.map +1 -0
  216. package/node_modules/@babel/types/lib/validators/isScope.js +18 -0
  217. package/node_modules/@babel/types/lib/validators/isScope.js.map +1 -0
  218. package/node_modules/@babel/types/lib/validators/isSpecifierDefault.js +14 -0
  219. package/node_modules/@babel/types/lib/validators/isSpecifierDefault.js.map +1 -0
  220. package/node_modules/@babel/types/lib/validators/isType.js +17 -0
  221. package/node_modules/@babel/types/lib/validators/isType.js.map +1 -0
  222. package/node_modules/@babel/types/lib/validators/isValidES3Identifier.js +13 -0
  223. package/node_modules/@babel/types/lib/validators/isValidES3Identifier.js.map +1 -0
  224. package/node_modules/@babel/types/lib/validators/isValidIdentifier.js +18 -0
  225. package/node_modules/@babel/types/lib/validators/isValidIdentifier.js.map +1 -0
  226. package/node_modules/@babel/types/lib/validators/isVar.js +15 -0
  227. package/node_modules/@babel/types/lib/validators/isVar.js.map +1 -0
  228. package/node_modules/@babel/types/lib/validators/matchesPattern.js +44 -0
  229. package/node_modules/@babel/types/lib/validators/matchesPattern.js.map +1 -0
  230. package/node_modules/@babel/types/lib/validators/react/isCompatTag.js +11 -0
  231. package/node_modules/@babel/types/lib/validators/react/isCompatTag.js.map +1 -0
  232. package/node_modules/@babel/types/lib/validators/react/isReactComponent.js +11 -0
  233. package/node_modules/@babel/types/lib/validators/react/isReactComponent.js.map +1 -0
  234. package/node_modules/@babel/types/lib/validators/validate.js +42 -0
  235. package/node_modules/@babel/types/lib/validators/validate.js.map +1 -0
  236. package/node_modules/@babel/types/package.json +39 -0
  237. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +28 -2
  238. package/node_modules/@code-yeongyu/senpi-codemode/README.md +128 -78
  239. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -3
  240. package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/protocol.ts +15 -2
  241. package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/reserved.ts +9 -0
  242. package/node_modules/@code-yeongyu/senpi-codemode/src/bridges/agent-bridge.ts +197 -0
  243. package/node_modules/@code-yeongyu/senpi-codemode/src/bridges/output-bridge.ts +96 -0
  244. package/node_modules/@code-yeongyu/senpi-codemode/src/bridges/schema-injection.ts +3 -0
  245. package/node_modules/@code-yeongyu/senpi-codemode/src/completion/handler.ts +95 -26
  246. package/node_modules/@code-yeongyu/senpi-codemode/src/completion/tool-bridge.ts +11 -2
  247. package/node_modules/@code-yeongyu/senpi-codemode/src/config/settings.ts +96 -8
  248. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/session-manager.ts +24 -3
  249. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +155 -21
  250. package/node_modules/@code-yeongyu/senpi-codemode/src/interpreters/detect.ts +1 -1
  251. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/jl/prelude.jl +252 -48
  252. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/jl/runner.jl +263 -83
  253. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +11 -5
  254. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/local-module-loader.ts +108 -0
  255. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/prelude.ts +8 -6
  256. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/rewrite-imports.ts +164 -0
  257. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-core.js +6 -1
  258. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-runtime.js +307 -41
  259. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel.ts +3 -2
  260. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/prelude.py +792 -79
  261. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/rb/prelude.rb +234 -21
  262. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/rb/runner.rb +154 -51
  263. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-queue.ts +1 -0
  264. package/node_modules/@code-yeongyu/senpi-codemode/src/output/output-meta.ts +89 -0
  265. package/node_modules/@code-yeongyu/senpi-codemode/src/output/streaming-output.ts +296 -0
  266. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +101 -31
  267. package/node_modules/@code-yeongyu/senpi-codemode/src/timeouts/bridge-timeout.ts +2 -0
  268. package/node_modules/@code-yeongyu/senpi-codemode/src/timeouts/idle-timeout.ts +8 -19
  269. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-handler.ts +175 -113
  270. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +130 -120
  271. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/image.ts +274 -0
  272. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/json-tree.ts +247 -0
  273. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +641 -38
  274. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/status-events.ts +12 -0
  275. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +29 -1
  276. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  277. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  278. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +2 -23
  279. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  280. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +175 -158
  281. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  282. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.d.ts +60 -0
  283. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.d.ts.map +1 -1
  284. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.js +54 -0
  285. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.js.map +1 -1
  286. package/node_modules/@earendil-works/pi-ai/dist/providers/cerebras.models.js +1 -1
  287. package/node_modules/@earendil-works/pi-ai/dist/providers/cerebras.models.js.map +1 -1
  288. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.d.ts +92 -0
  289. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.d.ts.map +1 -1
  290. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.js +72 -0
  291. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.js.map +1 -1
  292. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts +23 -22
  293. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts.map +1 -1
  294. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js +63 -63
  295. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js.map +1 -1
  296. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts +0 -136
  297. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts.map +1 -1
  298. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js +6 -142
  299. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js.map +1 -1
  300. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/context-transformer.d.ts.map +1 -1
  301. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/context-transformer.js +9 -0
  302. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/context-transformer.js.map +1 -1
  303. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.d.ts +1 -1
  304. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.d.ts.map +1 -1
  305. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.js +6 -2
  306. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.js.map +1 -1
  307. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/coerce-parameters.d.ts +8 -0
  308. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/coerce-parameters.d.ts.map +1 -0
  309. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/coerce-parameters.js +92 -0
  310. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/coerce-parameters.js.map +1 -0
  311. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/format.d.ts +6 -0
  312. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/format.d.ts.map +1 -0
  313. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/format.js +54 -0
  314. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/format.js.map +1 -0
  315. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/index.d.ts +4 -0
  316. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/index.d.ts.map +1 -0
  317. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/index.js +4 -0
  318. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/index.js.map +1 -0
  319. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-match.d.ts +7 -0
  320. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-match.d.ts.map +1 -0
  321. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-match.js +16 -0
  322. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-match.js.map +1 -0
  323. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-tag-scanner.d.ts +19 -0
  324. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-tag-scanner.d.ts.map +1 -0
  325. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-tag-scanner.js +217 -0
  326. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-tag-scanner.js.map +1 -0
  327. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/parse.d.ts +4 -0
  328. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/parse.d.ts.map +1 -0
  329. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/parse.js +46 -0
  330. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/parse.js.map +1 -0
  331. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream-boundary.d.ts +13 -0
  332. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream-boundary.d.ts.map +1 -0
  333. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream-boundary.js +144 -0
  334. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream-boundary.js.map +1 -0
  335. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream.d.ts +5 -0
  336. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream.d.ts.map +1 -0
  337. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream.js +208 -0
  338. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream.js.map +1 -0
  339. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/tool-resolver.d.ts +4 -0
  340. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/tool-resolver.d.ts.map +1 -0
  341. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/tool-resolver.js +17 -0
  342. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/tool-resolver.js.map +1 -0
  343. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/xml-entities.d.ts +5 -0
  344. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/xml-entities.d.ts.map +1 -0
  345. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/xml-entities.js +34 -0
  346. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/xml-entities.js.map +1 -0
  347. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/types.d.ts +3 -1
  348. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/types.d.ts.map +1 -1
  349. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/types.js.map +1 -1
  350. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  351. package/node_modules/@earendil-works/pi-pty/native/prebuilds/darwin-arm64/senpi_pty.darwin-arm64.node +0 -0
  352. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  353. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  354. package/package.json +6 -6
@@ -0,0 +1,296 @@
1
+ import { createWriteStream, mkdirSync, type WriteStream } from "node:fs";
2
+ import { dirname } from "node:path";
3
+ import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, truncateTail } from "../host-sdk.ts";
4
+ import { formatMiddleElisionMarker } from "./output-meta.ts";
5
+
6
+ export { artifactNotice, formatMiddleElisionMarker, resolveSessionArtifactsDir } from "./output-meta.ts";
7
+ export { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, truncateTail };
8
+
9
+ export const ARTIFACT_DEFAULT_HEAD_BYTES = 3 * 1024 * 1024;
10
+
11
+ export interface OutputSummary {
12
+ readonly output: string;
13
+ readonly truncated: boolean;
14
+ readonly totalLines: number;
15
+ readonly totalBytes: number;
16
+ readonly outputLines: number;
17
+ readonly outputBytes: number;
18
+ readonly elidedBytes?: number;
19
+ readonly elidedLines?: number;
20
+ readonly columnDroppedBytes?: number;
21
+ readonly columnTruncatedLines?: number;
22
+ readonly artifactId?: string;
23
+ }
24
+
25
+ export interface OutputSinkOptions {
26
+ readonly artifactPath?: string;
27
+ readonly spillThreshold?: number;
28
+ readonly headBytes?: number;
29
+ readonly maxColumns?: number;
30
+ readonly onChunk?: (chunk: string) => void;
31
+ readonly chunkThrottleMs?: number;
32
+ }
33
+
34
+ interface ByteSlice {
35
+ readonly text: string;
36
+ readonly bytes: number;
37
+ }
38
+
39
+ function countNewlines(text: string): number {
40
+ let count = 0;
41
+ let cursor = text.indexOf("\n");
42
+ while (cursor !== -1) {
43
+ count++;
44
+ cursor = text.indexOf("\n", cursor + 1);
45
+ }
46
+ return count;
47
+ }
48
+
49
+ function lineCount(text: string): number {
50
+ return text.length === 0 ? 0 : countNewlines(text) + 1;
51
+ }
52
+
53
+ function truncateHeadBytes(text: string, maxBytes: number): ByteSlice {
54
+ if (maxBytes <= 0) return { text: "", bytes: 0 };
55
+ const buffer = Buffer.from(text, "utf8");
56
+ if (buffer.length <= maxBytes) return { text, bytes: buffer.length };
57
+ let end = maxBytes;
58
+ while (end > 0 && (buffer[end] & 0xc0) === 0x80) end--;
59
+ const slice = buffer.subarray(0, end);
60
+ return { text: slice.toString("utf8"), bytes: slice.length };
61
+ }
62
+
63
+ function truncateTailBytes(text: string, maxBytes: number): ByteSlice {
64
+ if (maxBytes <= 0) return { text: "", bytes: 0 };
65
+ const buffer = Buffer.from(text, "utf8");
66
+ if (buffer.length <= maxBytes) return { text, bytes: buffer.length };
67
+ let start = buffer.length - maxBytes;
68
+ while (start < buffer.length && (buffer[start] & 0xc0) === 0x80) start++;
69
+ const slice = buffer.subarray(start);
70
+ return { text: slice.toString("utf8"), bytes: slice.length };
71
+ }
72
+
73
+ export class TailBuffer {
74
+ readonly #maxBytes: number;
75
+ #text = "";
76
+ #bytes = 0;
77
+
78
+ constructor(maxBytes: number) {
79
+ this.#maxBytes = Math.max(0, Math.floor(maxBytes));
80
+ }
81
+
82
+ append(text: string): void {
83
+ if (text.length === 0) return;
84
+ if (this.#maxBytes === 0) {
85
+ this.#text = "";
86
+ this.#bytes = 0;
87
+ return;
88
+ }
89
+ const incomingBytes = Buffer.byteLength(text, "utf8");
90
+ const next =
91
+ incomingBytes >= this.#maxBytes
92
+ ? truncateTailBytes(text, this.#maxBytes)
93
+ : truncateTailBytes(this.#text + text, this.#maxBytes);
94
+ this.#text = next.text;
95
+ this.#bytes = next.bytes;
96
+ }
97
+
98
+ text(): string {
99
+ return this.#text;
100
+ }
101
+
102
+ bytes(): number {
103
+ return this.#bytes;
104
+ }
105
+ }
106
+
107
+ export class OutputSink {
108
+ readonly #artifactPath: string | undefined;
109
+ readonly #spillThreshold: number;
110
+ readonly #headLimit: number;
111
+ readonly #maxColumns: number;
112
+ readonly #onChunk: ((chunk: string) => void) | undefined;
113
+ readonly #chunkThrottleMs: number;
114
+ readonly #tail: TailBuffer;
115
+ #head = "";
116
+ #headBytes = 0;
117
+ #totalNewlines = 0;
118
+ #totalBytes = 0;
119
+ #sawData = false;
120
+ #truncated = false;
121
+ #currentLineBytes = 0;
122
+ #columnCapped = false;
123
+ #columnDroppedBytes = 0;
124
+ #columnTruncatedLines = 0;
125
+ #lastChunkTime = 0;
126
+ #pendingChunk = "";
127
+ #beforeSpill = "";
128
+ #file: WriteStream | undefined;
129
+ #fileError: Error | undefined;
130
+ #dumpPromise: Promise<OutputSummary> | undefined;
131
+
132
+ constructor(options: OutputSinkOptions = {}) {
133
+ this.#artifactPath = options.artifactPath;
134
+ this.#spillThreshold = Math.max(0, Math.floor(options.spillThreshold ?? DEFAULT_MAX_BYTES));
135
+ this.#headLimit = Math.max(0, Math.floor(options.headBytes ?? 0));
136
+ this.#maxColumns = Math.max(0, Math.floor(options.maxColumns ?? 0));
137
+ this.#onChunk = options.onChunk;
138
+ this.#chunkThrottleMs = Math.max(0, Math.floor(options.chunkThrottleMs ?? 0));
139
+ this.#tail = new TailBuffer(this.#spillThreshold);
140
+ }
141
+
142
+ push(chunk: string): void {
143
+ if (chunk.length === 0) return;
144
+ this.#emitPreview(chunk);
145
+ const rawBytes = Buffer.byteLength(chunk, "utf8");
146
+ this.#totalBytes += rawBytes;
147
+ this.#totalNewlines += countNewlines(chunk);
148
+ this.#sawData = true;
149
+ this.#mirrorRaw(chunk);
150
+ this.#retain(this.#maxColumns > 0 ? this.#clampColumns(chunk) : chunk);
151
+ }
152
+
153
+ dump(notice?: string): Promise<OutputSummary> {
154
+ this.#dumpPromise ??= this.#finishDump(notice);
155
+ return this.#dumpPromise;
156
+ }
157
+
158
+ #emitPreview(chunk: string): void {
159
+ if (this.#onChunk === undefined) return;
160
+ const now = Date.now();
161
+ if (now - this.#lastChunkTime >= this.#chunkThrottleMs) {
162
+ this.#lastChunkTime = now;
163
+ this.#onChunk(this.#pendingChunk + chunk);
164
+ this.#pendingChunk = "";
165
+ return;
166
+ }
167
+ this.#pendingChunk += chunk;
168
+ }
169
+
170
+ #mirrorRaw(chunk: string): void {
171
+ if (this.#artifactPath === undefined) return;
172
+ if (this.#file !== undefined) {
173
+ this.#file.write(chunk);
174
+ return;
175
+ }
176
+ if (this.#totalBytes <= this.#spillThreshold) {
177
+ this.#beforeSpill += chunk;
178
+ return;
179
+ }
180
+ mkdirSync(dirname(this.#artifactPath), { recursive: true });
181
+ const stream = createWriteStream(this.#artifactPath, { encoding: "utf8" });
182
+ stream.on("error", (error) => {
183
+ this.#fileError = error;
184
+ });
185
+ this.#file = stream;
186
+ if (this.#beforeSpill.length > 0) stream.write(this.#beforeSpill);
187
+ this.#beforeSpill = "";
188
+ stream.write(chunk);
189
+ }
190
+
191
+ #retain(text: string): void {
192
+ let tailText = text;
193
+ if (this.#headBytes < this.#headLimit) {
194
+ const head = truncateHeadBytes(text, this.#headLimit - this.#headBytes);
195
+ this.#head += head.text;
196
+ this.#headBytes += head.bytes;
197
+ tailText = text.substring(head.text.length);
198
+ }
199
+ this.#tail.append(tailText);
200
+ const effectiveBytes = this.#totalBytes - this.#columnDroppedBytes;
201
+ if (effectiveBytes > this.#headBytes + this.#tail.bytes()) this.#truncated = true;
202
+ }
203
+
204
+ #clampColumns(chunk: string): string {
205
+ const output: string[] = [];
206
+ let cursor = 0;
207
+ while (cursor < chunk.length) {
208
+ const newline = chunk.indexOf("\n", cursor);
209
+ const end = newline === -1 ? chunk.length : newline;
210
+ const segment = chunk.substring(cursor, end);
211
+ if (segment.length > 0) {
212
+ const segmentBytes = Buffer.byteLength(segment, "utf8");
213
+ if (this.#columnCapped) {
214
+ this.#columnDroppedBytes += segmentBytes;
215
+ } else {
216
+ const remaining = Math.max(0, this.#maxColumns - this.#currentLineBytes);
217
+ const kept = truncateHeadBytes(segment, remaining);
218
+ output.push(kept.text);
219
+ this.#currentLineBytes += kept.bytes;
220
+ if (kept.bytes < segmentBytes) {
221
+ output.push("…");
222
+ this.#columnDroppedBytes += segmentBytes - kept.bytes;
223
+ this.#columnTruncatedLines++;
224
+ this.#columnCapped = true;
225
+ this.#truncated = true;
226
+ }
227
+ }
228
+ }
229
+ if (newline === -1) break;
230
+ output.push("\n");
231
+ this.#currentLineBytes = 0;
232
+ this.#columnCapped = false;
233
+ cursor = newline + 1;
234
+ }
235
+ return output.join("");
236
+ }
237
+
238
+ async #finishDump(notice: string | undefined): Promise<OutputSummary> {
239
+ if (this.#onChunk !== undefined && this.#pendingChunk.length > 0) {
240
+ this.#onChunk(this.#pendingChunk);
241
+ this.#pendingChunk = "";
242
+ }
243
+ await this.#closeFile();
244
+ let tail = this.#tail.text();
245
+ if (lineCount(tail) > DEFAULT_MAX_LINES) {
246
+ tail = truncateTail(tail, { maxLines: DEFAULT_MAX_LINES, maxBytes: Number.MAX_SAFE_INTEGER }).content;
247
+ this.#truncated = true;
248
+ }
249
+ const totalLines = this.#sawData ? this.#totalNewlines + 1 : 0;
250
+ const tailBytes = Buffer.byteLength(tail, "utf8");
251
+ const effectiveBytes = Math.max(0, this.#totalBytes - this.#columnDroppedBytes);
252
+ let body = this.#head + tail;
253
+ let elidedBytes: number | undefined;
254
+ let elidedLines: number | undefined;
255
+ if (this.#headBytes > 0 && effectiveBytes > this.#headBytes + tailBytes) {
256
+ elidedBytes = effectiveBytes - this.#headBytes - tailBytes;
257
+ elidedLines = Math.max(0, totalLines - lineCount(this.#head) - lineCount(tail));
258
+ const headSeparator = this.#head.endsWith("\n") ? "" : "\n";
259
+ const tailSeparator = tail.length === 0 || tail.startsWith("\n") ? "" : "\n";
260
+ body = `${this.#head}${headSeparator}${formatMiddleElisionMarker(elidedLines, elidedBytes)}${tailSeparator}${tail}`;
261
+ this.#truncated = true;
262
+ }
263
+ return {
264
+ output: notice === undefined ? body : `[${notice}]\n${body}`,
265
+ truncated: this.#truncated,
266
+ totalLines,
267
+ totalBytes: this.#totalBytes,
268
+ outputLines: lineCount(body),
269
+ outputBytes: Buffer.byteLength(body, "utf8"),
270
+ elidedBytes,
271
+ elidedLines,
272
+ columnDroppedBytes: this.#columnDroppedBytes > 0 ? this.#columnDroppedBytes : undefined,
273
+ columnTruncatedLines: this.#columnTruncatedLines > 0 ? this.#columnTruncatedLines : undefined,
274
+ artifactId: this.#file === undefined ? undefined : this.#artifactPath,
275
+ };
276
+ }
277
+
278
+ async #closeFile(): Promise<void> {
279
+ const stream = this.#file;
280
+ if (stream === undefined) return;
281
+ if (this.#fileError !== undefined) throw this.#fileError;
282
+ await new Promise<void>((resolve, reject) => {
283
+ const onError = (error: Error) => {
284
+ stream.off("finish", onFinish);
285
+ reject(error);
286
+ };
287
+ const onFinish = () => {
288
+ stream.off("error", onError);
289
+ resolve();
290
+ };
291
+ stream.once("error", onError);
292
+ stream.once("finish", onFinish);
293
+ stream.end();
294
+ });
295
+ }
296
+ }
@@ -11,76 +11,146 @@ export interface EvalPromptParts {
11
11
  readonly promptGuidelines: readonly string[];
12
12
  }
13
13
 
14
+ export interface EvalPromptOptions {
15
+ readonly spawns: boolean;
16
+ readonly spawnDefaultAgent?: string;
17
+ }
18
+
14
19
  type ContextValue = string | boolean;
15
20
  type Context = Readonly<Record<string, ContextValue>>;
21
+ type EvalPromptExample = {
22
+ readonly caption: string;
23
+ readonly language: keyof EnabledLanguages;
24
+ readonly title: string;
25
+ readonly code: string;
26
+ };
27
+
28
+ // senpi ToolDefinition has no examples field, so description embeds the examples.
29
+ // ADAPTATION: payloads diverge from omp's json-config chain to teach batch read,
30
+ // comprehension filtering, and parallel tool.<name> fan-out while keeping the
31
+ // three-cell reuse narrative.
32
+ const REUSE_CHAIN_EXAMPLES = [
33
+ {
34
+ caption: "First call — set up once",
35
+ language: "py",
36
+ title: "collect targets",
37
+ code: "from pathlib import Path\nfrom collections import Counter\nfiles = [p for p in Path('src').rglob('*.ts') if 'test' not in p.parts]\nprint(len(files))",
38
+ },
39
+ {
40
+ caption: "Second call — reuse `files`, batch-read in one cell",
41
+ language: "py",
42
+ title: "scan usages",
43
+ code: "hits = Counter()\nfor p in files:\n hits[p.name] = read(p).count('legacyClient')\ndisplay({k: v for k, v in hits.items() if v})",
44
+ },
45
+ {
46
+ caption: "Third call — reuse results, fan out session tools in parallel",
47
+ language: "py",
48
+ title: "confirm callsites",
49
+ code: "dirs = ['src/core', 'src/tools']\ndisplay(parallel([lambda d=d: tool.grep({'pattern': 'legacyClient', 'path': d}) for d in dirs]))",
50
+ },
51
+ ] as const satisfies readonly EvalPromptExample[];
16
52
 
17
53
  const EVAL_PROMPT_TEMPLATE = `Run one step of code in a persistent kernel.
18
54
 
19
55
  <instruction>
20
- **One eval call = one cell = one logical step.** State persists per language across separate eval calls and tool calls — define helpers, datasets, and clients in one call, then later calls reuse them directly.
56
+ **One eval call = one cell = one logical step.** State persists per language across separate eval calls and tool calls{{#if spawns}}, and \`task\` subagents{{/if}} — define helpers, datasets, and clients in one call, then later calls reuse them directly.
57
+
58
+ Work incrementally: imports in one call, define in the next, test, then use — each its own eval call. Re-run setup ONLY after \`reset\`, a kernel crash, or a \`NameError\`/\`ReferenceError\` proving the state is gone.
21
59
 
22
- Work incrementally: imports in one call, define in the next, test, then use each its own eval call. Re-run setup ONLY after \`reset\`, a kernel crash, or a \`NameError\`/\`ReferenceError\` proving the state is gone. Parallelize work *within* a cell with the \`parallel(thunks)\` helper, not by batching steps.
60
+ **Batch through eval.** One cell replaces many one-shot tool calls: loop or comprehend over file sets with \`read()\`/stdlib instead of reading files one call at a time, post-process \`tool.<name>()\` results programmatically, and fan independent calls through \`parallel(thunks)\` within the cell never one call per turn.
23
61
 
24
62
  Fields:
25
63
 
26
64
  - \`language\` — {{#if py}}\`"py"\` IPython kernel{{/if}}{{#ifAll py js}}, {{/ifAll}}{{#if js}}\`"js"\` persistent JavaScript VM{{/if}}{{#if rb}}{{#ifAny py js}}, {{/ifAny}}\`"rb"\` persistent Ruby kernel{{/if}}{{#if jl}}{{#ifAny py js rb}}, {{/ifAny}}\`"jl"\` persistent Julia kernel{{/if}}.
27
65
  - \`code\` — cell body, verbatim. Newlines/quotes JSON-encoded; no fences, no headers.
28
66
  - \`title\` (optional) — short transcript label (e.g. \`"imports"\`).
29
- - \`timeout\` (optional) — seconds. Raise only for heavy compute or long delegated tool calls.
67
+ - \`timeout\` (optional) — seconds. Raise only for heavy compute or long{{#if spawns}} non-agent{{/if}} tool calls.
30
68
  - \`reset\` (optional) — wipe this language's kernel first.{{#ifAll py js}} Per-language: a \`py\` reset never touches the JS VM.{{/ifAll}}
31
69
 
32
- {{#if py}}Live event loop: use top-level \`await\` directly; \`asyncio.run(...)\` raises "cannot be called from a running event loop".{{/if}}
70
+ {{#if py}}Live event loop: use top-level \`await\` directly; \`asyncio.run()\` raises "cannot be called from a running event loop".{{/if}}
33
71
  {{#if js}}JS runs under Node.js worker: top-level \`await\`/\`return\` work; \`fetch\`/\`Buffer\` available.{{/if}}
34
- {{#if rb}}Ruby: synchronous; helper options are keyword args; the last expression auto-displays unless it is \`nil\`, an assignment, or a definition.{{/if}}
35
- {{#if jl}}Julia: synchronous; helper options are standard keyword args; the last expression auto-displays unless it is an assignment or a definition.{{/if}}
72
+ {{#if rb}}Ruby: synchronous; helper options are keyword args{{#if spawns}} (e.g. \`output("id", limit: 2)\`){{/if}}; the last expression auto-displays unless it is \`nil\`, an assignment, or a definition (like IRB).{{/if}}
73
+ {{#if jl}}Julia: synchronous; helper options are standard keyword args{{#if spawns}} (e.g. \`output("id", limit=2)\`){{/if}}; the last expression auto-displays unless it is an assignment or a definition (like the Julia REPL).{{/if}}
36
74
  On error, fix and re-run only the failing step — prior calls' state survives.
37
75
  </instruction>
38
76
 
39
77
  <prelude>
40
- {{#ifAll py js}}Same helpers + arg order, both runtimes. Python: sync, options = trailing kwargs. JS: async/\`await\`able, options = ONE trailing object literal, never positional.{{else}}{{#if py}}Sync; options = trailing kwargs.{{/if}}{{#if js}}Async/\`await\`able; options = ONE trailing object literal, never positional.{{/if}}{{/ifAll}}{{#if rb}} Ruby: sync, options = trailing keyword args.{{/if}}{{#if jl}} Julia: sync, options = trailing keyword args.{{/if}}
78
+ {{#ifAll py js}}Same helpers + arg order, both runtimes. Python: sync, options = trailing kwargs. JS: async/\`await\`able, options = ONE trailing object literal, never positional (extras throw).{{else}}{{#if py}}Sync; options = trailing kwargs.{{/if}}{{#if js}}Async/\`await\`able; options = ONE trailing object literal, never positional (extras throw).{{/if}}{{/ifAll}}{{#if rb}} Ruby: sync, options = trailing keyword args.{{/if}}{{#if jl}} Julia: sync, options = trailing keyword args.{{/if}}
41
79
  \`\`\`
42
- display(value) -> None
43
- Cell result; figures/images/dataframes shown natively.
44
- print(value, ...) -> None
45
- Text stream.
46
- read(path, offset?=1, limit?=None) -> str
47
- File as text; offset/limit are 1-indexed lines.
48
- write(path, content) -> str
49
- Write file, creating parents, and return the resolved path.
50
- env(key?=None, value?=None) -> str | None | dict
51
- No args -> full env dict; one -> value of key; two -> set key=value and return value.
52
- tool.<name>(args) -> unknown
53
- Invoke any active session tool; args = its parameter object.
54
- completion(prompt, model?="default", system?=None, schema?=None) -> str | dict
55
- Oneshot, stateless completion. model "default" uses the session model; schema is JSON Schema for structured results.
56
- parallel(thunks) -> list
57
- Thunks through a bounded pool, input order kept; returns when all finish, a throwing thunk propagates.
58
- pipeline(items, ...stages) -> list
80
+ display(value) None
81
+ Cell output; figures/images/dataframes shown natively.
82
+ print(value, ...) None
83
+ Text output.
84
+ read(path, offset?=1, limit?=None) str
85
+ File as text; offset/limit are 1-indexed lines. Accepts \`local://…\`.
86
+ write(path, content) str
87
+ Write file (creates parents) resolved path. \`local://…\` persists across turns/subagents.
88
+ env(key?=None, value?=None) str | None | dict
89
+ No args full env dict; one value of \`key\`; two set \`key=value\`, return value.
90
+ {{#if spawns}}output(*ids, format?="raw", offset?=None, limit?=None) str | dict | list[dict]
91
+ Task/agent output by id. \`format\` selects full (\`"raw"\`) or trailing (\`"tail"\`) output.
92
+ {{/if}}tool.<name>(args) unknown
93
+ Invoke any session tool; \`args\` = its parameter object.
94
+ completion(prompt, model?="default", system?=None, schema?=None) str | dict
95
+ Oneshot, stateless (no history/tools). \`model\`: \`"smol"\` fast | \`"default"\` session | \`"slow"\` most capable. \`schema\` (JSON-Schema) → structured output, parsed object.
96
+ {{#if spawns}}agent(prompt, agent?="{{spawnDefaultAgent}}", model?=None, label?=None, schema?=None, handle?=False) str | dict
97
+ Run a subagent → final output. \`agent\` picks another discovered agent; omit it to use \`{{spawnDefaultAgent}}\`. \`schema\` as in completion(). Background via \`local://\` files named in the prompt. \`handle\` → DAG node dict { text, output, handle: \`agent://<id>\`, id, agent } (parsed under \`data\` when \`schema\` set).
98
+ {{#if js}} JS: options are ONE trailing object — agent(prompt, { agent, schema, handle }).
99
+ {{/if}}{{/if}}parallel(thunks) → list
100
+ Thunks through a bounded pool (wide as a \`task\` batch — don't pre-shrink), input order kept; returns when all finish, a throwing thunk propagates.
101
+ pipeline(items, ...stages) → list
59
102
  Map items through one-arg stages left-to-right, barrier between stages; stage 1 gets the item, later stages the previous result.
60
- log(message) -> None
103
+ log(message) None
61
104
  Progress line above the status tree.
62
- phase(title) -> None
105
+ phase(title) None
63
106
  Phase grouping subsequent status lines.
64
107
  \`\`\`
65
108
  </prelude>
109
+ {{#if spawns}}
110
+ <dag>
111
+ Pipe handles through stage helpers to build a dependency graph — acyclic waves:
112
+ - **Name nodes.** Capture each \`agent(…, {{#if py}}handle=True{{/if}}{{#if js}}{ handle: true }{{/if}}{{#if jl}}handle=true{{/if}})\` result; carries \`handle\` (\`agent://<id>\`) + \`output\`.
113
+ - **Wire edges by reference.** Put an upstream node's \`handle\`/\`output\` in the dependent stage's prompt — large transcript never re-inlined. Bulk: \`write("local://<name>.md", …)\`, pass the URI.
114
+ - **\`pipeline(items, *stages)\` = staged waves**, barrier between stages (every item clears stage N before any enters N+1). **\`parallel(thunks)\` = one wave** of independent nodes.
115
+ - **Isolate failure.** A raising node re-raises the lowest-index error, aborts its wave; wrap risky nodes in try/except so a failure degrades only its dependent subtree, independent branches finish.
116
+ - **Acyclic only.** A node never waits on its own descendant.
117
+ </dag>
118
+ {{/if}}
66
119
 
67
120
  <critical>
68
- Prior top-level names survive into the next eval call — reuse them; NEVER re-import, re-require, or re-declare a helper. Re-read a file only if it may have changed since the last read. Re-run setup only after \`reset\`, a crash, or a \`NameError\`/\`ReferenceError\`.
121
+ Prior top-level names (\`data\`, \`sessions\`, helpers, imports) survive into the next eval call — reuse them; NEVER re-import, re-require, or re-declare a helper. Re-read a file only if it may have changed since the last read.
69
122
  </critical>`;
70
123
 
71
- export function buildEvalPrompt(enabled: EnabledLanguages): EvalPromptParts {
124
+ export function buildEvalPrompt(
125
+ enabled: EnabledLanguages,
126
+ options: EvalPromptOptions = { spawns: false },
127
+ ): EvalPromptParts {
72
128
  if (!enabled.py && !enabled.js && !enabled.rb && !enabled.jl) {
73
129
  throw new Error("no kernels enabled for eval prompt");
74
130
  }
131
+ const spawnDefaultAgent = options.spawnDefaultAgent ?? "task";
75
132
  const context: Context = {
76
133
  py: enabled.py,
77
134
  js: enabled.js,
78
135
  rb: enabled.rb,
79
136
  jl: enabled.jl,
137
+ spawns: options.spawns,
138
+ spawnDefaultAgent,
80
139
  };
81
- const description = renderTemplate(EVAL_PROMPT_TEMPLATE, context)
82
- .replace(/\n{3,}/g, "\n\n")
83
- .trim();
140
+ const examples = REUSE_CHAIN_EXAMPLES.filter((example) => enabled[example.language])
141
+ .map((example) => {
142
+ const call = { language: example.language, title: example.title, code: example.code };
143
+ return `### ${example.caption}\n\`\`\`json\n${JSON.stringify(call, null, 2)}\n\`\`\``;
144
+ })
145
+ .join("\n\n");
146
+ const description = [
147
+ renderTemplate(EVAL_PROMPT_TEMPLATE, context)
148
+ .replace(/\n{3,}/g, "\n\n")
149
+ .trim(),
150
+ examples === "" ? "" : `<examples>\n${examples}\n</examples>`,
151
+ ]
152
+ .filter((part) => part !== "")
153
+ .join("\n\n");
84
154
  return {
85
155
  description,
86
156
  promptSnippet: "Run one incremental code cell in a persistent language kernel.",
@@ -1,3 +1,5 @@
1
+ export { TIMEOUT_PAUSE_OP, TIMEOUT_RESUME_OP } from "../bridge/reserved.ts";
2
+
1
3
  import type { TimeoutPauseHandle } from "./idle-timeout.ts";
2
4
 
3
5
  export async function withBridgeTimeoutPause<T>(
@@ -16,10 +16,10 @@ export interface TimeoutPauseHandle {
16
16
 
17
17
  export class IdleTimeout implements TimeoutPauseHandle {
18
18
  readonly #cellId: string;
19
- readonly #timeoutMs: number;
20
19
  readonly #onTimeout: (event: IdleTimeoutEvent) => void;
21
20
  readonly #controller = new AbortController();
22
- #remainingMs: number;
21
+ readonly signal = this.#controller.signal;
22
+ readonly timeoutMs: number;
23
23
  #deadlineMs: number;
24
24
  #timer: ReturnType<typeof setTimeout> | undefined;
25
25
  #pauseDepth = 0;
@@ -27,26 +27,16 @@ export class IdleTimeout implements TimeoutPauseHandle {
27
27
 
28
28
  constructor(options: IdleTimeoutOptions) {
29
29
  this.#cellId = options.cellId;
30
- this.#timeoutMs = Math.max(1, Math.floor(options.timeoutMs));
31
- this.#remainingMs = this.#timeoutMs;
32
- this.#deadlineMs = Date.now() + this.#remainingMs;
30
+ this.timeoutMs = Math.max(1, Math.floor(options.timeoutMs));
31
+ this.#deadlineMs = Date.now() + this.timeoutMs;
33
32
  this.#onTimeout = options.onTimeout;
34
- this.#arm(this.#remainingMs);
35
- }
36
-
37
- get signal(): AbortSignal {
38
- return this.#controller.signal;
39
- }
40
-
41
- get timeoutMs(): number {
42
- return this.#timeoutMs;
33
+ this.#arm(this.timeoutMs);
43
34
  }
44
35
 
45
36
  pause(): void {
46
37
  if (this.#settled) return;
47
38
  this.#pauseDepth++;
48
39
  if (this.#pauseDepth !== 1) return;
49
- this.#remainingMs = Math.max(0, this.#deadlineMs - Date.now());
50
40
  this.#clearTimer();
51
41
  }
52
42
 
@@ -54,8 +44,8 @@ export class IdleTimeout implements TimeoutPauseHandle {
54
44
  if (this.#settled || this.#pauseDepth === 0) return;
55
45
  this.#pauseDepth--;
56
46
  if (this.#pauseDepth > 0) return;
57
- this.#deadlineMs = Date.now() + this.#remainingMs;
58
- this.#arm(this.#remainingMs);
47
+ this.#deadlineMs = Date.now() + this.timeoutMs;
48
+ this.#arm(this.timeoutMs);
59
49
  }
60
50
 
61
51
  dispose(): void {
@@ -81,13 +71,12 @@ export class IdleTimeout implements TimeoutPauseHandle {
81
71
  if (this.#settled || this.#pauseDepth > 0) return;
82
72
  const remainingMs = this.#deadlineMs - Date.now();
83
73
  if (remainingMs > 0) {
84
- this.#remainingMs = remainingMs;
85
74
  this.#arm(remainingMs);
86
75
  return;
87
76
  }
88
77
  this.#settled = true;
89
78
  this.#timer = undefined;
90
- const error = new Error(`Cell timed out after ${this.#timeoutMs}ms`);
79
+ const error = new Error(`Cell timed out after ${this.timeoutMs}ms`);
91
80
  error.name = "TimeoutError";
92
81
  this.#controller.abort(error);
93
82
  this.#onTimeout({ cellId: this.#cellId, error });