@code-yeongyu/senpi 2026.5.13 → 2026.5.15-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 (274) hide show
  1. package/CHANGELOG.md +1109 -1150
  2. package/README.md +1 -2
  3. package/dist/core/agent-session.d.ts +9 -0
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +121 -12
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/bash-executor.d.ts.map +1 -1
  8. package/dist/core/bash-executor.js +1 -1
  9. package/dist/core/bash-executor.js.map +1 -1
  10. package/dist/core/compaction/compaction.d.ts.map +1 -1
  11. package/dist/core/compaction/compaction.js +2 -2
  12. package/dist/core/compaction/compaction.js.map +1 -1
  13. package/dist/core/dynamic-prompt/verification.d.ts +31 -0
  14. package/dist/core/dynamic-prompt/verification.d.ts.map +1 -1
  15. package/dist/core/dynamic-prompt/verification.js +41 -0
  16. package/dist/core/dynamic-prompt/verification.js.map +1 -1
  17. package/dist/core/export-html/index.d.ts.map +1 -1
  18. package/dist/core/export-html/index.js +8 -1
  19. package/dist/core/export-html/index.js.map +1 -1
  20. package/dist/core/extensions/builtin/anthropic-web-search/index.d.ts.map +1 -1
  21. package/dist/core/extensions/builtin/anthropic-web-search/index.js +20 -0
  22. package/dist/core/extensions/builtin/anthropic-web-search/index.js.map +1 -1
  23. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  24. package/dist/core/extensions/builtin/compaction/index.js +157 -29
  25. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  26. package/dist/core/extensions/builtin/compaction/openai-remote.d.ts +197 -0
  27. package/dist/core/extensions/builtin/compaction/openai-remote.d.ts.map +1 -0
  28. package/dist/core/extensions/builtin/compaction/openai-remote.js +690 -0
  29. package/dist/core/extensions/builtin/compaction/openai-remote.js.map +1 -0
  30. package/dist/core/extensions/builtin/compaction/prompts.d.ts +3 -3
  31. package/dist/core/extensions/builtin/compaction/prompts.d.ts.map +1 -1
  32. package/dist/core/extensions/builtin/compaction/prompts.js +0 -22
  33. package/dist/core/extensions/builtin/compaction/prompts.js.map +1 -1
  34. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.d.ts +4 -0
  35. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.d.ts.map +1 -0
  36. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.js +48 -0
  37. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.js.map +1 -0
  38. package/dist/core/extensions/builtin/compaction/speculative.d.ts +3 -1
  39. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  40. package/dist/core/extensions/builtin/compaction/speculative.js +82 -33
  41. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  42. package/dist/core/extensions/builtin/compaction/todo-bridge.d.ts +8 -0
  43. package/dist/core/extensions/builtin/compaction/todo-bridge.d.ts.map +1 -1
  44. package/dist/core/extensions/builtin/compaction/todo-bridge.js +12 -6
  45. package/dist/core/extensions/builtin/compaction/todo-bridge.js.map +1 -1
  46. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  47. package/dist/core/extensions/builtin/index.js +0 -20
  48. package/dist/core/extensions/builtin/index.js.map +1 -1
  49. package/dist/core/extensions/builtin/openai-web-search/index.d.ts.map +1 -1
  50. package/dist/core/extensions/builtin/openai-web-search/index.js +28 -0
  51. package/dist/core/extensions/builtin/openai-web-search/index.js.map +1 -1
  52. package/dist/core/extensions/builtin/permission-system/prompt.d.ts.map +1 -1
  53. package/dist/core/extensions/builtin/permission-system/prompt.js +0 -5
  54. package/dist/core/extensions/builtin/permission-system/prompt.js.map +1 -1
  55. package/dist/core/extensions/builtin/system-messages.d.ts +7 -7
  56. package/dist/core/extensions/builtin/system-messages.d.ts.map +1 -1
  57. package/dist/core/extensions/builtin/system-messages.js +10 -10
  58. package/dist/core/extensions/builtin/system-messages.js.map +1 -1
  59. package/dist/core/extensions/builtin/todotools/continuation/prompt.d.ts +1 -1
  60. package/dist/core/extensions/builtin/todotools/continuation/prompt.d.ts.map +1 -1
  61. package/dist/core/extensions/builtin/todotools/continuation/prompt.js +1 -1
  62. package/dist/core/extensions/builtin/todotools/continuation/prompt.js.map +1 -1
  63. package/dist/core/extensions/builtin/todotools/state.d.ts +1 -1
  64. package/dist/core/extensions/builtin/todotools/state.d.ts.map +1 -1
  65. package/dist/core/extensions/builtin/todotools/state.js +2 -2
  66. package/dist/core/extensions/builtin/todotools/state.js.map +1 -1
  67. package/dist/core/extensions/builtin/todotools/system-messages.d.ts +3 -3
  68. package/dist/core/extensions/builtin/todotools/system-messages.d.ts.map +1 -1
  69. package/dist/core/extensions/builtin/todotools/system-messages.js +6 -6
  70. package/dist/core/extensions/builtin/todotools/system-messages.js.map +1 -1
  71. package/dist/core/extensions/builtin/tool-pair-guard/index.d.ts +1 -1
  72. package/dist/core/extensions/builtin/tool-pair-guard/index.d.ts.map +1 -1
  73. package/dist/core/extensions/builtin/tool-pair-guard/index.js +8 -4
  74. package/dist/core/extensions/builtin/tool-pair-guard/index.js.map +1 -1
  75. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.d.ts +3 -0
  76. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.d.ts.map +1 -0
  77. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.js +89 -0
  78. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.js.map +1 -0
  79. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.d.ts +3 -0
  80. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.d.ts.map +1 -0
  81. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.js +122 -0
  82. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.js.map +1 -0
  83. package/dist/core/extensions/loader.d.ts.map +1 -1
  84. package/dist/core/extensions/loader.js +2 -0
  85. package/dist/core/extensions/loader.js.map +1 -1
  86. package/dist/core/extensions/runner.d.ts +3 -0
  87. package/dist/core/extensions/runner.d.ts.map +1 -1
  88. package/dist/core/extensions/runner.js +18 -0
  89. package/dist/core/extensions/runner.js.map +1 -1
  90. package/dist/core/extensions/types.d.ts +22 -0
  91. package/dist/core/extensions/types.d.ts.map +1 -1
  92. package/dist/core/extensions/types.js.map +1 -1
  93. package/dist/core/messages.d.ts +3 -3
  94. package/dist/core/messages.d.ts.map +1 -1
  95. package/dist/core/messages.js +5 -10
  96. package/dist/core/messages.js.map +1 -1
  97. package/dist/core/resource-loader.d.ts.map +1 -1
  98. package/dist/core/resource-loader.js +0 -9
  99. package/dist/core/resource-loader.js.map +1 -1
  100. package/dist/core/sdk.d.ts +2 -2
  101. package/dist/core/sdk.d.ts.map +1 -1
  102. package/dist/core/sdk.js +8 -23
  103. package/dist/core/sdk.js.map +1 -1
  104. package/dist/core/session-manager.d.ts.map +1 -1
  105. package/dist/core/session-manager.js +1 -1
  106. package/dist/core/session-manager.js.map +1 -1
  107. package/dist/core/settings-manager.d.ts +0 -5
  108. package/dist/core/settings-manager.d.ts.map +1 -1
  109. package/dist/core/settings-manager.js.map +1 -1
  110. package/dist/core/thinking-levels.d.ts +6 -0
  111. package/dist/core/thinking-levels.d.ts.map +1 -0
  112. package/dist/core/thinking-levels.js +36 -0
  113. package/dist/core/thinking-levels.js.map +1 -0
  114. package/dist/core/tools/bash.d.ts.map +1 -1
  115. package/dist/core/tools/bash.js +15 -1
  116. package/dist/core/tools/bash.js.map +1 -1
  117. package/dist/core/tools/render-utils.d.ts.map +1 -1
  118. package/dist/core/tools/render-utils.js +1 -1
  119. package/dist/core/tools/render-utils.js.map +1 -1
  120. package/dist/main.d.ts.map +1 -1
  121. package/dist/main.js +3 -2
  122. package/dist/main.js.map +1 -1
  123. package/dist/modes/interactive/components/assistant-message.d.ts +0 -3
  124. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  125. package/dist/modes/interactive/components/assistant-message.js +3 -22
  126. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  127. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  128. package/dist/modes/interactive/components/bash-execution.js +1 -1
  129. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  130. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  131. package/dist/modes/interactive/components/compaction-summary-message.js +20 -2
  132. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  133. package/dist/modes/interactive/components/extension-selector.d.ts +2 -0
  134. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  135. package/dist/modes/interactive/components/extension-selector.js +6 -1
  136. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  137. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  138. package/dist/modes/interactive/components/keybinding-hints.js +3 -1
  139. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  140. package/dist/modes/interactive/interactive-mode.d.ts +23 -0
  141. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  142. package/dist/modes/interactive/interactive-mode.js +139 -54
  143. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  144. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  145. package/dist/modes/interactive/theme/theme.js +2 -2
  146. package/dist/modes/interactive/theme/theme.js.map +1 -1
  147. package/dist/modes/print-mode.d.ts.map +1 -1
  148. package/dist/modes/print-mode.js +3 -11
  149. package/dist/modes/print-mode.js.map +1 -1
  150. package/dist/modes/provider-native-rendering.d.ts +5 -0
  151. package/dist/modes/provider-native-rendering.d.ts.map +1 -0
  152. package/dist/modes/provider-native-rendering.js +247 -0
  153. package/dist/modes/provider-native-rendering.js.map +1 -0
  154. package/dist/utils/ansi.d.ts +2 -0
  155. package/dist/utils/ansi.d.ts.map +1 -0
  156. package/dist/utils/ansi.js +52 -0
  157. package/dist/utils/ansi.js.map +1 -0
  158. package/dist/utils/html.d.ts +7 -0
  159. package/dist/utils/html.d.ts.map +1 -0
  160. package/dist/utils/html.js +40 -0
  161. package/dist/utils/html.js.map +1 -0
  162. package/dist/utils/mime.d.ts +1 -0
  163. package/dist/utils/mime.d.ts.map +1 -1
  164. package/dist/utils/mime.js +59 -16
  165. package/dist/utils/mime.js.map +1 -1
  166. package/dist/utils/syntax-highlight.d.ts +12 -0
  167. package/dist/utils/syntax-highlight.d.ts.map +1 -0
  168. package/dist/utils/syntax-highlight.js +118 -0
  169. package/dist/utils/syntax-highlight.js.map +1 -0
  170. package/dist/utils/tools-manager.d.ts.map +1 -1
  171. package/dist/utils/tools-manager.js +76 -7
  172. package/dist/utils/tools-manager.js.map +1 -1
  173. package/docs/extensions.md +0 -1
  174. package/docs/index.md +0 -1
  175. package/docs/sdk.md +25 -44
  176. package/docs/settings.md +1 -29
  177. package/docs/termux.md +2 -2
  178. package/docs/usage.md +1 -1
  179. package/examples/README.md +1 -1
  180. package/examples/extensions/README.md +0 -1
  181. package/examples/extensions/overlay-qa-tests.ts +1 -1
  182. package/examples/sdk/01-minimal.ts +14 -10
  183. package/examples/sdk/02-custom-model.ts +12 -8
  184. package/examples/sdk/03-custom-prompt.ts +24 -16
  185. package/examples/sdk/04-skills.ts +2 -2
  186. package/examples/sdk/05-tools.ts +8 -4
  187. package/examples/sdk/06-extensions.ts +11 -7
  188. package/examples/sdk/07-context-files.ts +2 -2
  189. package/examples/sdk/08-prompt-templates.ts +2 -2
  190. package/examples/sdk/09-api-keys-and-oauth.ts +8 -4
  191. package/examples/sdk/10-settings.ts +4 -4
  192. package/examples/sdk/11-sessions.ts +4 -0
  193. package/examples/sdk/12-full-control.ts +11 -7
  194. package/examples/sdk/README.md +6 -9
  195. package/package.json +7 -12
  196. package/dist/core/extensions/builtin/anthropic-code-execution/index.d.ts +0 -7
  197. package/dist/core/extensions/builtin/anthropic-code-execution/index.d.ts.map +0 -1
  198. package/dist/core/extensions/builtin/anthropic-code-execution/index.js +0 -79
  199. package/dist/core/extensions/builtin/anthropic-code-execution/index.js.map +0 -1
  200. package/dist/core/extensions/builtin/anthropic-computer-use/index.d.ts +0 -53
  201. package/dist/core/extensions/builtin/anthropic-computer-use/index.d.ts.map +0 -1
  202. package/dist/core/extensions/builtin/anthropic-computer-use/index.js +0 -676
  203. package/dist/core/extensions/builtin/anthropic-computer-use/index.js.map +0 -1
  204. package/dist/core/extensions/builtin/anthropic-text-editor/index.d.ts +0 -25
  205. package/dist/core/extensions/builtin/anthropic-text-editor/index.d.ts.map +0 -1
  206. package/dist/core/extensions/builtin/anthropic-text-editor/index.js +0 -244
  207. package/dist/core/extensions/builtin/anthropic-text-editor/index.js.map +0 -1
  208. package/dist/core/extensions/builtin/anthropic-tool-search/index.d.ts +0 -6
  209. package/dist/core/extensions/builtin/anthropic-tool-search/index.d.ts.map +0 -1
  210. package/dist/core/extensions/builtin/anthropic-tool-search/index.js +0 -112
  211. package/dist/core/extensions/builtin/anthropic-tool-search/index.js.map +0 -1
  212. package/dist/core/extensions/builtin/background-task/cancel-tool.d.ts +0 -10
  213. package/dist/core/extensions/builtin/background-task/cancel-tool.d.ts.map +0 -1
  214. package/dist/core/extensions/builtin/background-task/cancel-tool.js +0 -109
  215. package/dist/core/extensions/builtin/background-task/cancel-tool.js.map +0 -1
  216. package/dist/core/extensions/builtin/background-task/index.d.ts +0 -3
  217. package/dist/core/extensions/builtin/background-task/index.d.ts.map +0 -1
  218. package/dist/core/extensions/builtin/background-task/index.js +0 -207
  219. package/dist/core/extensions/builtin/background-task/index.js.map +0 -1
  220. package/dist/core/extensions/builtin/background-task/manager.d.ts +0 -17
  221. package/dist/core/extensions/builtin/background-task/manager.d.ts.map +0 -1
  222. package/dist/core/extensions/builtin/background-task/manager.js +0 -114
  223. package/dist/core/extensions/builtin/background-task/manager.js.map +0 -1
  224. package/dist/core/extensions/builtin/background-task/notification.d.ts +0 -22
  225. package/dist/core/extensions/builtin/background-task/notification.d.ts.map +0 -1
  226. package/dist/core/extensions/builtin/background-task/notification.js +0 -105
  227. package/dist/core/extensions/builtin/background-task/notification.js.map +0 -1
  228. package/dist/core/extensions/builtin/background-task/output-tool.d.ts +0 -11
  229. package/dist/core/extensions/builtin/background-task/output-tool.d.ts.map +0 -1
  230. package/dist/core/extensions/builtin/background-task/output-tool.js +0 -127
  231. package/dist/core/extensions/builtin/background-task/output-tool.js.map +0 -1
  232. package/dist/core/extensions/builtin/background-task/spawner.d.ts +0 -8
  233. package/dist/core/extensions/builtin/background-task/spawner.d.ts.map +0 -1
  234. package/dist/core/extensions/builtin/background-task/spawner.js +0 -207
  235. package/dist/core/extensions/builtin/background-task/spawner.js.map +0 -1
  236. package/dist/core/extensions/builtin/background-task/task-tool.d.ts +0 -20
  237. package/dist/core/extensions/builtin/background-task/task-tool.d.ts.map +0 -1
  238. package/dist/core/extensions/builtin/background-task/task-tool.js +0 -302
  239. package/dist/core/extensions/builtin/background-task/task-tool.js.map +0 -1
  240. package/dist/core/extensions/builtin/background-task/types.d.ts +0 -72
  241. package/dist/core/extensions/builtin/background-task/types.d.ts.map +0 -1
  242. package/dist/core/extensions/builtin/background-task/types.js +0 -32
  243. package/dist/core/extensions/builtin/background-task/types.js.map +0 -1
  244. package/dist/core/extensions/builtin/google-code-execution/index.d.ts +0 -7
  245. package/dist/core/extensions/builtin/google-code-execution/index.d.ts.map +0 -1
  246. package/dist/core/extensions/builtin/google-code-execution/index.js +0 -73
  247. package/dist/core/extensions/builtin/google-code-execution/index.js.map +0 -1
  248. package/dist/core/extensions/builtin/google-google-search/index.d.ts +0 -7
  249. package/dist/core/extensions/builtin/google-google-search/index.d.ts.map +0 -1
  250. package/dist/core/extensions/builtin/google-google-search/index.js +0 -83
  251. package/dist/core/extensions/builtin/google-google-search/index.js.map +0 -1
  252. package/dist/core/extensions/builtin/google-url-context/index.d.ts +0 -7
  253. package/dist/core/extensions/builtin/google-url-context/index.d.ts.map +0 -1
  254. package/dist/core/extensions/builtin/google-url-context/index.js +0 -82
  255. package/dist/core/extensions/builtin/google-url-context/index.js.map +0 -1
  256. package/dist/core/extensions/builtin/openai-api-parallel-tool-calls/index.d.ts +0 -6
  257. package/dist/core/extensions/builtin/openai-api-parallel-tool-calls/index.d.ts.map +0 -1
  258. package/dist/core/extensions/builtin/openai-api-parallel-tool-calls/index.js +0 -57
  259. package/dist/core/extensions/builtin/openai-api-parallel-tool-calls/index.js.map +0 -1
  260. package/dist/core/extensions/builtin/openai-code-interpreter/index.d.ts +0 -10
  261. package/dist/core/extensions/builtin/openai-code-interpreter/index.d.ts.map +0 -1
  262. package/dist/core/extensions/builtin/openai-code-interpreter/index.js +0 -95
  263. package/dist/core/extensions/builtin/openai-code-interpreter/index.js.map +0 -1
  264. package/docs/agents.md +0 -348
  265. package/examples/extensions/subagent/README.md +0 -172
  266. package/examples/extensions/subagent/agents/planner.md +0 -37
  267. package/examples/extensions/subagent/agents/reviewer.md +0 -35
  268. package/examples/extensions/subagent/agents/scout.md +0 -50
  269. package/examples/extensions/subagent/agents/worker.md +0 -24
  270. package/examples/extensions/subagent/agents.ts +0 -126
  271. package/examples/extensions/subagent/index.ts +0 -987
  272. package/examples/extensions/subagent/prompts/implement-and-review.md +0 -10
  273. package/examples/extensions/subagent/prompts/implement.md +0 -10
  274. package/examples/extensions/subagent/prompts/scout-and-plan.md +0 -9
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/openai-web-search/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api } from \"@earendil-works/pi-ai\";\nimport type { ExtensionAPI } from \"../../types.js\";\n\ntype ToolDefinition = Record<string, unknown>;\n\nconst OPENAI_RESPONSES_APIS: ReadonlySet<Api> = new Set([\"openai-responses\", \"azure-openai-responses\"]);\nconst ENABLE_ENV = \"PI_OPENAI_WEB_SEARCH\";\nconst NATIVE_OPENAI_WEB_SEARCH_TYPE = \"web_search_preview\";\n\nfunction parseEnableEnv(envVar: string): boolean {\n\tconst envValue = process.env[envVar];\n\tif (!envValue) {\n\t\treturn true;\n\t}\n\n\tconst normalized = envValue.trim().toLowerCase();\n\tif (normalized === \"0\" || normalized === \"false\" || normalized === \"no\" || normalized === \"off\") {\n\t\treturn false;\n\t}\n\n\tif (normalized === \"1\" || normalized === \"true\" || normalized === \"yes\" || normalized === \"on\") {\n\t\treturn true;\n\t}\n\n\t// Unknown values fall back to default-on behavior.\n\treturn true;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction isOpenAiResponsesApi(api: Api | undefined): api is \"openai-responses\" | \"azure-openai-responses\" {\n\treturn api !== undefined && OPENAI_RESPONSES_APIS.has(api);\n}\n\nfunction isNativeOpenAiWebSearchType(value: unknown): value is \"web_search_preview\" | \"web_search_preview_2025_03_11\" {\n\treturn value === \"web_search_preview\" || value === \"web_search_preview_2025_03_11\";\n}\n\nfunction isUnsupportedWebSearchType(value: unknown): boolean {\n\treturn (\n\t\ttypeof value === \"string\" &&\n\t\t(value === \"web_search\" || value.startsWith(\"web_search_\")) &&\n\t\t!isNativeOpenAiWebSearchType(value)\n\t);\n}\n\nfunction isAnthropicWebFetchType(value: unknown): boolean {\n\treturn typeof value === \"string\" && value.startsWith(\"web_fetch_\");\n}\n\ntype SanitizedTools = {\n\tchanged: boolean;\n\ttools: ToolDefinition[];\n};\n\ntype SanitizeToolsOptions = {\n\tstripFunctionWebSearch: boolean;\n};\n\nfunction sanitizeTools(tools: unknown[], options: SanitizeToolsOptions): SanitizedTools {\n\tconst sanitized: ToolDefinition[] = [];\n\tlet changed = false;\n\tfor (const tool of tools) {\n\t\tif (!isRecord(tool)) {\n\t\t\tchanged = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst type = tool.type;\n\t\tconst shouldStripFunctionVariant =\n\t\t\toptions.stripFunctionWebSearch && tool.name === \"web_search\" && !isNativeOpenAiWebSearchType(type);\n\t\tconst shouldStripProviderNativeVariant = isUnsupportedWebSearchType(type) || isAnthropicWebFetchType(type);\n\t\tif (shouldStripFunctionVariant || shouldStripProviderNativeVariant) {\n\t\t\tchanged = true;\n\t\t} else {\n\t\t\tsanitized.push(tool);\n\t\t}\n\t}\n\n\treturn { changed, tools: sanitized };\n}\n\nexport function addOpenAiWebSearchToPayload(api: Api | undefined, payload: unknown): unknown {\n\tif (!isOpenAiResponsesApi(api)) {\n\t\treturn payload;\n\t}\n\n\tif (!isRecord(payload)) {\n\t\treturn payload;\n\t}\n\n\tconst tools = Array.isArray(payload.tools) ? payload.tools : [];\n\tconst shouldInjectWebSearch = isOpenaiWebSearchEnabled();\n\tconst sanitized = sanitizeTools(tools, { stripFunctionWebSearch: shouldInjectWebSearch });\n\tconst sanitizedTools = sanitized.tools;\n\tif (!shouldInjectWebSearch) {\n\t\tif (!sanitized.changed) {\n\t\t\treturn payload;\n\t\t}\n\n\t\treturn {\n\t\t\t...payload,\n\t\t\ttools: sanitizedTools,\n\t\t};\n\t}\n\n\tconst hasNativeWebSearch = sanitizedTools.some((tool) => isNativeOpenAiWebSearchType(tool.type));\n\n\tif (!hasNativeWebSearch) {\n\t\tsanitizedTools.push({ type: NATIVE_OPENAI_WEB_SEARCH_TYPE });\n\t}\n\n\treturn {\n\t\t...payload,\n\t\ttools: sanitizedTools,\n\t};\n}\n\nexport function isOpenaiWebSearchEnabled(): boolean {\n\treturn parseEnableEnv(ENABLE_ENV);\n}\n\nexport const OPENAI_WEB_SEARCH_SECTION = `\n## Web Search\n\nNative web search is available in this session.\nUse web search when the user asks for current or online information.\nPrefer web search over guessing when freshness matters.\n`;\n\nexport default function openaiWebSearchExtension(pi: ExtensionAPI): void {\n\tpi.on(\"before_provider_request\", (event, ctx) => {\n\t\treturn addOpenAiWebSearchToPayload(ctx.model?.api, event.payload);\n\t});\n\n\tpi.on(\"before_agent_start\", async (event, ctx) => {\n\t\tif (!isOpenAiResponsesApi(ctx.model?.api)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (!isOpenaiWebSearchEnabled()) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn {\n\t\t\tsystemPrompt: `${event.systemPrompt}\\n${OPENAI_WEB_SEARCH_SECTION}`,\n\t\t};\n\t});\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/openai-web-search/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api } from \"@earendil-works/pi-ai\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.js\";\n\ntype ToolDefinition = Record<string, unknown>;\n\nconst OPENAI_RESPONSES_APIS: ReadonlySet<Api> = new Set([\"openai-responses\", \"azure-openai-responses\"]);\nconst ENABLE_ENV = \"PI_OPENAI_WEB_SEARCH\";\nconst NATIVE_OPENAI_WEB_SEARCH_TYPE = \"web_search_preview\";\nconst WEB_SEARCH_SOURCES_INCLUDE = \"web_search_call.action.sources\";\nconst STATUS_KEY = \"openai-web-search\";\nconst WIDGET_KEY = \"openai-web-search\";\n\nfunction parseEnableEnv(envVar: string): boolean {\n\tconst envValue = process.env[envVar];\n\tif (!envValue) {\n\t\treturn true;\n\t}\n\n\tconst normalized = envValue.trim().toLowerCase();\n\tif (normalized === \"0\" || normalized === \"false\" || normalized === \"no\" || normalized === \"off\") {\n\t\treturn false;\n\t}\n\n\tif (normalized === \"1\" || normalized === \"true\" || normalized === \"yes\" || normalized === \"on\") {\n\t\treturn true;\n\t}\n\n\t// Unknown values fall back to default-on behavior.\n\treturn true;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction isOpenAiResponsesApi(api: Api | undefined): api is \"openai-responses\" | \"azure-openai-responses\" {\n\treturn api !== undefined && OPENAI_RESPONSES_APIS.has(api);\n}\n\nfunction isNativeOpenAiWebSearchType(value: unknown): value is \"web_search_preview\" | \"web_search_preview_2025_03_11\" {\n\treturn value === \"web_search_preview\" || value === \"web_search_preview_2025_03_11\";\n}\n\nfunction isUnsupportedWebSearchType(value: unknown): boolean {\n\treturn (\n\t\ttypeof value === \"string\" &&\n\t\t(value === \"web_search\" || value.startsWith(\"web_search_\")) &&\n\t\t!isNativeOpenAiWebSearchType(value)\n\t);\n}\n\nfunction isAnthropicWebFetchType(value: unknown): boolean {\n\treturn typeof value === \"string\" && value.startsWith(\"web_fetch_\");\n}\n\ntype SanitizedTools = {\n\tchanged: boolean;\n\ttools: ToolDefinition[];\n};\n\ntype SanitizeToolsOptions = {\n\tstripFunctionWebSearch: boolean;\n};\n\nfunction sanitizeTools(tools: unknown[], options: SanitizeToolsOptions): SanitizedTools {\n\tconst sanitized: ToolDefinition[] = [];\n\tlet changed = false;\n\tfor (const tool of tools) {\n\t\tif (!isRecord(tool)) {\n\t\t\tchanged = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst type = tool.type;\n\t\tconst shouldStripFunctionVariant =\n\t\t\toptions.stripFunctionWebSearch && tool.name === \"web_search\" && !isNativeOpenAiWebSearchType(type);\n\t\tconst shouldStripProviderNativeVariant = isUnsupportedWebSearchType(type) || isAnthropicWebFetchType(type);\n\t\tif (shouldStripFunctionVariant || shouldStripProviderNativeVariant) {\n\t\t\tchanged = true;\n\t\t} else {\n\t\t\tsanitized.push(tool);\n\t\t}\n\t}\n\n\treturn { changed, tools: sanitized };\n}\n\nfunction includeWebSearchSources(payload: Record<string, unknown>): string[] {\n\tconst include = Array.isArray(payload.include)\n\t\t? payload.include.filter((value): value is string => typeof value === \"string\")\n\t\t: [];\n\treturn include.includes(WEB_SEARCH_SOURCES_INCLUDE) ? include : [...include, WEB_SEARCH_SOURCES_INCLUDE];\n}\n\nexport function addOpenAiWebSearchToPayload(api: Api | undefined, payload: unknown): unknown {\n\tif (!isOpenAiResponsesApi(api)) {\n\t\treturn payload;\n\t}\n\n\tif (!isRecord(payload)) {\n\t\treturn payload;\n\t}\n\n\tconst tools = Array.isArray(payload.tools) ? payload.tools : [];\n\tconst shouldInjectWebSearch = isOpenaiWebSearchEnabled();\n\tconst sanitized = sanitizeTools(tools, { stripFunctionWebSearch: shouldInjectWebSearch });\n\tconst sanitizedTools = sanitized.tools;\n\tif (!shouldInjectWebSearch) {\n\t\tif (!sanitized.changed) {\n\t\t\treturn payload;\n\t\t}\n\n\t\treturn {\n\t\t\t...payload,\n\t\t\ttools: sanitizedTools,\n\t\t};\n\t}\n\n\tconst hasNativeWebSearch = sanitizedTools.some((tool) => isNativeOpenAiWebSearchType(tool.type));\n\n\tif (!hasNativeWebSearch) {\n\t\tsanitizedTools.push({ type: NATIVE_OPENAI_WEB_SEARCH_TYPE });\n\t}\n\n\treturn {\n\t\t...payload,\n\t\ttools: sanitizedTools,\n\t\tinclude: includeWebSearchSources(payload),\n\t};\n}\n\nexport function isOpenaiWebSearchEnabled(): boolean {\n\treturn parseEnableEnv(ENABLE_ENV);\n}\n\nfunction clearUi(ctx: ExtensionContext): void {\n\tif (!ctx.hasUI) return;\n\tctx.ui.setStatus(STATUS_KEY, undefined);\n\tctx.ui.setWidget(WIDGET_KEY, undefined);\n}\n\nfunction syncUi(ctx: ExtensionContext): void {\n\tclearUi(ctx);\n}\n\nexport const OPENAI_WEB_SEARCH_SECTION = `\n## Web Search\n\nNative web search is available in this session.\nUse web search when the user asks for current or online information.\nPrefer web search over guessing when freshness matters.\n`;\n\nexport default function openaiWebSearchExtension(pi: ExtensionAPI): void {\n\tpi.on(\"before_provider_request\", (event, ctx) => {\n\t\treturn addOpenAiWebSearchToPayload(ctx.model?.api, event.payload);\n\t});\n\n\tpi.on(\"session_start\", async (_event, ctx) => {\n\t\tsyncUi(ctx);\n\t});\n\n\tpi.on(\"model_select\", async (_event, ctx) => {\n\t\tsyncUi(ctx);\n\t});\n\n\tpi.on(\"session_shutdown\", async (_event, ctx) => {\n\t\tclearUi(ctx);\n\t});\n\n\tpi.on(\"before_agent_start\", async (event, ctx) => {\n\t\tif (!isOpenAiResponsesApi(ctx.model?.api)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (!isOpenaiWebSearchEnabled()) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn {\n\t\t\tsystemPrompt: `${event.systemPrompt}\\n${OPENAI_WEB_SEARCH_SECTION}`,\n\t\t};\n\t});\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/permission-system/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAS,UAAU,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE7D,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CA6BvG","sourcesContent":["import type { ExtensionContext } from \"../../types.js\";\nimport type { Reply, ReplyInput, Request } from \"./types.js\";\n\nexport async function showPermissionPrompt(ctx: ExtensionContext, request: Request): Promise<ReplyInput> {\n\tconst title = `Permission required: ${request.permission}`;\n\tconst message = formatRequestForDisplay(request);\n\n\tconst displayTitle = `${title}\\n\\n${message}`;\n\n\tconst options = [\"Allow once\", \"Allow always\", \"Deny\", \"Deny with feedback\"];\n\n\tconst choice = await ctx.ui.select(displayTitle, options);\n\n\tif (choice === \"Deny with feedback\") {\n\t\tconst feedback = await ctx.ui.input(\"Feedback\", \"Why are you denying this permission? (optional)\");\n\t\treturn {\n\t\t\trequestID: request.id,\n\t\t\treply: \"reject\",\n\t\t\tmessage: feedback || undefined,\n\t\t};\n\t}\n\n\tconst replyMap: Record<string, Reply> = {\n\t\t\"Allow once\": \"once\",\n\t\t\"Allow always\": \"always\",\n\t\tDeny: \"reject\",\n\t};\n\n\treturn {\n\t\trequestID: request.id,\n\t\treply: choice ? replyMap[choice] : \"reject\",\n\t};\n}\n\nfunction formatRequestForDisplay(request: Request): string {\n\tconst parts: string[] = [];\n\tconst meta = request.metadata || {};\n\n\tswitch (request.permission) {\n\t\tcase \"edit\":\n\t\t\tparts.push(`File: ${meta.filepath || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"read\":\n\t\t\tparts.push(`Path: ${meta.filePath || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"glob\":\n\t\tcase \"grep\":\n\t\t\tparts.push(`Pattern: ${meta.pattern || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"list\":\n\t\t\tparts.push(`Path: ${meta.path || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"bash\":\n\t\t\tif (meta.description) parts.push(`Description: ${meta.description}`);\n\t\t\tparts.push(`Command: $ ${meta.command || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"task\":\n\t\t\tparts.push(`Type: ${meta.subagent_type || \"Unknown\"}`);\n\t\t\tif (meta.description) parts.push(`Description: ${meta.description}`);\n\t\t\tbreak;\n\t\tcase \"websearch\":\n\t\tcase \"codesearch\":\n\t\t\tparts.push(`Query: ${meta.query || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"external_directory\": {\n\t\t\tconst parent = typeof meta.parentDir === \"string\" ? meta.parentDir : undefined;\n\t\t\tconst filepath = typeof meta.filepath === \"string\" ? meta.filepath : undefined;\n\t\t\tconst pattern = request.patterns?.[0];\n\t\t\tconst derived =\n\t\t\t\ttypeof pattern === \"string\" ? (pattern.includes(\"*\") ? pattern.split(\"*\")[0] : pattern) : undefined;\n\t\t\tconst dir = parent ?? filepath ?? derived ?? \"Unknown\";\n\t\t\tparts.push(`Directory: ${dir}`);\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tparts.push(`Tool: ${request.permission}`);\n\t\t\tbreak;\n\t}\n\n\tif (request.patterns && request.patterns.length > 0) {\n\t\tparts.push(`\\nPatterns:\\n${request.patterns.map((p) => ` - ${p}`).join(\"\\n\")}`);\n\t}\n\n\treturn parts.join(\"\\n\");\n}\n"]}
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/permission-system/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAS,UAAU,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE7D,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CA6BvG","sourcesContent":["import type { ExtensionContext } from \"../../types.js\";\nimport type { Reply, ReplyInput, Request } from \"./types.js\";\n\nexport async function showPermissionPrompt(ctx: ExtensionContext, request: Request): Promise<ReplyInput> {\n\tconst title = `Permission required: ${request.permission}`;\n\tconst message = formatRequestForDisplay(request);\n\n\tconst displayTitle = `${title}\\n\\n${message}`;\n\n\tconst options = [\"Allow once\", \"Allow always\", \"Deny\", \"Deny with feedback\"];\n\n\tconst choice = await ctx.ui.select(displayTitle, options);\n\n\tif (choice === \"Deny with feedback\") {\n\t\tconst feedback = await ctx.ui.input(\"Feedback\", \"Why are you denying this permission? (optional)\");\n\t\treturn {\n\t\t\trequestID: request.id,\n\t\t\treply: \"reject\",\n\t\t\tmessage: feedback || undefined,\n\t\t};\n\t}\n\n\tconst replyMap: Record<string, Reply> = {\n\t\t\"Allow once\": \"once\",\n\t\t\"Allow always\": \"always\",\n\t\tDeny: \"reject\",\n\t};\n\n\treturn {\n\t\trequestID: request.id,\n\t\treply: choice ? replyMap[choice] : \"reject\",\n\t};\n}\n\nfunction formatRequestForDisplay(request: Request): string {\n\tconst parts: string[] = [];\n\tconst meta = request.metadata || {};\n\n\tswitch (request.permission) {\n\t\tcase \"edit\":\n\t\t\tparts.push(`File: ${meta.filepath || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"read\":\n\t\t\tparts.push(`Path: ${meta.filePath || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"glob\":\n\t\tcase \"grep\":\n\t\t\tparts.push(`Pattern: ${meta.pattern || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"list\":\n\t\t\tparts.push(`Path: ${meta.path || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"bash\":\n\t\t\tif (meta.description) parts.push(`Description: ${meta.description}`);\n\t\t\tparts.push(`Command: $ ${meta.command || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"websearch\":\n\t\tcase \"codesearch\":\n\t\t\tparts.push(`Query: ${meta.query || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"external_directory\": {\n\t\t\tconst parent = typeof meta.parentDir === \"string\" ? meta.parentDir : undefined;\n\t\t\tconst filepath = typeof meta.filepath === \"string\" ? meta.filepath : undefined;\n\t\t\tconst pattern = request.patterns?.[0];\n\t\t\tconst derived =\n\t\t\t\ttypeof pattern === \"string\" ? (pattern.includes(\"*\") ? pattern.split(\"*\")[0] : pattern) : undefined;\n\t\t\tconst dir = parent ?? filepath ?? derived ?? \"Unknown\";\n\t\t\tparts.push(`Directory: ${dir}`);\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tparts.push(`Tool: ${request.permission}`);\n\t\t\tbreak;\n\t}\n\n\tif (request.patterns && request.patterns.length > 0) {\n\t\tparts.push(`\\nPatterns:\\n${request.patterns.map((p) => ` - ${p}`).join(\"\\n\")}`);\n\t}\n\n\treturn parts.join(\"\\n\");\n}\n"]}
@@ -44,11 +44,6 @@ function formatRequestForDisplay(request) {
44
44
  parts.push(`Description: ${meta.description}`);
45
45
  parts.push(`Command: $ ${meta.command || "Unknown"}`);
46
46
  break;
47
- case "task":
48
- parts.push(`Type: ${meta.subagent_type || "Unknown"}`);
49
- if (meta.description)
50
- parts.push(`Description: ${meta.description}`);
51
- break;
52
47
  case "websearch":
53
48
  case "codesearch":
54
49
  parts.push(`Query: ${meta.query || "Unknown"}`);
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/permission-system/prompt.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionContext } from \"../../types.js\";\nimport type { Reply, ReplyInput, Request } from \"./types.js\";\n\nexport async function showPermissionPrompt(ctx: ExtensionContext, request: Request): Promise<ReplyInput> {\n\tconst title = `Permission required: ${request.permission}`;\n\tconst message = formatRequestForDisplay(request);\n\n\tconst displayTitle = `${title}\\n\\n${message}`;\n\n\tconst options = [\"Allow once\", \"Allow always\", \"Deny\", \"Deny with feedback\"];\n\n\tconst choice = await ctx.ui.select(displayTitle, options);\n\n\tif (choice === \"Deny with feedback\") {\n\t\tconst feedback = await ctx.ui.input(\"Feedback\", \"Why are you denying this permission? (optional)\");\n\t\treturn {\n\t\t\trequestID: request.id,\n\t\t\treply: \"reject\",\n\t\t\tmessage: feedback || undefined,\n\t\t};\n\t}\n\n\tconst replyMap: Record<string, Reply> = {\n\t\t\"Allow once\": \"once\",\n\t\t\"Allow always\": \"always\",\n\t\tDeny: \"reject\",\n\t};\n\n\treturn {\n\t\trequestID: request.id,\n\t\treply: choice ? replyMap[choice] : \"reject\",\n\t};\n}\n\nfunction formatRequestForDisplay(request: Request): string {\n\tconst parts: string[] = [];\n\tconst meta = request.metadata || {};\n\n\tswitch (request.permission) {\n\t\tcase \"edit\":\n\t\t\tparts.push(`File: ${meta.filepath || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"read\":\n\t\t\tparts.push(`Path: ${meta.filePath || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"glob\":\n\t\tcase \"grep\":\n\t\t\tparts.push(`Pattern: ${meta.pattern || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"list\":\n\t\t\tparts.push(`Path: ${meta.path || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"bash\":\n\t\t\tif (meta.description) parts.push(`Description: ${meta.description}`);\n\t\t\tparts.push(`Command: $ ${meta.command || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"task\":\n\t\t\tparts.push(`Type: ${meta.subagent_type || \"Unknown\"}`);\n\t\t\tif (meta.description) parts.push(`Description: ${meta.description}`);\n\t\t\tbreak;\n\t\tcase \"websearch\":\n\t\tcase \"codesearch\":\n\t\t\tparts.push(`Query: ${meta.query || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"external_directory\": {\n\t\t\tconst parent = typeof meta.parentDir === \"string\" ? meta.parentDir : undefined;\n\t\t\tconst filepath = typeof meta.filepath === \"string\" ? meta.filepath : undefined;\n\t\t\tconst pattern = request.patterns?.[0];\n\t\t\tconst derived =\n\t\t\t\ttypeof pattern === \"string\" ? (pattern.includes(\"*\") ? pattern.split(\"*\")[0] : pattern) : undefined;\n\t\t\tconst dir = parent ?? filepath ?? derived ?? \"Unknown\";\n\t\t\tparts.push(`Directory: ${dir}`);\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tparts.push(`Tool: ${request.permission}`);\n\t\t\tbreak;\n\t}\n\n\tif (request.patterns && request.patterns.length > 0) {\n\t\tparts.push(`\\nPatterns:\\n${request.patterns.map((p) => ` - ${p}`).join(\"\\n\")}`);\n\t}\n\n\treturn parts.join(\"\\n\");\n}\n"]}
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/permission-system/prompt.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionContext } from \"../../types.js\";\nimport type { Reply, ReplyInput, Request } from \"./types.js\";\n\nexport async function showPermissionPrompt(ctx: ExtensionContext, request: Request): Promise<ReplyInput> {\n\tconst title = `Permission required: ${request.permission}`;\n\tconst message = formatRequestForDisplay(request);\n\n\tconst displayTitle = `${title}\\n\\n${message}`;\n\n\tconst options = [\"Allow once\", \"Allow always\", \"Deny\", \"Deny with feedback\"];\n\n\tconst choice = await ctx.ui.select(displayTitle, options);\n\n\tif (choice === \"Deny with feedback\") {\n\t\tconst feedback = await ctx.ui.input(\"Feedback\", \"Why are you denying this permission? (optional)\");\n\t\treturn {\n\t\t\trequestID: request.id,\n\t\t\treply: \"reject\",\n\t\t\tmessage: feedback || undefined,\n\t\t};\n\t}\n\n\tconst replyMap: Record<string, Reply> = {\n\t\t\"Allow once\": \"once\",\n\t\t\"Allow always\": \"always\",\n\t\tDeny: \"reject\",\n\t};\n\n\treturn {\n\t\trequestID: request.id,\n\t\treply: choice ? replyMap[choice] : \"reject\",\n\t};\n}\n\nfunction formatRequestForDisplay(request: Request): string {\n\tconst parts: string[] = [];\n\tconst meta = request.metadata || {};\n\n\tswitch (request.permission) {\n\t\tcase \"edit\":\n\t\t\tparts.push(`File: ${meta.filepath || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"read\":\n\t\t\tparts.push(`Path: ${meta.filePath || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"glob\":\n\t\tcase \"grep\":\n\t\t\tparts.push(`Pattern: ${meta.pattern || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"list\":\n\t\t\tparts.push(`Path: ${meta.path || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"bash\":\n\t\t\tif (meta.description) parts.push(`Description: ${meta.description}`);\n\t\t\tparts.push(`Command: $ ${meta.command || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"websearch\":\n\t\tcase \"codesearch\":\n\t\t\tparts.push(`Query: ${meta.query || \"Unknown\"}`);\n\t\t\tbreak;\n\t\tcase \"external_directory\": {\n\t\t\tconst parent = typeof meta.parentDir === \"string\" ? meta.parentDir : undefined;\n\t\t\tconst filepath = typeof meta.filepath === \"string\" ? meta.filepath : undefined;\n\t\t\tconst pattern = request.patterns?.[0];\n\t\t\tconst derived =\n\t\t\t\ttypeof pattern === \"string\" ? (pattern.includes(\"*\") ? pattern.split(\"*\")[0] : pattern) : undefined;\n\t\t\tconst dir = parent ?? filepath ?? derived ?? \"Unknown\";\n\t\t\tparts.push(`Directory: ${dir}`);\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tparts.push(`Tool: ${request.permission}`);\n\t\t\tbreak;\n\t}\n\n\tif (request.patterns && request.patterns.length > 0) {\n\t\tparts.push(`\\nPatterns:\\n${request.patterns.map((p) => ` - ${p}`).join(\"\\n\")}`);\n\t}\n\n\treturn parts.join(\"\\n\");\n}\n"]}
@@ -1,19 +1,19 @@
1
1
  import type { ImageContent, TextContent } from "@earendil-works/pi-ai";
2
2
  import type { CustomMessage } from "../../messages.js";
3
3
  import type { ExtensionAPI } from "../types.js";
4
- export declare const SANEPI_SYSTEM_PREFIX = "[system:sanepi]";
5
- export declare const SANEPI_CONVERSATION_EVENT = "sanepi:conversation";
6
- export type BuiltinSystemMessageRoute = "background-task.notification" | "todotools.continuation";
7
- export type SanepiConversationAction = "injected" | "failed";
8
- export interface SanepiConversationEvent {
4
+ export declare const SENPI_SYSTEM_PREFIX = "[system:senpi]";
5
+ export declare const SENPI_CONVERSATION_EVENT = "senpi:conversation";
6
+ export type BuiltinSystemMessageRoute = "todotools.continuation";
7
+ export type SenpiConversationAction = "injected" | "failed";
8
+ export interface SenpiConversationEvent {
9
9
  version: 1;
10
10
  source: "builtin";
11
- action: SanepiConversationAction;
11
+ action: SenpiConversationAction;
12
12
  route: BuiltinSystemMessageRoute;
13
13
  sessionId?: string;
14
14
  timestamp: number;
15
15
  conversation: {
16
- prefix: typeof SANEPI_SYSTEM_PREFIX;
16
+ prefix: typeof SENPI_SYSTEM_PREFIX;
17
17
  kind: "custom_message" | "user_message";
18
18
  customType?: string;
19
19
  deliverAs?: "steer" | "followUp";
@@ -1 +1 @@
1
- {"version":3,"file":"system-messages.d.ts","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/system-messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AACtD,eAAO,MAAM,yBAAyB,wBAAwB,CAAC;AAE/D,MAAM,MAAM,yBAAyB,GAAG,8BAA8B,GAAG,wBAAwB,CAAC;AAClG,MAAM,MAAM,wBAAwB,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE7D,MAAM,WAAW,uBAAuB;IACvC,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,wBAAwB,CAAC;IACjC,KAAK,EAAE,yBAAyB,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE;QACb,MAAM,EAAE,OAAO,oBAAoB,CAAC;QACpC,IAAI,EAAE,gBAAgB,GAAG,cAAc,CAAC;QACxC,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;QACjC,WAAW,CAAC,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,KAAK,yBAAyB,GAAG;IAChC,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,2BAA2B,GAAG;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAqFF,wBAAgB,sBAAsB,CACrC,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,yBAAyB,EAChC,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,EAChD,OAAO,CAAC,EAAE,yBAAyB,GACjC,IAAI,CAqBN;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAChD,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,yBAAyB,EAChC,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,CAAC,EACxF,OAAO,CAAC,EAAE,2BAA2B,GACnC,IAAI,CAgCN;AAED,wBAAgB,+BAA+B,CAC9C,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE;IACL,KAAK,EAAE,yBAAyB,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,gBAAgB,GAAG,cAAc,CAAC;IACxC,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IACjC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACrB,GACC,IAAI,CAiBN","sourcesContent":["import type { ImageContent, TextContent } from \"@earendil-works/pi-ai\";\nimport type { CustomMessage } from \"../../messages.js\";\nimport type { ExtensionAPI } from \"../types.js\";\n\nexport const SANEPI_SYSTEM_PREFIX = \"[system:sanepi]\";\nexport const SANEPI_CONVERSATION_EVENT = \"sanepi:conversation\";\n\nexport type BuiltinSystemMessageRoute = \"background-task.notification\" | \"todotools.continuation\";\nexport type SanepiConversationAction = \"injected\" | \"failed\";\n\nexport interface SanepiConversationEvent {\n\tversion: 1;\n\tsource: \"builtin\";\n\taction: SanepiConversationAction;\n\troute: BuiltinSystemMessageRoute;\n\tsessionId?: string;\n\ttimestamp: number;\n\tconversation: {\n\t\tprefix: typeof SANEPI_SYSTEM_PREFIX;\n\t\tkind: \"custom_message\" | \"user_message\";\n\t\tcustomType?: string;\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\ttriggerTurn?: boolean;\n\t};\n\ttext: string;\n\terrorMessage?: string;\n}\n\ntype BuiltinUserMessageOptions = {\n\tdeliverAs?: \"steer\" | \"followUp\";\n\tsessionId?: string;\n};\n\ntype BuiltinCustomMessageOptions = {\n\ttriggerTurn?: boolean;\n\tdeliverAs?: \"steer\" | \"followUp\" | \"nextTurn\";\n\tsessionId?: string;\n};\n\nfunction prefixText(text: string): string {\n\treturn text.startsWith(SANEPI_SYSTEM_PREFIX) ? text : `${SANEPI_SYSTEM_PREFIX}\\n${text}`;\n}\n\nfunction prefixContent(content: string | (TextContent | ImageContent)[]): string | (TextContent | ImageContent)[] {\n\tif (typeof content === \"string\") {\n\t\treturn prefixText(content);\n\t}\n\n\tconst firstTextIndex = content.findIndex((part) => part.type === \"text\");\n\tif (firstTextIndex === -1) {\n\t\treturn [{ type: \"text\", text: SANEPI_SYSTEM_PREFIX }, ...content];\n\t}\n\n\treturn content.map((part, index) => {\n\t\tif (part.type !== \"text\" || index !== firstTextIndex) {\n\t\t\treturn part;\n\t\t}\n\n\t\treturn {\n\t\t\t...part,\n\t\t\ttext: prefixText(part.text),\n\t\t};\n\t});\n}\n\nfunction extractText(content: string | (TextContent | ImageContent)[]): string {\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\n\treturn content\n\t\t.filter((part): part is TextContent => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\");\n}\n\nfunction emitSanepiConversationEvent(pi: ExtensionAPI, event: SanepiConversationEvent): void {\n\tpi.events.emit(SANEPI_CONVERSATION_EVENT, event);\n}\n\nfunction createBaseEvent(args: {\n\taction: SanepiConversationAction;\n\troute: BuiltinSystemMessageRoute;\n\tsessionId?: string;\n\tkind: \"custom_message\" | \"user_message\";\n\tcustomType?: string;\n\tdeliverAs?: \"steer\" | \"followUp\";\n\ttriggerTurn?: boolean;\n\ttext: string;\n\terrorMessage?: string;\n}): SanepiConversationEvent {\n\treturn {\n\t\tversion: 1,\n\t\tsource: \"builtin\",\n\t\taction: args.action,\n\t\troute: args.route,\n\t\tsessionId: args.sessionId,\n\t\ttimestamp: Date.now(),\n\t\tconversation: {\n\t\t\tprefix: SANEPI_SYSTEM_PREFIX,\n\t\t\tkind: args.kind,\n\t\t\tcustomType: args.customType,\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\ttriggerTurn: args.triggerTurn,\n\t\t},\n\t\ttext: args.text,\n\t\terrorMessage: args.errorMessage,\n\t};\n}\n\nfunction hasUserMessageOptions(\n\toptions: BuiltinUserMessageOptions | undefined,\n): options is BuiltinUserMessageOptions & { deliverAs: \"steer\" | \"followUp\" } {\n\treturn options?.deliverAs !== undefined;\n}\n\nfunction hasCustomMessageOptions(\n\toptions: BuiltinCustomMessageOptions | undefined,\n): options is BuiltinCustomMessageOptions & { triggerTurn?: boolean; deliverAs?: \"steer\" | \"followUp\" | \"nextTurn\" } {\n\treturn options?.triggerTurn === true || options?.deliverAs !== undefined;\n}\n\nexport function sendBuiltinUserMessage(\n\tpi: ExtensionAPI,\n\troute: BuiltinSystemMessageRoute,\n\tcontent: string | (TextContent | ImageContent)[],\n\toptions?: BuiltinUserMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(content);\n\n\temitSanepiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\tkind: \"user_message\",\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: options?.deliverAs,\n\t\t}),\n\t);\n\n\tif (hasUserMessageOptions(options)) {\n\t\tpi.sendUserMessage(prefixedContent, { deliverAs: options.deliverAs });\n\t\treturn;\n\t}\n\n\tpi.sendUserMessage(prefixedContent);\n}\n\nexport function sendBuiltinCustomMessage<TDetails>(\n\tpi: ExtensionAPI,\n\troute: BuiltinSystemMessageRoute,\n\tmessage: Pick<CustomMessage<TDetails>, \"content\" | \"customType\" | \"details\" | \"display\">,\n\toptions?: BuiltinCustomMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(message.content);\n\tconst deliverAs = options?.deliverAs === \"nextTurn\" ? undefined : options?.deliverAs;\n\n\temitSanepiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\tkind: \"custom_message\",\n\t\t\tcustomType: message.customType,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs,\n\t\t\ttriggerTurn: options?.triggerTurn,\n\t\t}),\n\t);\n\n\tconst prefixedMessage = {\n\t\t...message,\n\t\tcontent: prefixedContent,\n\t};\n\n\tif (hasCustomMessageOptions(options)) {\n\t\tpi.sendMessage(prefixedMessage, {\n\t\t\ttriggerTurn: options.triggerTurn,\n\t\t\tdeliverAs: options.deliverAs,\n\t\t});\n\t\treturn;\n\t}\n\n\tpi.sendMessage(prefixedMessage);\n}\n\nexport function emitBuiltinSystemMessageFailure(\n\tpi: ExtensionAPI,\n\targs: {\n\t\troute: BuiltinSystemMessageRoute;\n\t\tsessionId?: string;\n\t\tkind: \"custom_message\" | \"user_message\";\n\t\tcontent: string | (TextContent | ImageContent)[];\n\t\tcustomType?: string;\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\ttriggerTurn?: boolean;\n\t\terrorMessage: string;\n\t},\n): void {\n\tconst prefixedContent = prefixContent(args.content);\n\n\temitSanepiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"failed\",\n\t\t\troute: args.route,\n\t\t\tsessionId: args.sessionId,\n\t\t\tkind: args.kind,\n\t\t\tcustomType: args.customType,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\ttriggerTurn: args.triggerTurn,\n\t\t\terrorMessage: args.errorMessage,\n\t\t}),\n\t);\n}\n"]}
1
+ {"version":3,"file":"system-messages.d.ts","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/system-messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AACpD,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAE7D,MAAM,MAAM,yBAAyB,GAAG,wBAAwB,CAAC;AACjE,MAAM,MAAM,uBAAuB,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE5D,MAAM,WAAW,sBAAsB;IACtC,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,uBAAuB,CAAC;IAChC,KAAK,EAAE,yBAAyB,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE;QACb,MAAM,EAAE,OAAO,mBAAmB,CAAC;QACnC,IAAI,EAAE,gBAAgB,GAAG,cAAc,CAAC;QACxC,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;QACjC,WAAW,CAAC,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,KAAK,yBAAyB,GAAG;IAChC,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,2BAA2B,GAAG;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAqFF,wBAAgB,sBAAsB,CACrC,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,yBAAyB,EAChC,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,EAChD,OAAO,CAAC,EAAE,yBAAyB,GACjC,IAAI,CAqBN;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAChD,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,yBAAyB,EAChC,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,CAAC,EACxF,OAAO,CAAC,EAAE,2BAA2B,GACnC,IAAI,CAgCN;AAED,wBAAgB,+BAA+B,CAC9C,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE;IACL,KAAK,EAAE,yBAAyB,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,gBAAgB,GAAG,cAAc,CAAC;IACxC,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IACjC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACrB,GACC,IAAI,CAiBN","sourcesContent":["import type { ImageContent, TextContent } from \"@earendil-works/pi-ai\";\nimport type { CustomMessage } from \"../../messages.js\";\nimport type { ExtensionAPI } from \"../types.js\";\n\nexport const SENPI_SYSTEM_PREFIX = \"[system:senpi]\";\nexport const SENPI_CONVERSATION_EVENT = \"senpi:conversation\";\n\nexport type BuiltinSystemMessageRoute = \"todotools.continuation\";\nexport type SenpiConversationAction = \"injected\" | \"failed\";\n\nexport interface SenpiConversationEvent {\n\tversion: 1;\n\tsource: \"builtin\";\n\taction: SenpiConversationAction;\n\troute: BuiltinSystemMessageRoute;\n\tsessionId?: string;\n\ttimestamp: number;\n\tconversation: {\n\t\tprefix: typeof SENPI_SYSTEM_PREFIX;\n\t\tkind: \"custom_message\" | \"user_message\";\n\t\tcustomType?: string;\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\ttriggerTurn?: boolean;\n\t};\n\ttext: string;\n\terrorMessage?: string;\n}\n\ntype BuiltinUserMessageOptions = {\n\tdeliverAs?: \"steer\" | \"followUp\";\n\tsessionId?: string;\n};\n\ntype BuiltinCustomMessageOptions = {\n\ttriggerTurn?: boolean;\n\tdeliverAs?: \"steer\" | \"followUp\" | \"nextTurn\";\n\tsessionId?: string;\n};\n\nfunction prefixText(text: string): string {\n\treturn text.startsWith(SENPI_SYSTEM_PREFIX) ? text : `${SENPI_SYSTEM_PREFIX}\\n${text}`;\n}\n\nfunction prefixContent(content: string | (TextContent | ImageContent)[]): string | (TextContent | ImageContent)[] {\n\tif (typeof content === \"string\") {\n\t\treturn prefixText(content);\n\t}\n\n\tconst firstTextIndex = content.findIndex((part) => part.type === \"text\");\n\tif (firstTextIndex === -1) {\n\t\treturn [{ type: \"text\", text: SENPI_SYSTEM_PREFIX }, ...content];\n\t}\n\n\treturn content.map((part, index) => {\n\t\tif (part.type !== \"text\" || index !== firstTextIndex) {\n\t\t\treturn part;\n\t\t}\n\n\t\treturn {\n\t\t\t...part,\n\t\t\ttext: prefixText(part.text),\n\t\t};\n\t});\n}\n\nfunction extractText(content: string | (TextContent | ImageContent)[]): string {\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\n\treturn content\n\t\t.filter((part): part is TextContent => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\");\n}\n\nfunction emitSenpiConversationEvent(pi: ExtensionAPI, event: SenpiConversationEvent): void {\n\tpi.events.emit(SENPI_CONVERSATION_EVENT, event);\n}\n\nfunction createBaseEvent(args: {\n\taction: SenpiConversationAction;\n\troute: BuiltinSystemMessageRoute;\n\tsessionId?: string;\n\tkind: \"custom_message\" | \"user_message\";\n\tcustomType?: string;\n\tdeliverAs?: \"steer\" | \"followUp\";\n\ttriggerTurn?: boolean;\n\ttext: string;\n\terrorMessage?: string;\n}): SenpiConversationEvent {\n\treturn {\n\t\tversion: 1,\n\t\tsource: \"builtin\",\n\t\taction: args.action,\n\t\troute: args.route,\n\t\tsessionId: args.sessionId,\n\t\ttimestamp: Date.now(),\n\t\tconversation: {\n\t\t\tprefix: SENPI_SYSTEM_PREFIX,\n\t\t\tkind: args.kind,\n\t\t\tcustomType: args.customType,\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\ttriggerTurn: args.triggerTurn,\n\t\t},\n\t\ttext: args.text,\n\t\terrorMessage: args.errorMessage,\n\t};\n}\n\nfunction hasUserMessageOptions(\n\toptions: BuiltinUserMessageOptions | undefined,\n): options is BuiltinUserMessageOptions & { deliverAs: \"steer\" | \"followUp\" } {\n\treturn options?.deliverAs !== undefined;\n}\n\nfunction hasCustomMessageOptions(\n\toptions: BuiltinCustomMessageOptions | undefined,\n): options is BuiltinCustomMessageOptions & { triggerTurn?: boolean; deliverAs?: \"steer\" | \"followUp\" | \"nextTurn\" } {\n\treturn options?.triggerTurn === true || options?.deliverAs !== undefined;\n}\n\nexport function sendBuiltinUserMessage(\n\tpi: ExtensionAPI,\n\troute: BuiltinSystemMessageRoute,\n\tcontent: string | (TextContent | ImageContent)[],\n\toptions?: BuiltinUserMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(content);\n\n\temitSenpiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\tkind: \"user_message\",\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: options?.deliverAs,\n\t\t}),\n\t);\n\n\tif (hasUserMessageOptions(options)) {\n\t\tpi.sendUserMessage(prefixedContent, { deliverAs: options.deliverAs });\n\t\treturn;\n\t}\n\n\tpi.sendUserMessage(prefixedContent);\n}\n\nexport function sendBuiltinCustomMessage<TDetails>(\n\tpi: ExtensionAPI,\n\troute: BuiltinSystemMessageRoute,\n\tmessage: Pick<CustomMessage<TDetails>, \"content\" | \"customType\" | \"details\" | \"display\">,\n\toptions?: BuiltinCustomMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(message.content);\n\tconst deliverAs = options?.deliverAs === \"nextTurn\" ? undefined : options?.deliverAs;\n\n\temitSenpiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\tkind: \"custom_message\",\n\t\t\tcustomType: message.customType,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs,\n\t\t\ttriggerTurn: options?.triggerTurn,\n\t\t}),\n\t);\n\n\tconst prefixedMessage = {\n\t\t...message,\n\t\tcontent: prefixedContent,\n\t};\n\n\tif (hasCustomMessageOptions(options)) {\n\t\tpi.sendMessage(prefixedMessage, {\n\t\t\ttriggerTurn: options.triggerTurn,\n\t\t\tdeliverAs: options.deliverAs,\n\t\t});\n\t\treturn;\n\t}\n\n\tpi.sendMessage(prefixedMessage);\n}\n\nexport function emitBuiltinSystemMessageFailure(\n\tpi: ExtensionAPI,\n\targs: {\n\t\troute: BuiltinSystemMessageRoute;\n\t\tsessionId?: string;\n\t\tkind: \"custom_message\" | \"user_message\";\n\t\tcontent: string | (TextContent | ImageContent)[];\n\t\tcustomType?: string;\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\ttriggerTurn?: boolean;\n\t\terrorMessage: string;\n\t},\n): void {\n\tconst prefixedContent = prefixContent(args.content);\n\n\temitSenpiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"failed\",\n\t\t\troute: args.route,\n\t\t\tsessionId: args.sessionId,\n\t\t\tkind: args.kind,\n\t\t\tcustomType: args.customType,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\ttriggerTurn: args.triggerTurn,\n\t\t\terrorMessage: args.errorMessage,\n\t\t}),\n\t);\n}\n"]}
@@ -1,7 +1,7 @@
1
- export const SANEPI_SYSTEM_PREFIX = "[system:sanepi]";
2
- export const SANEPI_CONVERSATION_EVENT = "sanepi:conversation";
1
+ export const SENPI_SYSTEM_PREFIX = "[system:senpi]";
2
+ export const SENPI_CONVERSATION_EVENT = "senpi:conversation";
3
3
  function prefixText(text) {
4
- return text.startsWith(SANEPI_SYSTEM_PREFIX) ? text : `${SANEPI_SYSTEM_PREFIX}\n${text}`;
4
+ return text.startsWith(SENPI_SYSTEM_PREFIX) ? text : `${SENPI_SYSTEM_PREFIX}\n${text}`;
5
5
  }
6
6
  function prefixContent(content) {
7
7
  if (typeof content === "string") {
@@ -9,7 +9,7 @@ function prefixContent(content) {
9
9
  }
10
10
  const firstTextIndex = content.findIndex((part) => part.type === "text");
11
11
  if (firstTextIndex === -1) {
12
- return [{ type: "text", text: SANEPI_SYSTEM_PREFIX }, ...content];
12
+ return [{ type: "text", text: SENPI_SYSTEM_PREFIX }, ...content];
13
13
  }
14
14
  return content.map((part, index) => {
15
15
  if (part.type !== "text" || index !== firstTextIndex) {
@@ -30,8 +30,8 @@ function extractText(content) {
30
30
  .map((part) => part.text)
31
31
  .join("\n");
32
32
  }
33
- function emitSanepiConversationEvent(pi, event) {
34
- pi.events.emit(SANEPI_CONVERSATION_EVENT, event);
33
+ function emitSenpiConversationEvent(pi, event) {
34
+ pi.events.emit(SENPI_CONVERSATION_EVENT, event);
35
35
  }
36
36
  function createBaseEvent(args) {
37
37
  return {
@@ -42,7 +42,7 @@ function createBaseEvent(args) {
42
42
  sessionId: args.sessionId,
43
43
  timestamp: Date.now(),
44
44
  conversation: {
45
- prefix: SANEPI_SYSTEM_PREFIX,
45
+ prefix: SENPI_SYSTEM_PREFIX,
46
46
  kind: args.kind,
47
47
  customType: args.customType,
48
48
  deliverAs: args.deliverAs,
@@ -60,7 +60,7 @@ function hasCustomMessageOptions(options) {
60
60
  }
61
61
  export function sendBuiltinUserMessage(pi, route, content, options) {
62
62
  const prefixedContent = prefixContent(content);
63
- emitSanepiConversationEvent(pi, createBaseEvent({
63
+ emitSenpiConversationEvent(pi, createBaseEvent({
64
64
  action: "injected",
65
65
  route,
66
66
  sessionId: options?.sessionId,
@@ -77,7 +77,7 @@ export function sendBuiltinUserMessage(pi, route, content, options) {
77
77
  export function sendBuiltinCustomMessage(pi, route, message, options) {
78
78
  const prefixedContent = prefixContent(message.content);
79
79
  const deliverAs = options?.deliverAs === "nextTurn" ? undefined : options?.deliverAs;
80
- emitSanepiConversationEvent(pi, createBaseEvent({
80
+ emitSenpiConversationEvent(pi, createBaseEvent({
81
81
  action: "injected",
82
82
  route,
83
83
  sessionId: options?.sessionId,
@@ -102,7 +102,7 @@ export function sendBuiltinCustomMessage(pi, route, message, options) {
102
102
  }
103
103
  export function emitBuiltinSystemMessageFailure(pi, args) {
104
104
  const prefixedContent = prefixContent(args.content);
105
- emitSanepiConversationEvent(pi, createBaseEvent({
105
+ emitSenpiConversationEvent(pi, createBaseEvent({
106
106
  action: "failed",
107
107
  route: args.route,
108
108
  sessionId: args.sessionId,
@@ -1 +1 @@
1
- {"version":3,"file":"system-messages.js","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/system-messages.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ImageContent, TextContent } from \"@earendil-works/pi-ai\";\nimport type { CustomMessage } from \"../../messages.js\";\nimport type { ExtensionAPI } from \"../types.js\";\n\nexport const SANEPI_SYSTEM_PREFIX = \"[system:sanepi]\";\nexport const SANEPI_CONVERSATION_EVENT = \"sanepi:conversation\";\n\nexport type BuiltinSystemMessageRoute = \"background-task.notification\" | \"todotools.continuation\";\nexport type SanepiConversationAction = \"injected\" | \"failed\";\n\nexport interface SanepiConversationEvent {\n\tversion: 1;\n\tsource: \"builtin\";\n\taction: SanepiConversationAction;\n\troute: BuiltinSystemMessageRoute;\n\tsessionId?: string;\n\ttimestamp: number;\n\tconversation: {\n\t\tprefix: typeof SANEPI_SYSTEM_PREFIX;\n\t\tkind: \"custom_message\" | \"user_message\";\n\t\tcustomType?: string;\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\ttriggerTurn?: boolean;\n\t};\n\ttext: string;\n\terrorMessage?: string;\n}\n\ntype BuiltinUserMessageOptions = {\n\tdeliverAs?: \"steer\" | \"followUp\";\n\tsessionId?: string;\n};\n\ntype BuiltinCustomMessageOptions = {\n\ttriggerTurn?: boolean;\n\tdeliverAs?: \"steer\" | \"followUp\" | \"nextTurn\";\n\tsessionId?: string;\n};\n\nfunction prefixText(text: string): string {\n\treturn text.startsWith(SANEPI_SYSTEM_PREFIX) ? text : `${SANEPI_SYSTEM_PREFIX}\\n${text}`;\n}\n\nfunction prefixContent(content: string | (TextContent | ImageContent)[]): string | (TextContent | ImageContent)[] {\n\tif (typeof content === \"string\") {\n\t\treturn prefixText(content);\n\t}\n\n\tconst firstTextIndex = content.findIndex((part) => part.type === \"text\");\n\tif (firstTextIndex === -1) {\n\t\treturn [{ type: \"text\", text: SANEPI_SYSTEM_PREFIX }, ...content];\n\t}\n\n\treturn content.map((part, index) => {\n\t\tif (part.type !== \"text\" || index !== firstTextIndex) {\n\t\t\treturn part;\n\t\t}\n\n\t\treturn {\n\t\t\t...part,\n\t\t\ttext: prefixText(part.text),\n\t\t};\n\t});\n}\n\nfunction extractText(content: string | (TextContent | ImageContent)[]): string {\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\n\treturn content\n\t\t.filter((part): part is TextContent => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\");\n}\n\nfunction emitSanepiConversationEvent(pi: ExtensionAPI, event: SanepiConversationEvent): void {\n\tpi.events.emit(SANEPI_CONVERSATION_EVENT, event);\n}\n\nfunction createBaseEvent(args: {\n\taction: SanepiConversationAction;\n\troute: BuiltinSystemMessageRoute;\n\tsessionId?: string;\n\tkind: \"custom_message\" | \"user_message\";\n\tcustomType?: string;\n\tdeliverAs?: \"steer\" | \"followUp\";\n\ttriggerTurn?: boolean;\n\ttext: string;\n\terrorMessage?: string;\n}): SanepiConversationEvent {\n\treturn {\n\t\tversion: 1,\n\t\tsource: \"builtin\",\n\t\taction: args.action,\n\t\troute: args.route,\n\t\tsessionId: args.sessionId,\n\t\ttimestamp: Date.now(),\n\t\tconversation: {\n\t\t\tprefix: SANEPI_SYSTEM_PREFIX,\n\t\t\tkind: args.kind,\n\t\t\tcustomType: args.customType,\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\ttriggerTurn: args.triggerTurn,\n\t\t},\n\t\ttext: args.text,\n\t\terrorMessage: args.errorMessage,\n\t};\n}\n\nfunction hasUserMessageOptions(\n\toptions: BuiltinUserMessageOptions | undefined,\n): options is BuiltinUserMessageOptions & { deliverAs: \"steer\" | \"followUp\" } {\n\treturn options?.deliverAs !== undefined;\n}\n\nfunction hasCustomMessageOptions(\n\toptions: BuiltinCustomMessageOptions | undefined,\n): options is BuiltinCustomMessageOptions & { triggerTurn?: boolean; deliverAs?: \"steer\" | \"followUp\" | \"nextTurn\" } {\n\treturn options?.triggerTurn === true || options?.deliverAs !== undefined;\n}\n\nexport function sendBuiltinUserMessage(\n\tpi: ExtensionAPI,\n\troute: BuiltinSystemMessageRoute,\n\tcontent: string | (TextContent | ImageContent)[],\n\toptions?: BuiltinUserMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(content);\n\n\temitSanepiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\tkind: \"user_message\",\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: options?.deliverAs,\n\t\t}),\n\t);\n\n\tif (hasUserMessageOptions(options)) {\n\t\tpi.sendUserMessage(prefixedContent, { deliverAs: options.deliverAs });\n\t\treturn;\n\t}\n\n\tpi.sendUserMessage(prefixedContent);\n}\n\nexport function sendBuiltinCustomMessage<TDetails>(\n\tpi: ExtensionAPI,\n\troute: BuiltinSystemMessageRoute,\n\tmessage: Pick<CustomMessage<TDetails>, \"content\" | \"customType\" | \"details\" | \"display\">,\n\toptions?: BuiltinCustomMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(message.content);\n\tconst deliverAs = options?.deliverAs === \"nextTurn\" ? undefined : options?.deliverAs;\n\n\temitSanepiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\tkind: \"custom_message\",\n\t\t\tcustomType: message.customType,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs,\n\t\t\ttriggerTurn: options?.triggerTurn,\n\t\t}),\n\t);\n\n\tconst prefixedMessage = {\n\t\t...message,\n\t\tcontent: prefixedContent,\n\t};\n\n\tif (hasCustomMessageOptions(options)) {\n\t\tpi.sendMessage(prefixedMessage, {\n\t\t\ttriggerTurn: options.triggerTurn,\n\t\t\tdeliverAs: options.deliverAs,\n\t\t});\n\t\treturn;\n\t}\n\n\tpi.sendMessage(prefixedMessage);\n}\n\nexport function emitBuiltinSystemMessageFailure(\n\tpi: ExtensionAPI,\n\targs: {\n\t\troute: BuiltinSystemMessageRoute;\n\t\tsessionId?: string;\n\t\tkind: \"custom_message\" | \"user_message\";\n\t\tcontent: string | (TextContent | ImageContent)[];\n\t\tcustomType?: string;\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\ttriggerTurn?: boolean;\n\t\terrorMessage: string;\n\t},\n): void {\n\tconst prefixedContent = prefixContent(args.content);\n\n\temitSanepiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"failed\",\n\t\t\troute: args.route,\n\t\t\tsessionId: args.sessionId,\n\t\t\tkind: args.kind,\n\t\t\tcustomType: args.customType,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\ttriggerTurn: args.triggerTurn,\n\t\t\terrorMessage: args.errorMessage,\n\t\t}),\n\t);\n}\n"]}
1
+ {"version":3,"file":"system-messages.js","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/system-messages.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ImageContent, TextContent } from \"@earendil-works/pi-ai\";\nimport type { CustomMessage } from \"../../messages.js\";\nimport type { ExtensionAPI } from \"../types.js\";\n\nexport const SENPI_SYSTEM_PREFIX = \"[system:senpi]\";\nexport const SENPI_CONVERSATION_EVENT = \"senpi:conversation\";\n\nexport type BuiltinSystemMessageRoute = \"todotools.continuation\";\nexport type SenpiConversationAction = \"injected\" | \"failed\";\n\nexport interface SenpiConversationEvent {\n\tversion: 1;\n\tsource: \"builtin\";\n\taction: SenpiConversationAction;\n\troute: BuiltinSystemMessageRoute;\n\tsessionId?: string;\n\ttimestamp: number;\n\tconversation: {\n\t\tprefix: typeof SENPI_SYSTEM_PREFIX;\n\t\tkind: \"custom_message\" | \"user_message\";\n\t\tcustomType?: string;\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\ttriggerTurn?: boolean;\n\t};\n\ttext: string;\n\terrorMessage?: string;\n}\n\ntype BuiltinUserMessageOptions = {\n\tdeliverAs?: \"steer\" | \"followUp\";\n\tsessionId?: string;\n};\n\ntype BuiltinCustomMessageOptions = {\n\ttriggerTurn?: boolean;\n\tdeliverAs?: \"steer\" | \"followUp\" | \"nextTurn\";\n\tsessionId?: string;\n};\n\nfunction prefixText(text: string): string {\n\treturn text.startsWith(SENPI_SYSTEM_PREFIX) ? text : `${SENPI_SYSTEM_PREFIX}\\n${text}`;\n}\n\nfunction prefixContent(content: string | (TextContent | ImageContent)[]): string | (TextContent | ImageContent)[] {\n\tif (typeof content === \"string\") {\n\t\treturn prefixText(content);\n\t}\n\n\tconst firstTextIndex = content.findIndex((part) => part.type === \"text\");\n\tif (firstTextIndex === -1) {\n\t\treturn [{ type: \"text\", text: SENPI_SYSTEM_PREFIX }, ...content];\n\t}\n\n\treturn content.map((part, index) => {\n\t\tif (part.type !== \"text\" || index !== firstTextIndex) {\n\t\t\treturn part;\n\t\t}\n\n\t\treturn {\n\t\t\t...part,\n\t\t\ttext: prefixText(part.text),\n\t\t};\n\t});\n}\n\nfunction extractText(content: string | (TextContent | ImageContent)[]): string {\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\n\treturn content\n\t\t.filter((part): part is TextContent => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\");\n}\n\nfunction emitSenpiConversationEvent(pi: ExtensionAPI, event: SenpiConversationEvent): void {\n\tpi.events.emit(SENPI_CONVERSATION_EVENT, event);\n}\n\nfunction createBaseEvent(args: {\n\taction: SenpiConversationAction;\n\troute: BuiltinSystemMessageRoute;\n\tsessionId?: string;\n\tkind: \"custom_message\" | \"user_message\";\n\tcustomType?: string;\n\tdeliverAs?: \"steer\" | \"followUp\";\n\ttriggerTurn?: boolean;\n\ttext: string;\n\terrorMessage?: string;\n}): SenpiConversationEvent {\n\treturn {\n\t\tversion: 1,\n\t\tsource: \"builtin\",\n\t\taction: args.action,\n\t\troute: args.route,\n\t\tsessionId: args.sessionId,\n\t\ttimestamp: Date.now(),\n\t\tconversation: {\n\t\t\tprefix: SENPI_SYSTEM_PREFIX,\n\t\t\tkind: args.kind,\n\t\t\tcustomType: args.customType,\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\ttriggerTurn: args.triggerTurn,\n\t\t},\n\t\ttext: args.text,\n\t\terrorMessage: args.errorMessage,\n\t};\n}\n\nfunction hasUserMessageOptions(\n\toptions: BuiltinUserMessageOptions | undefined,\n): options is BuiltinUserMessageOptions & { deliverAs: \"steer\" | \"followUp\" } {\n\treturn options?.deliverAs !== undefined;\n}\n\nfunction hasCustomMessageOptions(\n\toptions: BuiltinCustomMessageOptions | undefined,\n): options is BuiltinCustomMessageOptions & { triggerTurn?: boolean; deliverAs?: \"steer\" | \"followUp\" | \"nextTurn\" } {\n\treturn options?.triggerTurn === true || options?.deliverAs !== undefined;\n}\n\nexport function sendBuiltinUserMessage(\n\tpi: ExtensionAPI,\n\troute: BuiltinSystemMessageRoute,\n\tcontent: string | (TextContent | ImageContent)[],\n\toptions?: BuiltinUserMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(content);\n\n\temitSenpiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\tkind: \"user_message\",\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: options?.deliverAs,\n\t\t}),\n\t);\n\n\tif (hasUserMessageOptions(options)) {\n\t\tpi.sendUserMessage(prefixedContent, { deliverAs: options.deliverAs });\n\t\treturn;\n\t}\n\n\tpi.sendUserMessage(prefixedContent);\n}\n\nexport function sendBuiltinCustomMessage<TDetails>(\n\tpi: ExtensionAPI,\n\troute: BuiltinSystemMessageRoute,\n\tmessage: Pick<CustomMessage<TDetails>, \"content\" | \"customType\" | \"details\" | \"display\">,\n\toptions?: BuiltinCustomMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(message.content);\n\tconst deliverAs = options?.deliverAs === \"nextTurn\" ? undefined : options?.deliverAs;\n\n\temitSenpiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\tkind: \"custom_message\",\n\t\t\tcustomType: message.customType,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs,\n\t\t\ttriggerTurn: options?.triggerTurn,\n\t\t}),\n\t);\n\n\tconst prefixedMessage = {\n\t\t...message,\n\t\tcontent: prefixedContent,\n\t};\n\n\tif (hasCustomMessageOptions(options)) {\n\t\tpi.sendMessage(prefixedMessage, {\n\t\t\ttriggerTurn: options.triggerTurn,\n\t\t\tdeliverAs: options.deliverAs,\n\t\t});\n\t\treturn;\n\t}\n\n\tpi.sendMessage(prefixedMessage);\n}\n\nexport function emitBuiltinSystemMessageFailure(\n\tpi: ExtensionAPI,\n\targs: {\n\t\troute: BuiltinSystemMessageRoute;\n\t\tsessionId?: string;\n\t\tkind: \"custom_message\" | \"user_message\";\n\t\tcontent: string | (TextContent | ImageContent)[];\n\t\tcustomType?: string;\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\ttriggerTurn?: boolean;\n\t\terrorMessage: string;\n\t},\n): void {\n\tconst prefixedContent = prefixContent(args.content);\n\n\temitSenpiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"failed\",\n\t\t\troute: args.route,\n\t\t\tsessionId: args.sessionId,\n\t\t\tkind: args.kind,\n\t\t\tcustomType: args.customType,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\ttriggerTurn: args.triggerTurn,\n\t\t\terrorMessage: args.errorMessage,\n\t\t}),\n\t);\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { type TodoItem } from "../state.js";
2
- export declare const CONTINUATION_DIRECTIVE = "[SYSTEM DIRECTIVE: SANEPI - TODO CONTINUATION]\n\nIncomplete tasks remain in your todo list. Continue working on the next pending task.\n\n- FIRST: Continue the first actionable remaining task now. If an in-progress task is already done, verify it and mark it completed before moving on\n- Proceed without asking for permission\n- Mark each task complete immediately when finished\n- Do not stop until all tasks are done\n- Do not reply with refusal, deferral, or a summary-only response\n- If a task is already complete, no longer needed, or blocked, verify that and update the todo list to a terminal state instead of leaving it pending\n- If you believe all work is already complete, the system is questioning your completion claim. Critically re-examine each todo item from a skeptical perspective, verify the work was actually done correctly, and update the todo list accordingly.";
2
+ export declare const CONTINUATION_DIRECTIVE = "[SYSTEM DIRECTIVE: SENPI - TODO CONTINUATION]\n\nIncomplete tasks remain in your todo list. Continue working on the next pending task.\n\n- FIRST: Continue the first actionable remaining task now. If an in-progress task is already done, verify it and mark it completed before moving on\n- Proceed without asking for permission\n- Mark each task complete immediately when finished\n- Do not stop until all tasks are done\n- Do not reply with refusal, deferral, or a summary-only response\n- If a task is already complete, no longer needed, or blocked, verify that and update the todo list to a terminal state instead of leaving it pending\n- If you believe all work is already complete, the system is questioning your completion claim. Critically re-examine each todo item from a skeptical perspective, verify the work was actually done correctly, and update the todo list accordingly.";
3
3
  export declare function countIncomplete(todos: TodoItem[]): number;
4
4
  export declare function buildContinuationPrompt(todos: TodoItem[]): string;
5
5
  //# sourceMappingURL=prompt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/todotools/continuation/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEhF,eAAO,MAAM,sBAAsB,03BAUmN,CAAC;AAEvP,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAEzD;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAmBjE","sourcesContent":["import { isIncompleteTodo, sanitizeTodoText, type TodoItem } from \"../state.js\";\n\nexport const CONTINUATION_DIRECTIVE = `[SYSTEM DIRECTIVE: SANEPI - TODO CONTINUATION]\n\nIncomplete tasks remain in your todo list. Continue working on the next pending task.\n\n- FIRST: Continue the first actionable remaining task now. If an in-progress task is already done, verify it and mark it completed before moving on\n- Proceed without asking for permission\n- Mark each task complete immediately when finished\n- Do not stop until all tasks are done\n- Do not reply with refusal, deferral, or a summary-only response\n- If a task is already complete, no longer needed, or blocked, verify that and update the todo list to a terminal state instead of leaving it pending\n- If you believe all work is already complete, the system is questioning your completion claim. Critically re-examine each todo item from a skeptical perspective, verify the work was actually done correctly, and update the todo list accordingly.`;\n\nexport function countIncomplete(todos: TodoItem[]): number {\n\treturn todos.filter(isIncompleteTodo).length;\n}\n\nexport function buildContinuationPrompt(todos: TodoItem[]): string {\n\tif (todos.length === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst completedCount = todos.filter((todo) => todo.status === \"completed\").length;\n\tconst remainingTodos = todos.filter(isIncompleteTodo);\n\tconst activeTotal = completedCount + remainingTodos.length;\n\tconst remainingLines = remainingTodos\n\t\t.map((todo) => `- [${todo.status}] ${sanitizeTodoText(todo.content)}`)\n\t\t.join(\"\\n\");\n\n\treturn `${CONTINUATION_DIRECTIVE}\n\n[Status: ${completedCount}/${activeTotal} completed, ${remainingTodos.length} remaining]\n\nRemaining tasks:\n${remainingLines}\n`;\n}\n"]}
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/todotools/continuation/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEhF,eAAO,MAAM,sBAAsB,y3BAUmN,CAAC;AAEvP,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAEzD;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAmBjE","sourcesContent":["import { isIncompleteTodo, sanitizeTodoText, type TodoItem } from \"../state.js\";\n\nexport const CONTINUATION_DIRECTIVE = `[SYSTEM DIRECTIVE: SENPI - TODO CONTINUATION]\n\nIncomplete tasks remain in your todo list. Continue working on the next pending task.\n\n- FIRST: Continue the first actionable remaining task now. If an in-progress task is already done, verify it and mark it completed before moving on\n- Proceed without asking for permission\n- Mark each task complete immediately when finished\n- Do not stop until all tasks are done\n- Do not reply with refusal, deferral, or a summary-only response\n- If a task is already complete, no longer needed, or blocked, verify that and update the todo list to a terminal state instead of leaving it pending\n- If you believe all work is already complete, the system is questioning your completion claim. Critically re-examine each todo item from a skeptical perspective, verify the work was actually done correctly, and update the todo list accordingly.`;\n\nexport function countIncomplete(todos: TodoItem[]): number {\n\treturn todos.filter(isIncompleteTodo).length;\n}\n\nexport function buildContinuationPrompt(todos: TodoItem[]): string {\n\tif (todos.length === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst completedCount = todos.filter((todo) => todo.status === \"completed\").length;\n\tconst remainingTodos = todos.filter(isIncompleteTodo);\n\tconst activeTotal = completedCount + remainingTodos.length;\n\tconst remainingLines = remainingTodos\n\t\t.map((todo) => `- [${todo.status}] ${sanitizeTodoText(todo.content)}`)\n\t\t.join(\"\\n\");\n\n\treturn `${CONTINUATION_DIRECTIVE}\n\n[Status: ${completedCount}/${activeTotal} completed, ${remainingTodos.length} remaining]\n\nRemaining tasks:\n${remainingLines}\n`;\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { isIncompleteTodo, sanitizeTodoText } from "../state.js";
2
- export const CONTINUATION_DIRECTIVE = `[SYSTEM DIRECTIVE: SANEPI - TODO CONTINUATION]
2
+ export const CONTINUATION_DIRECTIVE = `[SYSTEM DIRECTIVE: SENPI - TODO CONTINUATION]
3
3
 
4
4
  Incomplete tasks remain in your todo list. Continue working on the next pending task.
5
5
 
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/todotools/continuation/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAiB,MAAM,aAAa,CAAC;AAEhF,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;sPAUgN,CAAC;AAEvP,MAAM,UAAU,eAAe,CAAC,KAAiB,EAAU;IAC1D,OAAO,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC;AAAA,CAC7C;AAED,MAAM,UAAU,uBAAuB,CAAC,KAAiB,EAAU;IAClE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACX,CAAC;IAED,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC;IAClF,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACtD,MAAM,WAAW,GAAG,cAAc,GAAG,cAAc,CAAC,MAAM,CAAC;IAC3D,MAAM,cAAc,GAAG,cAAc;SACnC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,IAAI,CAAC,MAAM,KAAK,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;SACrE,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO,GAAG,sBAAsB;;WAEtB,cAAc,IAAI,WAAW,eAAe,cAAc,CAAC,MAAM;;;EAG1E,cAAc;CACf,CAAC;AAAA,CACD","sourcesContent":["import { isIncompleteTodo, sanitizeTodoText, type TodoItem } from \"../state.js\";\n\nexport const CONTINUATION_DIRECTIVE = `[SYSTEM DIRECTIVE: SANEPI - TODO CONTINUATION]\n\nIncomplete tasks remain in your todo list. Continue working on the next pending task.\n\n- FIRST: Continue the first actionable remaining task now. If an in-progress task is already done, verify it and mark it completed before moving on\n- Proceed without asking for permission\n- Mark each task complete immediately when finished\n- Do not stop until all tasks are done\n- Do not reply with refusal, deferral, or a summary-only response\n- If a task is already complete, no longer needed, or blocked, verify that and update the todo list to a terminal state instead of leaving it pending\n- If you believe all work is already complete, the system is questioning your completion claim. Critically re-examine each todo item from a skeptical perspective, verify the work was actually done correctly, and update the todo list accordingly.`;\n\nexport function countIncomplete(todos: TodoItem[]): number {\n\treturn todos.filter(isIncompleteTodo).length;\n}\n\nexport function buildContinuationPrompt(todos: TodoItem[]): string {\n\tif (todos.length === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst completedCount = todos.filter((todo) => todo.status === \"completed\").length;\n\tconst remainingTodos = todos.filter(isIncompleteTodo);\n\tconst activeTotal = completedCount + remainingTodos.length;\n\tconst remainingLines = remainingTodos\n\t\t.map((todo) => `- [${todo.status}] ${sanitizeTodoText(todo.content)}`)\n\t\t.join(\"\\n\");\n\n\treturn `${CONTINUATION_DIRECTIVE}\n\n[Status: ${completedCount}/${activeTotal} completed, ${remainingTodos.length} remaining]\n\nRemaining tasks:\n${remainingLines}\n`;\n}\n"]}
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/todotools/continuation/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAiB,MAAM,aAAa,CAAC;AAEhF,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;sPAUgN,CAAC;AAEvP,MAAM,UAAU,eAAe,CAAC,KAAiB,EAAU;IAC1D,OAAO,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC;AAAA,CAC7C;AAED,MAAM,UAAU,uBAAuB,CAAC,KAAiB,EAAU;IAClE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACX,CAAC;IAED,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC;IAClF,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACtD,MAAM,WAAW,GAAG,cAAc,GAAG,cAAc,CAAC,MAAM,CAAC;IAC3D,MAAM,cAAc,GAAG,cAAc;SACnC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,IAAI,CAAC,MAAM,KAAK,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;SACrE,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO,GAAG,sBAAsB;;WAEtB,cAAc,IAAI,WAAW,eAAe,cAAc,CAAC,MAAM;;;EAG1E,cAAc;CACf,CAAC;AAAA,CACD","sourcesContent":["import { isIncompleteTodo, sanitizeTodoText, type TodoItem } from \"../state.js\";\n\nexport const CONTINUATION_DIRECTIVE = `[SYSTEM DIRECTIVE: SENPI - TODO CONTINUATION]\n\nIncomplete tasks remain in your todo list. Continue working on the next pending task.\n\n- FIRST: Continue the first actionable remaining task now. If an in-progress task is already done, verify it and mark it completed before moving on\n- Proceed without asking for permission\n- Mark each task complete immediately when finished\n- Do not stop until all tasks are done\n- Do not reply with refusal, deferral, or a summary-only response\n- If a task is already complete, no longer needed, or blocked, verify that and update the todo list to a terminal state instead of leaving it pending\n- If you believe all work is already complete, the system is questioning your completion claim. Critically re-examine each todo item from a skeptical perspective, verify the work was actually done correctly, and update the todo list accordingly.`;\n\nexport function countIncomplete(todos: TodoItem[]): number {\n\treturn todos.filter(isIncompleteTodo).length;\n}\n\nexport function buildContinuationPrompt(todos: TodoItem[]): string {\n\tif (todos.length === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst completedCount = todos.filter((todo) => todo.status === \"completed\").length;\n\tconst remainingTodos = todos.filter(isIncompleteTodo);\n\tconst activeTotal = completedCount + remainingTodos.length;\n\tconst remainingLines = remainingTodos\n\t\t.map((todo) => `- [${todo.status}] ${sanitizeTodoText(todo.content)}`)\n\t\t.join(\"\\n\");\n\n\treturn `${CONTINUATION_DIRECTIVE}\n\n[Status: ${completedCount}/${activeTotal} completed, ${remainingTodos.length} remaining]\n\nRemaining tasks:\n${remainingLines}\n`;\n}\n"]}
@@ -15,7 +15,7 @@ type BranchEntry = {
15
15
  data?: unknown;
16
16
  message?: unknown;
17
17
  };
18
- export declare const TODO_STATE_ENTRY_TYPE = "sanepi.todo-state";
18
+ export declare const TODO_STATE_ENTRY_TYPE = "senpi.todo-state";
19
19
  export declare function isTerminalTodoStatus(status: string): boolean;
20
20
  export declare function isIncompleteTodo(todo: TodoItem): boolean;
21
21
  export declare function sanitizeTodoText(text: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/state.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,QAAQ,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,QAAQ,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC5B,KAAK,EAAE,QAAQ,EAAE,CAAC;CAClB,CAAC;AAEF,KAAK,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAE5F,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AAEzD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAExD;AAMD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMrD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKpD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,GAAG,SAAS,CAK1E;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,CAK9D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAM5D;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,EAAE,CAEnE;AAED,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,QAAQ,EAAE,CA4BlF","sourcesContent":["import stripAnsi from \"strip-ansi\";\n\nexport type TodoItem = {\n\tcontent: string;\n\tstatus: string;\n\tpriority: string;\n};\n\nexport type TodoWriteDetails = {\n\ttodos: TodoItem[];\n};\n\nexport type TodoStateEntry = {\n\ttodos: TodoItem[];\n};\n\ntype BranchEntry = { type: string; customType?: string; data?: unknown; message?: unknown };\n\nexport const TODO_STATE_ENTRY_TYPE = \"sanepi.todo-state\";\n\nexport function isTerminalTodoStatus(status: string): boolean {\n\treturn status === \"completed\" || status === \"cancelled\";\n}\n\nexport function isIncompleteTodo(todo: TodoItem): boolean {\n\treturn !isTerminalTodoStatus(todo.status);\n}\n\nfunction countOpenTodos(todos: TodoItem[]): number {\n\treturn todos.filter(isIncompleteTodo).length;\n}\n\nexport function sanitizeTodoText(text: string): string {\n\treturn stripAnsi(text)\n\t\t.replace(/[\\r\\n]+/g, \" \")\n\t\t.replace(/[\\u0000-\\u001F\\u007F-\\u009F]/g, \" \")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim();\n}\n\nexport function getTodoMarker(status: string): string {\n\tif (status === \"completed\") return \"[✓]\";\n\tif (status === \"in_progress\") return \"[•]\";\n\tif (status === \"cancelled\") return \"[×]\";\n\treturn \"[ ]\";\n}\n\nexport function getTodoWidgetLines(todos: TodoItem[]): string[] | undefined {\n\tif (todos.length === 0 || !todos.some(isIncompleteTodo)) {\n\t\treturn undefined;\n\t}\n\treturn [\"Todo\", ...todos.map((todo) => `${getTodoMarker(todo.status)} ${sanitizeTodoText(todo.content)}`)];\n}\n\nexport function getTodoResultLines(todos: TodoItem[]): string[] {\n\treturn [\n\t\t`${countOpenTodos(todos)} todos`,\n\t\t...todos.map((todo) => `${getTodoMarker(todo.status)} ${sanitizeTodoText(todo.content)}`),\n\t];\n}\n\nexport function isTodoItem(value: unknown): value is TodoItem {\n\tif (typeof value !== \"object\" || value === null) {\n\t\treturn false;\n\t}\n\tconst item = value as Record<string, unknown>;\n\treturn typeof item.content === \"string\" && typeof item.status === \"string\" && typeof item.priority === \"string\";\n}\n\nexport function isTodoItemArray(value: unknown): value is TodoItem[] {\n\treturn Array.isArray(value) && value.every(isTodoItem);\n}\n\nexport function getLatestTodosFromBranchEntries(entries: BranchEntry[]): TodoItem[] {\n\tlet todos: TodoItem[] = [];\n\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"custom\" && entry.customType === TODO_STATE_ENTRY_TYPE) {\n\t\t\tconst data = entry.data as TodoStateEntry | undefined;\n\t\t\tif (isTodoItemArray(data?.todos)) {\n\t\t\t\ttodos = data.todos.map((todo) => ({ ...todo }));\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (entry.type !== \"message\" || typeof entry.message !== \"object\" || entry.message === null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst message = entry.message as { role?: string; toolName?: string; details?: unknown };\n\t\tif (message.role !== \"toolResult\" || message.toolName !== \"todowrite\") {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst details = message.details as TodoWriteDetails | undefined;\n\t\tif (isTodoItemArray(details?.todos)) {\n\t\t\ttodos = details.todos.map((todo) => ({ ...todo }));\n\t\t}\n\t}\n\n\treturn todos;\n}\n"]}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/state.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,QAAQ,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,QAAQ,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC5B,KAAK,EAAE,QAAQ,EAAE,CAAC;CAClB,CAAC;AAEF,KAAK,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAE5F,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAExD;AAMD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMrD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKpD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,GAAG,SAAS,CAK1E;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,CAK9D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAM5D;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,EAAE,CAEnE;AAED,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,QAAQ,EAAE,CA4BlF","sourcesContent":["import { stripAnsi } from \"../../../../utils/ansi.js\";\n\nexport type TodoItem = {\n\tcontent: string;\n\tstatus: string;\n\tpriority: string;\n};\n\nexport type TodoWriteDetails = {\n\ttodos: TodoItem[];\n};\n\nexport type TodoStateEntry = {\n\ttodos: TodoItem[];\n};\n\ntype BranchEntry = { type: string; customType?: string; data?: unknown; message?: unknown };\n\nexport const TODO_STATE_ENTRY_TYPE = \"senpi.todo-state\";\n\nexport function isTerminalTodoStatus(status: string): boolean {\n\treturn status === \"completed\" || status === \"cancelled\";\n}\n\nexport function isIncompleteTodo(todo: TodoItem): boolean {\n\treturn !isTerminalTodoStatus(todo.status);\n}\n\nfunction countOpenTodos(todos: TodoItem[]): number {\n\treturn todos.filter(isIncompleteTodo).length;\n}\n\nexport function sanitizeTodoText(text: string): string {\n\treturn stripAnsi(text)\n\t\t.replace(/[\\r\\n]+/g, \" \")\n\t\t.replace(/[\\u0000-\\u001F\\u007F-\\u009F]/g, \" \")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim();\n}\n\nexport function getTodoMarker(status: string): string {\n\tif (status === \"completed\") return \"[✓]\";\n\tif (status === \"in_progress\") return \"[•]\";\n\tif (status === \"cancelled\") return \"[×]\";\n\treturn \"[ ]\";\n}\n\nexport function getTodoWidgetLines(todos: TodoItem[]): string[] | undefined {\n\tif (todos.length === 0 || !todos.some(isIncompleteTodo)) {\n\t\treturn undefined;\n\t}\n\treturn [\"Todo\", ...todos.map((todo) => `${getTodoMarker(todo.status)} ${sanitizeTodoText(todo.content)}`)];\n}\n\nexport function getTodoResultLines(todos: TodoItem[]): string[] {\n\treturn [\n\t\t`${countOpenTodos(todos)} todos`,\n\t\t...todos.map((todo) => `${getTodoMarker(todo.status)} ${sanitizeTodoText(todo.content)}`),\n\t];\n}\n\nexport function isTodoItem(value: unknown): value is TodoItem {\n\tif (typeof value !== \"object\" || value === null) {\n\t\treturn false;\n\t}\n\tconst item = value as Record<string, unknown>;\n\treturn typeof item.content === \"string\" && typeof item.status === \"string\" && typeof item.priority === \"string\";\n}\n\nexport function isTodoItemArray(value: unknown): value is TodoItem[] {\n\treturn Array.isArray(value) && value.every(isTodoItem);\n}\n\nexport function getLatestTodosFromBranchEntries(entries: BranchEntry[]): TodoItem[] {\n\tlet todos: TodoItem[] = [];\n\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"custom\" && entry.customType === TODO_STATE_ENTRY_TYPE) {\n\t\t\tconst data = entry.data as TodoStateEntry | undefined;\n\t\t\tif (isTodoItemArray(data?.todos)) {\n\t\t\t\ttodos = data.todos.map((todo) => ({ ...todo }));\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (entry.type !== \"message\" || typeof entry.message !== \"object\" || entry.message === null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst message = entry.message as { role?: string; toolName?: string; details?: unknown };\n\t\tif (message.role !== \"toolResult\" || message.toolName !== \"todowrite\") {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst details = message.details as TodoWriteDetails | undefined;\n\t\tif (isTodoItemArray(details?.todos)) {\n\t\t\ttodos = details.todos.map((todo) => ({ ...todo }));\n\t\t}\n\t}\n\n\treturn todos;\n}\n"]}
@@ -1,5 +1,5 @@
1
- import stripAnsi from "strip-ansi";
2
- export const TODO_STATE_ENTRY_TYPE = "sanepi.todo-state";
1
+ import { stripAnsi } from "../../../../utils/ansi.js";
2
+ export const TODO_STATE_ENTRY_TYPE = "senpi.todo-state";
3
3
  export function isTerminalTodoStatus(status) {
4
4
  return status === "completed" || status === "cancelled";
5
5
  }
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/state.ts"],"names":[],"mappings":"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","sourcesContent":["import stripAnsi from \"strip-ansi\";\n\nexport type TodoItem = {\n\tcontent: string;\n\tstatus: string;\n\tpriority: string;\n};\n\nexport type TodoWriteDetails = {\n\ttodos: TodoItem[];\n};\n\nexport type TodoStateEntry = {\n\ttodos: TodoItem[];\n};\n\ntype BranchEntry = { type: string; customType?: string; data?: unknown; message?: unknown };\n\nexport const TODO_STATE_ENTRY_TYPE = \"sanepi.todo-state\";\n\nexport function isTerminalTodoStatus(status: string): boolean {\n\treturn status === \"completed\" || status === \"cancelled\";\n}\n\nexport function isIncompleteTodo(todo: TodoItem): boolean {\n\treturn !isTerminalTodoStatus(todo.status);\n}\n\nfunction countOpenTodos(todos: TodoItem[]): number {\n\treturn todos.filter(isIncompleteTodo).length;\n}\n\nexport function sanitizeTodoText(text: string): string {\n\treturn stripAnsi(text)\n\t\t.replace(/[\\r\\n]+/g, \" \")\n\t\t.replace(/[\\u0000-\\u001F\\u007F-\\u009F]/g, \" \")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim();\n}\n\nexport function getTodoMarker(status: string): string {\n\tif (status === \"completed\") return \"[✓]\";\n\tif (status === \"in_progress\") return \"[•]\";\n\tif (status === \"cancelled\") return \"[×]\";\n\treturn \"[ ]\";\n}\n\nexport function getTodoWidgetLines(todos: TodoItem[]): string[] | undefined {\n\tif (todos.length === 0 || !todos.some(isIncompleteTodo)) {\n\t\treturn undefined;\n\t}\n\treturn [\"Todo\", ...todos.map((todo) => `${getTodoMarker(todo.status)} ${sanitizeTodoText(todo.content)}`)];\n}\n\nexport function getTodoResultLines(todos: TodoItem[]): string[] {\n\treturn [\n\t\t`${countOpenTodos(todos)} todos`,\n\t\t...todos.map((todo) => `${getTodoMarker(todo.status)} ${sanitizeTodoText(todo.content)}`),\n\t];\n}\n\nexport function isTodoItem(value: unknown): value is TodoItem {\n\tif (typeof value !== \"object\" || value === null) {\n\t\treturn false;\n\t}\n\tconst item = value as Record<string, unknown>;\n\treturn typeof item.content === \"string\" && typeof item.status === \"string\" && typeof item.priority === \"string\";\n}\n\nexport function isTodoItemArray(value: unknown): value is TodoItem[] {\n\treturn Array.isArray(value) && value.every(isTodoItem);\n}\n\nexport function getLatestTodosFromBranchEntries(entries: BranchEntry[]): TodoItem[] {\n\tlet todos: TodoItem[] = [];\n\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"custom\" && entry.customType === TODO_STATE_ENTRY_TYPE) {\n\t\t\tconst data = entry.data as TodoStateEntry | undefined;\n\t\t\tif (isTodoItemArray(data?.todos)) {\n\t\t\t\ttodos = data.todos.map((todo) => ({ ...todo }));\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (entry.type !== \"message\" || typeof entry.message !== \"object\" || entry.message === null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst message = entry.message as { role?: string; toolName?: string; details?: unknown };\n\t\tif (message.role !== \"toolResult\" || message.toolName !== \"todowrite\") {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst details = message.details as TodoWriteDetails | undefined;\n\t\tif (isTodoItemArray(details?.todos)) {\n\t\t\ttodos = details.todos.map((todo) => ({ ...todo }));\n\t\t}\n\t}\n\n\treturn todos;\n}\n"]}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAkBtD,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AAExD,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAW;IAC7D,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,KAAK,WAAW,CAAC;AAAA,CACxD;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAc,EAAW;IACzD,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAAA,CAC1C;AAED,SAAS,cAAc,CAAC,KAAiB,EAAU;IAClD,OAAO,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC;AAAA,CAC7C;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAU;IACtD,OAAO,SAAS,CAAC,IAAI,CAAC;SACpB,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;SACxB,OAAO,CAAC,+BAA+B,EAAE,GAAG,CAAC;SAC7C,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;AAAA,CACT;AAED,MAAM,UAAU,aAAa,CAAC,MAAc,EAAU;IACrD,IAAI,MAAM,KAAK,WAAW;QAAE,OAAO,OAAK,CAAC;IACzC,IAAI,MAAM,KAAK,aAAa;QAAE,OAAO,OAAK,CAAC;IAC3C,IAAI,MAAM,KAAK,WAAW;QAAE,OAAO,MAAK,CAAC;IACzC,OAAO,KAAK,CAAC;AAAA,CACb;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAiB,EAAwB;IAC3E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACzD,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;AAAA,CAC3G;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAiB,EAAY;IAC/D,OAAO;QACN,GAAG,cAAc,CAAC,KAAK,CAAC,QAAQ;QAChC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;KACzF,CAAC;AAAA,CACF;AAED,MAAM,UAAU,UAAU,CAAC,KAAc,EAAqB;IAC7D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACjD,OAAO,KAAK,CAAC;IACd,CAAC;IACD,MAAM,IAAI,GAAG,KAAgC,CAAC;IAC9C,OAAO,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC;AAAA,CAChH;AAED,MAAM,UAAU,eAAe,CAAC,KAAc,EAAuB;IACpE,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;AAAA,CACvD;AAED,MAAM,UAAU,+BAA+B,CAAC,OAAsB,EAAc;IACnF,IAAI,KAAK,GAAe,EAAE,CAAC;IAE3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,KAAK,qBAAqB,EAAE,CAAC;YAC3E,MAAM,IAAI,GAAG,KAAK,CAAC,IAAkC,CAAC;YACtD,IAAI,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;gBAClC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;YACjD,CAAC;YACD,SAAS;QACV,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YAC7F,SAAS;QACV,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,OAAkE,CAAC;QACzF,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,IAAI,OAAO,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;YACvE,SAAS;QACV,CAAC;QAED,MAAM,OAAO,GAAG,OAAO,CAAC,OAAuC,CAAC;QAChE,IAAI,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;YACrC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;QACpD,CAAC;IACF,CAAC;IAED,OAAO,KAAK,CAAC;AAAA,CACb","sourcesContent":["import { stripAnsi } from \"../../../../utils/ansi.js\";\n\nexport type TodoItem = {\n\tcontent: string;\n\tstatus: string;\n\tpriority: string;\n};\n\nexport type TodoWriteDetails = {\n\ttodos: TodoItem[];\n};\n\nexport type TodoStateEntry = {\n\ttodos: TodoItem[];\n};\n\ntype BranchEntry = { type: string; customType?: string; data?: unknown; message?: unknown };\n\nexport const TODO_STATE_ENTRY_TYPE = \"senpi.todo-state\";\n\nexport function isTerminalTodoStatus(status: string): boolean {\n\treturn status === \"completed\" || status === \"cancelled\";\n}\n\nexport function isIncompleteTodo(todo: TodoItem): boolean {\n\treturn !isTerminalTodoStatus(todo.status);\n}\n\nfunction countOpenTodos(todos: TodoItem[]): number {\n\treturn todos.filter(isIncompleteTodo).length;\n}\n\nexport function sanitizeTodoText(text: string): string {\n\treturn stripAnsi(text)\n\t\t.replace(/[\\r\\n]+/g, \" \")\n\t\t.replace(/[\\u0000-\\u001F\\u007F-\\u009F]/g, \" \")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim();\n}\n\nexport function getTodoMarker(status: string): string {\n\tif (status === \"completed\") return \"[✓]\";\n\tif (status === \"in_progress\") return \"[•]\";\n\tif (status === \"cancelled\") return \"[×]\";\n\treturn \"[ ]\";\n}\n\nexport function getTodoWidgetLines(todos: TodoItem[]): string[] | undefined {\n\tif (todos.length === 0 || !todos.some(isIncompleteTodo)) {\n\t\treturn undefined;\n\t}\n\treturn [\"Todo\", ...todos.map((todo) => `${getTodoMarker(todo.status)} ${sanitizeTodoText(todo.content)}`)];\n}\n\nexport function getTodoResultLines(todos: TodoItem[]): string[] {\n\treturn [\n\t\t`${countOpenTodos(todos)} todos`,\n\t\t...todos.map((todo) => `${getTodoMarker(todo.status)} ${sanitizeTodoText(todo.content)}`),\n\t];\n}\n\nexport function isTodoItem(value: unknown): value is TodoItem {\n\tif (typeof value !== \"object\" || value === null) {\n\t\treturn false;\n\t}\n\tconst item = value as Record<string, unknown>;\n\treturn typeof item.content === \"string\" && typeof item.status === \"string\" && typeof item.priority === \"string\";\n}\n\nexport function isTodoItemArray(value: unknown): value is TodoItem[] {\n\treturn Array.isArray(value) && value.every(isTodoItem);\n}\n\nexport function getLatestTodosFromBranchEntries(entries: BranchEntry[]): TodoItem[] {\n\tlet todos: TodoItem[] = [];\n\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"custom\" && entry.customType === TODO_STATE_ENTRY_TYPE) {\n\t\t\tconst data = entry.data as TodoStateEntry | undefined;\n\t\t\tif (isTodoItemArray(data?.todos)) {\n\t\t\t\ttodos = data.todos.map((todo) => ({ ...todo }));\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (entry.type !== \"message\" || typeof entry.message !== \"object\" || entry.message === null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst message = entry.message as { role?: string; toolName?: string; details?: unknown };\n\t\tif (message.role !== \"toolResult\" || message.toolName !== \"todowrite\") {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst details = message.details as TodoWriteDetails | undefined;\n\t\tif (isTodoItemArray(details?.todos)) {\n\t\t\ttodos = details.todos.map((todo) => ({ ...todo }));\n\t\t}\n\t}\n\n\treturn todos;\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import type { ImageContent, TextContent } from "@earendil-works/pi-ai";
2
2
  import type { ExtensionAPI } from "../../types.js";
3
- export declare const SANEPI_SYSTEM_PREFIX = "[system:sanepi]";
4
- export declare const SANEPI_CONVERSATION_EVENT = "sanepi:conversation";
3
+ export declare const SENPI_SYSTEM_PREFIX = "[system:senpi]";
4
+ export declare const SENPI_CONVERSATION_EVENT = "senpi:conversation";
5
5
  export type TodoSystemMessageRoute = "todotools.continuation";
6
6
  export type TodoConversationAction = "injected" | "failed";
7
7
  export interface TodoConversationEvent {
@@ -12,7 +12,7 @@ export interface TodoConversationEvent {
12
12
  sessionId?: string;
13
13
  timestamp: number;
14
14
  conversation: {
15
- prefix: typeof SANEPI_SYSTEM_PREFIX;
15
+ prefix: typeof SENPI_SYSTEM_PREFIX;
16
16
  kind: "user_message";
17
17
  deliverAs?: "steer" | "followUp";
18
18
  };
@@ -1 +1 @@
1
- {"version":3,"file":"system-messages.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/system-messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AACtD,eAAO,MAAM,yBAAyB,wBAAwB,CAAC;AAE/D,MAAM,MAAM,sBAAsB,GAAG,wBAAwB,CAAC;AAC9D,MAAM,MAAM,sBAAsB,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE3D,MAAM,WAAW,qBAAqB;IACrC,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,KAAK,EAAE,sBAAsB,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE;QACb,MAAM,EAAE,OAAO,oBAAoB,CAAC;QACpC,IAAI,EAAE,cAAc,CAAC;QACrB,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;KACjC,CAAC;IACF,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,sBAAsB;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;CACjC;AA0ED,wBAAgB,mBAAmB,CAClC,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,sBAAsB,EAC7B,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,EAChD,OAAO,CAAC,EAAE,sBAAsB,GAC9B,IAAI,CAoBN;AAED,wBAAgB,4BAA4B,CAC3C,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE;IACL,KAAK,EAAE,sBAAsB,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC;IACjD,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;CACrB,GACC,IAAI,CAcN","sourcesContent":["import type { ImageContent, TextContent } from \"@earendil-works/pi-ai\";\nimport type { ExtensionAPI } from \"../../types.js\";\n\nexport const SANEPI_SYSTEM_PREFIX = \"[system:sanepi]\";\nexport const SANEPI_CONVERSATION_EVENT = \"sanepi:conversation\";\n\nexport type TodoSystemMessageRoute = \"todotools.continuation\";\nexport type TodoConversationAction = \"injected\" | \"failed\";\n\nexport interface TodoConversationEvent {\n\tversion: 1;\n\tsource: \"builtin\";\n\taction: TodoConversationAction;\n\troute: TodoSystemMessageRoute;\n\tsessionId?: string;\n\ttimestamp: number;\n\tconversation: {\n\t\tprefix: typeof SANEPI_SYSTEM_PREFIX;\n\t\tkind: \"user_message\";\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t};\n\ttext: string;\n\terrorMessage?: string;\n}\n\nexport interface TodoUserMessageOptions {\n\tsessionId?: string;\n\tdeliverAs?: \"steer\" | \"followUp\";\n}\n\nfunction prefixText(text: string): string {\n\treturn text.startsWith(SANEPI_SYSTEM_PREFIX) ? text : `${SANEPI_SYSTEM_PREFIX}\\n${text}`;\n}\n\nfunction prefixContent(content: string | (TextContent | ImageContent)[]): string | (TextContent | ImageContent)[] {\n\tif (typeof content === \"string\") {\n\t\treturn prefixText(content);\n\t}\n\n\tconst firstTextIndex = content.findIndex((part) => part.type === \"text\");\n\tif (firstTextIndex === -1) {\n\t\treturn [{ type: \"text\", text: SANEPI_SYSTEM_PREFIX }, ...content];\n\t}\n\n\treturn content.map((part, index) => {\n\t\tif (part.type !== \"text\" || index !== firstTextIndex) {\n\t\t\treturn part;\n\t\t}\n\n\t\treturn {\n\t\t\t...part,\n\t\t\ttext: prefixText(part.text),\n\t\t};\n\t});\n}\n\nfunction extractText(content: string | (TextContent | ImageContent)[]): string {\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\n\treturn content\n\t\t.filter((part): part is TextContent => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\");\n}\n\nfunction emitTodoConversationEvent(pi: ExtensionAPI, event: TodoConversationEvent): void {\n\tpi.events.emit(SANEPI_CONVERSATION_EVENT, event);\n}\n\nfunction createBaseEvent(args: {\n\taction: TodoConversationAction;\n\troute: TodoSystemMessageRoute;\n\tsessionId?: string;\n\tdeliverAs?: \"steer\" | \"followUp\";\n\ttext: string;\n\terrorMessage?: string;\n}): TodoConversationEvent {\n\treturn {\n\t\tversion: 1,\n\t\tsource: \"builtin\",\n\t\taction: args.action,\n\t\troute: args.route,\n\t\tsessionId: args.sessionId,\n\t\ttimestamp: Date.now(),\n\t\tconversation: {\n\t\t\tprefix: SANEPI_SYSTEM_PREFIX,\n\t\t\tkind: \"user_message\",\n\t\t\tdeliverAs: args.deliverAs,\n\t\t},\n\t\ttext: args.text,\n\t\terrorMessage: args.errorMessage,\n\t};\n}\n\nfunction hasUserMessageOptions(\n\toptions: TodoUserMessageOptions | undefined,\n): options is TodoUserMessageOptions & { deliverAs: \"steer\" | \"followUp\" } {\n\treturn options?.deliverAs !== undefined;\n}\n\nexport function sendTodoUserMessage(\n\tpi: ExtensionAPI,\n\troute: TodoSystemMessageRoute,\n\tcontent: string | (TextContent | ImageContent)[],\n\toptions?: TodoUserMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(content);\n\n\temitTodoConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: options?.deliverAs,\n\t\t}),\n\t);\n\n\tif (hasUserMessageOptions(options)) {\n\t\tpi.sendUserMessage(prefixedContent, { deliverAs: options.deliverAs });\n\t\treturn;\n\t}\n\n\tpi.sendUserMessage(prefixedContent);\n}\n\nexport function emitTodoSystemMessageFailure(\n\tpi: ExtensionAPI,\n\targs: {\n\t\troute: TodoSystemMessageRoute;\n\t\tsessionId?: string;\n\t\tcontent: string | (TextContent | ImageContent)[];\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\terrorMessage: string;\n\t},\n): void {\n\tconst prefixedContent = prefixContent(args.content);\n\n\temitTodoConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"failed\",\n\t\t\troute: args.route,\n\t\t\tsessionId: args.sessionId,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\terrorMessage: args.errorMessage,\n\t\t}),\n\t);\n}\n"]}
1
+ {"version":3,"file":"system-messages.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/system-messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AACpD,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAE7D,MAAM,MAAM,sBAAsB,GAAG,wBAAwB,CAAC;AAC9D,MAAM,MAAM,sBAAsB,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE3D,MAAM,WAAW,qBAAqB;IACrC,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,KAAK,EAAE,sBAAsB,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE;QACb,MAAM,EAAE,OAAO,mBAAmB,CAAC;QACnC,IAAI,EAAE,cAAc,CAAC;QACrB,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;KACjC,CAAC;IACF,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,sBAAsB;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;CACjC;AA0ED,wBAAgB,mBAAmB,CAClC,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,sBAAsB,EAC7B,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,EAChD,OAAO,CAAC,EAAE,sBAAsB,GAC9B,IAAI,CAoBN;AAED,wBAAgB,4BAA4B,CAC3C,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE;IACL,KAAK,EAAE,sBAAsB,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC;IACjD,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;CACrB,GACC,IAAI,CAcN","sourcesContent":["import type { ImageContent, TextContent } from \"@earendil-works/pi-ai\";\nimport type { ExtensionAPI } from \"../../types.js\";\n\nexport const SENPI_SYSTEM_PREFIX = \"[system:senpi]\";\nexport const SENPI_CONVERSATION_EVENT = \"senpi:conversation\";\n\nexport type TodoSystemMessageRoute = \"todotools.continuation\";\nexport type TodoConversationAction = \"injected\" | \"failed\";\n\nexport interface TodoConversationEvent {\n\tversion: 1;\n\tsource: \"builtin\";\n\taction: TodoConversationAction;\n\troute: TodoSystemMessageRoute;\n\tsessionId?: string;\n\ttimestamp: number;\n\tconversation: {\n\t\tprefix: typeof SENPI_SYSTEM_PREFIX;\n\t\tkind: \"user_message\";\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t};\n\ttext: string;\n\terrorMessage?: string;\n}\n\nexport interface TodoUserMessageOptions {\n\tsessionId?: string;\n\tdeliverAs?: \"steer\" | \"followUp\";\n}\n\nfunction prefixText(text: string): string {\n\treturn text.startsWith(SENPI_SYSTEM_PREFIX) ? text : `${SENPI_SYSTEM_PREFIX}\\n${text}`;\n}\n\nfunction prefixContent(content: string | (TextContent | ImageContent)[]): string | (TextContent | ImageContent)[] {\n\tif (typeof content === \"string\") {\n\t\treturn prefixText(content);\n\t}\n\n\tconst firstTextIndex = content.findIndex((part) => part.type === \"text\");\n\tif (firstTextIndex === -1) {\n\t\treturn [{ type: \"text\", text: SENPI_SYSTEM_PREFIX }, ...content];\n\t}\n\n\treturn content.map((part, index) => {\n\t\tif (part.type !== \"text\" || index !== firstTextIndex) {\n\t\t\treturn part;\n\t\t}\n\n\t\treturn {\n\t\t\t...part,\n\t\t\ttext: prefixText(part.text),\n\t\t};\n\t});\n}\n\nfunction extractText(content: string | (TextContent | ImageContent)[]): string {\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\n\treturn content\n\t\t.filter((part): part is TextContent => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\");\n}\n\nfunction emitTodoConversationEvent(pi: ExtensionAPI, event: TodoConversationEvent): void {\n\tpi.events.emit(SENPI_CONVERSATION_EVENT, event);\n}\n\nfunction createBaseEvent(args: {\n\taction: TodoConversationAction;\n\troute: TodoSystemMessageRoute;\n\tsessionId?: string;\n\tdeliverAs?: \"steer\" | \"followUp\";\n\ttext: string;\n\terrorMessage?: string;\n}): TodoConversationEvent {\n\treturn {\n\t\tversion: 1,\n\t\tsource: \"builtin\",\n\t\taction: args.action,\n\t\troute: args.route,\n\t\tsessionId: args.sessionId,\n\t\ttimestamp: Date.now(),\n\t\tconversation: {\n\t\t\tprefix: SENPI_SYSTEM_PREFIX,\n\t\t\tkind: \"user_message\",\n\t\t\tdeliverAs: args.deliverAs,\n\t\t},\n\t\ttext: args.text,\n\t\terrorMessage: args.errorMessage,\n\t};\n}\n\nfunction hasUserMessageOptions(\n\toptions: TodoUserMessageOptions | undefined,\n): options is TodoUserMessageOptions & { deliverAs: \"steer\" | \"followUp\" } {\n\treturn options?.deliverAs !== undefined;\n}\n\nexport function sendTodoUserMessage(\n\tpi: ExtensionAPI,\n\troute: TodoSystemMessageRoute,\n\tcontent: string | (TextContent | ImageContent)[],\n\toptions?: TodoUserMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(content);\n\n\temitTodoConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: options?.deliverAs,\n\t\t}),\n\t);\n\n\tif (hasUserMessageOptions(options)) {\n\t\tpi.sendUserMessage(prefixedContent, { deliverAs: options.deliverAs });\n\t\treturn;\n\t}\n\n\tpi.sendUserMessage(prefixedContent);\n}\n\nexport function emitTodoSystemMessageFailure(\n\tpi: ExtensionAPI,\n\targs: {\n\t\troute: TodoSystemMessageRoute;\n\t\tsessionId?: string;\n\t\tcontent: string | (TextContent | ImageContent)[];\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\terrorMessage: string;\n\t},\n): void {\n\tconst prefixedContent = prefixContent(args.content);\n\n\temitTodoConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"failed\",\n\t\t\troute: args.route,\n\t\t\tsessionId: args.sessionId,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\terrorMessage: args.errorMessage,\n\t\t}),\n\t);\n}\n"]}
@@ -1,7 +1,7 @@
1
- export const SANEPI_SYSTEM_PREFIX = "[system:sanepi]";
2
- export const SANEPI_CONVERSATION_EVENT = "sanepi:conversation";
1
+ export const SENPI_SYSTEM_PREFIX = "[system:senpi]";
2
+ export const SENPI_CONVERSATION_EVENT = "senpi:conversation";
3
3
  function prefixText(text) {
4
- return text.startsWith(SANEPI_SYSTEM_PREFIX) ? text : `${SANEPI_SYSTEM_PREFIX}\n${text}`;
4
+ return text.startsWith(SENPI_SYSTEM_PREFIX) ? text : `${SENPI_SYSTEM_PREFIX}\n${text}`;
5
5
  }
6
6
  function prefixContent(content) {
7
7
  if (typeof content === "string") {
@@ -9,7 +9,7 @@ function prefixContent(content) {
9
9
  }
10
10
  const firstTextIndex = content.findIndex((part) => part.type === "text");
11
11
  if (firstTextIndex === -1) {
12
- return [{ type: "text", text: SANEPI_SYSTEM_PREFIX }, ...content];
12
+ return [{ type: "text", text: SENPI_SYSTEM_PREFIX }, ...content];
13
13
  }
14
14
  return content.map((part, index) => {
15
15
  if (part.type !== "text" || index !== firstTextIndex) {
@@ -31,7 +31,7 @@ function extractText(content) {
31
31
  .join("\n");
32
32
  }
33
33
  function emitTodoConversationEvent(pi, event) {
34
- pi.events.emit(SANEPI_CONVERSATION_EVENT, event);
34
+ pi.events.emit(SENPI_CONVERSATION_EVENT, event);
35
35
  }
36
36
  function createBaseEvent(args) {
37
37
  return {
@@ -42,7 +42,7 @@ function createBaseEvent(args) {
42
42
  sessionId: args.sessionId,
43
43
  timestamp: Date.now(),
44
44
  conversation: {
45
- prefix: SANEPI_SYSTEM_PREFIX,
45
+ prefix: SENPI_SYSTEM_PREFIX,
46
46
  kind: "user_message",
47
47
  deliverAs: args.deliverAs,
48
48
  },
@@ -1 +1 @@
1
- {"version":3,"file":"system-messages.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/system-messages.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ImageContent, TextContent } from \"@earendil-works/pi-ai\";\nimport type { ExtensionAPI } from \"../../types.js\";\n\nexport const SANEPI_SYSTEM_PREFIX = \"[system:sanepi]\";\nexport const SANEPI_CONVERSATION_EVENT = \"sanepi:conversation\";\n\nexport type TodoSystemMessageRoute = \"todotools.continuation\";\nexport type TodoConversationAction = \"injected\" | \"failed\";\n\nexport interface TodoConversationEvent {\n\tversion: 1;\n\tsource: \"builtin\";\n\taction: TodoConversationAction;\n\troute: TodoSystemMessageRoute;\n\tsessionId?: string;\n\ttimestamp: number;\n\tconversation: {\n\t\tprefix: typeof SANEPI_SYSTEM_PREFIX;\n\t\tkind: \"user_message\";\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t};\n\ttext: string;\n\terrorMessage?: string;\n}\n\nexport interface TodoUserMessageOptions {\n\tsessionId?: string;\n\tdeliverAs?: \"steer\" | \"followUp\";\n}\n\nfunction prefixText(text: string): string {\n\treturn text.startsWith(SANEPI_SYSTEM_PREFIX) ? text : `${SANEPI_SYSTEM_PREFIX}\\n${text}`;\n}\n\nfunction prefixContent(content: string | (TextContent | ImageContent)[]): string | (TextContent | ImageContent)[] {\n\tif (typeof content === \"string\") {\n\t\treturn prefixText(content);\n\t}\n\n\tconst firstTextIndex = content.findIndex((part) => part.type === \"text\");\n\tif (firstTextIndex === -1) {\n\t\treturn [{ type: \"text\", text: SANEPI_SYSTEM_PREFIX }, ...content];\n\t}\n\n\treturn content.map((part, index) => {\n\t\tif (part.type !== \"text\" || index !== firstTextIndex) {\n\t\t\treturn part;\n\t\t}\n\n\t\treturn {\n\t\t\t...part,\n\t\t\ttext: prefixText(part.text),\n\t\t};\n\t});\n}\n\nfunction extractText(content: string | (TextContent | ImageContent)[]): string {\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\n\treturn content\n\t\t.filter((part): part is TextContent => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\");\n}\n\nfunction emitTodoConversationEvent(pi: ExtensionAPI, event: TodoConversationEvent): void {\n\tpi.events.emit(SANEPI_CONVERSATION_EVENT, event);\n}\n\nfunction createBaseEvent(args: {\n\taction: TodoConversationAction;\n\troute: TodoSystemMessageRoute;\n\tsessionId?: string;\n\tdeliverAs?: \"steer\" | \"followUp\";\n\ttext: string;\n\terrorMessage?: string;\n}): TodoConversationEvent {\n\treturn {\n\t\tversion: 1,\n\t\tsource: \"builtin\",\n\t\taction: args.action,\n\t\troute: args.route,\n\t\tsessionId: args.sessionId,\n\t\ttimestamp: Date.now(),\n\t\tconversation: {\n\t\t\tprefix: SANEPI_SYSTEM_PREFIX,\n\t\t\tkind: \"user_message\",\n\t\t\tdeliverAs: args.deliverAs,\n\t\t},\n\t\ttext: args.text,\n\t\terrorMessage: args.errorMessage,\n\t};\n}\n\nfunction hasUserMessageOptions(\n\toptions: TodoUserMessageOptions | undefined,\n): options is TodoUserMessageOptions & { deliverAs: \"steer\" | \"followUp\" } {\n\treturn options?.deliverAs !== undefined;\n}\n\nexport function sendTodoUserMessage(\n\tpi: ExtensionAPI,\n\troute: TodoSystemMessageRoute,\n\tcontent: string | (TextContent | ImageContent)[],\n\toptions?: TodoUserMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(content);\n\n\temitTodoConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: options?.deliverAs,\n\t\t}),\n\t);\n\n\tif (hasUserMessageOptions(options)) {\n\t\tpi.sendUserMessage(prefixedContent, { deliverAs: options.deliverAs });\n\t\treturn;\n\t}\n\n\tpi.sendUserMessage(prefixedContent);\n}\n\nexport function emitTodoSystemMessageFailure(\n\tpi: ExtensionAPI,\n\targs: {\n\t\troute: TodoSystemMessageRoute;\n\t\tsessionId?: string;\n\t\tcontent: string | (TextContent | ImageContent)[];\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\terrorMessage: string;\n\t},\n): void {\n\tconst prefixedContent = prefixContent(args.content);\n\n\temitTodoConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"failed\",\n\t\t\troute: args.route,\n\t\t\tsessionId: args.sessionId,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\terrorMessage: args.errorMessage,\n\t\t}),\n\t);\n}\n"]}
1
+ {"version":3,"file":"system-messages.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/system-messages.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ImageContent, TextContent } from \"@earendil-works/pi-ai\";\nimport type { ExtensionAPI } from \"../../types.js\";\n\nexport const SENPI_SYSTEM_PREFIX = \"[system:senpi]\";\nexport const SENPI_CONVERSATION_EVENT = \"senpi:conversation\";\n\nexport type TodoSystemMessageRoute = \"todotools.continuation\";\nexport type TodoConversationAction = \"injected\" | \"failed\";\n\nexport interface TodoConversationEvent {\n\tversion: 1;\n\tsource: \"builtin\";\n\taction: TodoConversationAction;\n\troute: TodoSystemMessageRoute;\n\tsessionId?: string;\n\ttimestamp: number;\n\tconversation: {\n\t\tprefix: typeof SENPI_SYSTEM_PREFIX;\n\t\tkind: \"user_message\";\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t};\n\ttext: string;\n\terrorMessage?: string;\n}\n\nexport interface TodoUserMessageOptions {\n\tsessionId?: string;\n\tdeliverAs?: \"steer\" | \"followUp\";\n}\n\nfunction prefixText(text: string): string {\n\treturn text.startsWith(SENPI_SYSTEM_PREFIX) ? text : `${SENPI_SYSTEM_PREFIX}\\n${text}`;\n}\n\nfunction prefixContent(content: string | (TextContent | ImageContent)[]): string | (TextContent | ImageContent)[] {\n\tif (typeof content === \"string\") {\n\t\treturn prefixText(content);\n\t}\n\n\tconst firstTextIndex = content.findIndex((part) => part.type === \"text\");\n\tif (firstTextIndex === -1) {\n\t\treturn [{ type: \"text\", text: SENPI_SYSTEM_PREFIX }, ...content];\n\t}\n\n\treturn content.map((part, index) => {\n\t\tif (part.type !== \"text\" || index !== firstTextIndex) {\n\t\t\treturn part;\n\t\t}\n\n\t\treturn {\n\t\t\t...part,\n\t\t\ttext: prefixText(part.text),\n\t\t};\n\t});\n}\n\nfunction extractText(content: string | (TextContent | ImageContent)[]): string {\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\n\treturn content\n\t\t.filter((part): part is TextContent => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\");\n}\n\nfunction emitTodoConversationEvent(pi: ExtensionAPI, event: TodoConversationEvent): void {\n\tpi.events.emit(SENPI_CONVERSATION_EVENT, event);\n}\n\nfunction createBaseEvent(args: {\n\taction: TodoConversationAction;\n\troute: TodoSystemMessageRoute;\n\tsessionId?: string;\n\tdeliverAs?: \"steer\" | \"followUp\";\n\ttext: string;\n\terrorMessage?: string;\n}): TodoConversationEvent {\n\treturn {\n\t\tversion: 1,\n\t\tsource: \"builtin\",\n\t\taction: args.action,\n\t\troute: args.route,\n\t\tsessionId: args.sessionId,\n\t\ttimestamp: Date.now(),\n\t\tconversation: {\n\t\t\tprefix: SENPI_SYSTEM_PREFIX,\n\t\t\tkind: \"user_message\",\n\t\t\tdeliverAs: args.deliverAs,\n\t\t},\n\t\ttext: args.text,\n\t\terrorMessage: args.errorMessage,\n\t};\n}\n\nfunction hasUserMessageOptions(\n\toptions: TodoUserMessageOptions | undefined,\n): options is TodoUserMessageOptions & { deliverAs: \"steer\" | \"followUp\" } {\n\treturn options?.deliverAs !== undefined;\n}\n\nexport function sendTodoUserMessage(\n\tpi: ExtensionAPI,\n\troute: TodoSystemMessageRoute,\n\tcontent: string | (TextContent | ImageContent)[],\n\toptions?: TodoUserMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(content);\n\n\temitTodoConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: options?.deliverAs,\n\t\t}),\n\t);\n\n\tif (hasUserMessageOptions(options)) {\n\t\tpi.sendUserMessage(prefixedContent, { deliverAs: options.deliverAs });\n\t\treturn;\n\t}\n\n\tpi.sendUserMessage(prefixedContent);\n}\n\nexport function emitTodoSystemMessageFailure(\n\tpi: ExtensionAPI,\n\targs: {\n\t\troute: TodoSystemMessageRoute;\n\t\tsessionId?: string;\n\t\tcontent: string | (TextContent | ImageContent)[];\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\terrorMessage: string;\n\t},\n): void {\n\tconst prefixedContent = prefixContent(args.content);\n\n\temitTodoConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"failed\",\n\t\t\troute: args.route,\n\t\t\tsessionId: args.sessionId,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\terrorMessage: args.errorMessage,\n\t\t}),\n\t);\n}\n"]}
@@ -1,4 +1,4 @@
1
1
  import type { ExtensionAPI } from "../../types.js";
2
- /** Guards provider requests by removing orphan tool_result blocks. */
2
+ /** Guards provider requests by keeping tool-call/result pairs balanced. */
3
3
  export default function toolPairGuardExtension(pi: ExtensionAPI): void;
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-pair-guard/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGnD,sEAAsE;AACtE,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAMrE","sourcesContent":["import type { ExtensionAPI } from \"../../types.js\";\nimport { sanitizeAnthropicPayload } from \"./sanitize-anthropic-payload.js\";\n\n/** Guards provider requests by removing orphan tool_result blocks. */\nexport default function toolPairGuardExtension(pi: ExtensionAPI): void {\n\tpi.on(\"before_provider_request\", (event) => {\n\t\tconst sanitized = sanitizeAnthropicPayload(event.payload);\n\t\tif (sanitized === event.payload) return undefined;\n\t\treturn sanitized;\n\t});\n}\n"]}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-pair-guard/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAKnD,2EAA2E;AAC3E,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAQrE","sourcesContent":["import type { ExtensionAPI } from \"../../types.js\";\nimport { sanitizeAnthropicPayload } from \"./sanitize-anthropic-payload.js\";\nimport { sanitizeOpenAIChatCompletionsPayload } from \"./sanitize-openai-chat-completions-payload.js\";\nimport { sanitizeOpenAIResponsesPayload } from \"./sanitize-openai-responses-payload.js\";\n\n/** Guards provider requests by keeping tool-call/result pairs balanced. */\nexport default function toolPairGuardExtension(pi: ExtensionAPI): void {\n\tpi.on(\"before_provider_request\", (event) => {\n\t\tconst sanitizedAnthropicPayload = sanitizeAnthropicPayload(event.payload);\n\t\tconst sanitizedResponsesPayload = sanitizeOpenAIResponsesPayload(sanitizedAnthropicPayload);\n\t\tconst sanitizedPayload = sanitizeOpenAIChatCompletionsPayload(sanitizedResponsesPayload);\n\t\tif (sanitizedPayload === event.payload) return undefined;\n\t\treturn sanitizedPayload;\n\t});\n}\n"]}