@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,676 +0,0 @@
1
- import { execFile } from "node:child_process";
2
- import { randomUUID } from "node:crypto";
3
- import { readFile, rm } from "node:fs/promises";
4
- import { tmpdir } from "node:os";
5
- import path from "node:path";
6
- import { promisify } from "node:util";
7
- import { Type } from "typebox";
8
- const execFileAsync = promisify(execFile);
9
- const ANTHROPIC_COMPUTER_USE_ENV = "PI_ANTHROPIC_COMPUTER_USE";
10
- const ANTHROPIC_COMPUTER_USE_WIDTH_ENV = "PI_ANTHROPIC_COMPUTER_USE_WIDTH";
11
- const ANTHROPIC_COMPUTER_USE_HEIGHT_ENV = "PI_ANTHROPIC_COMPUTER_USE_HEIGHT";
12
- const ANTHROPIC_COMPUTER_USE_DISPLAY_NUMBER_ENV = "PI_ANTHROPIC_COMPUTER_USE_DISPLAY_NUMBER";
13
- const ANTHROPIC_COMPUTER_USE_BETA = "computer-use-2025-01-24";
14
- const ANTHROPIC_NATIVE_COMPUTER_TOOL_TYPE = "computer_20250124";
15
- const ANTHROPIC_NATIVE_COMPUTER_TOOL_NAME = "computer";
16
- export const computerSchema = Type.Object({
17
- action: Type.Union([
18
- Type.Literal("screenshot"),
19
- Type.Literal("key"),
20
- Type.Literal("type"),
21
- Type.Literal("mouse_move"),
22
- Type.Literal("left_click"),
23
- Type.Literal("right_click"),
24
- Type.Literal("middle_click"),
25
- Type.Literal("double_click"),
26
- Type.Literal("triple_click"),
27
- Type.Literal("left_click_drag"),
28
- Type.Literal("cursor_position"),
29
- Type.Literal("left_mouse_down"),
30
- Type.Literal("left_mouse_up"),
31
- Type.Literal("scroll"),
32
- Type.Literal("hold_key"),
33
- Type.Literal("wait"),
34
- ]),
35
- coordinate: Type.Optional(Type.Array(Type.Number(), { minItems: 2, maxItems: 2 })),
36
- start_coordinate: Type.Optional(Type.Array(Type.Number(), { minItems: 2, maxItems: 2 })),
37
- text: Type.Optional(Type.String()),
38
- key: Type.Optional(Type.String()),
39
- scroll_direction: Type.Optional(Type.Union([Type.Literal("up"), Type.Literal("down"), Type.Literal("left"), Type.Literal("right")])),
40
- scroll_amount: Type.Optional(Type.Number()),
41
- duration: Type.Optional(Type.Number()),
42
- });
43
- function isRecord(value) {
44
- return typeof value === "object" && value !== null;
45
- }
46
- function enabledByEnv(env) {
47
- if (!env) {
48
- return false;
49
- }
50
- const normalized = env.trim().toLowerCase();
51
- return normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on";
52
- }
53
- function parsePositiveInt(value) {
54
- if (!value) {
55
- return undefined;
56
- }
57
- const trimmed = value.trim();
58
- if (!/^\d+$/.test(trimmed)) {
59
- return undefined;
60
- }
61
- const parsed = Number.parseInt(trimmed, 10);
62
- return parsed > 0 ? parsed : undefined;
63
- }
64
- function getComputerDisplayConfig() {
65
- const width = parsePositiveInt(process.env[ANTHROPIC_COMPUTER_USE_WIDTH_ENV]);
66
- const height = parsePositiveInt(process.env[ANTHROPIC_COMPUTER_USE_HEIGHT_ENV]);
67
- const displayNumber = parsePositiveInt(process.env[ANTHROPIC_COMPUTER_USE_DISPLAY_NUMBER_ENV]);
68
- if (width === undefined || height === undefined) {
69
- return undefined;
70
- }
71
- if (displayNumber === undefined) {
72
- return { width, height };
73
- }
74
- return { width, height, displayNumber };
75
- }
76
- function getComputerEnableState() {
77
- if (!enabledByEnv(process.env[ANTHROPIC_COMPUTER_USE_ENV])) {
78
- return { enabled: false };
79
- }
80
- const config = getComputerDisplayConfig();
81
- if (!config) {
82
- return { enabled: false };
83
- }
84
- return { enabled: true, config };
85
- }
86
- export function isAnthropicComputerUseEnabled() {
87
- return getComputerEnableState().enabled;
88
- }
89
- function isComputerToolType(value) {
90
- return typeof value === "string" && value.startsWith("computer_");
91
- }
92
- function sanitizeTools(tools) {
93
- const sanitizedTools = [];
94
- for (const tool of tools) {
95
- if (!isRecord(tool)) {
96
- continue;
97
- }
98
- const shouldStripFunctionVariant = tool.name === ANTHROPIC_NATIVE_COMPUTER_TOOL_NAME && !isComputerToolType(tool.type);
99
- if (!shouldStripFunctionVariant) {
100
- sanitizedTools.push(tool);
101
- }
102
- }
103
- return sanitizedTools;
104
- }
105
- function mergeBetaHeader(existing) {
106
- const existingParts = typeof existing === "string"
107
- ? existing
108
- .split(",")
109
- .map((part) => part.trim())
110
- .filter(Boolean)
111
- : [];
112
- if (existingParts.includes(ANTHROPIC_COMPUTER_USE_BETA)) {
113
- return existingParts.join(",");
114
- }
115
- return [...existingParts, ANTHROPIC_COMPUTER_USE_BETA].join(",");
116
- }
117
- export function addAnthropicComputerUseToPayload(api, payload) {
118
- if (api !== "anthropic-messages") {
119
- return payload;
120
- }
121
- const state = getComputerEnableState();
122
- if (!state.enabled || !state.config) {
123
- return payload;
124
- }
125
- if (!isRecord(payload)) {
126
- return payload;
127
- }
128
- const tools = Array.isArray(payload.tools) ? payload.tools : [];
129
- const sanitizedTools = sanitizeTools(tools);
130
- const hasNativeComputer = sanitizedTools.some((tool) => isComputerToolType(tool.type));
131
- if (!hasNativeComputer) {
132
- sanitizedTools.push({
133
- type: ANTHROPIC_NATIVE_COMPUTER_TOOL_TYPE,
134
- name: ANTHROPIC_NATIVE_COMPUTER_TOOL_NAME,
135
- display_width_px: state.config.width,
136
- display_height_px: state.config.height,
137
- ...(state.config.displayNumber !== undefined ? { display_number: state.config.displayNumber } : {}),
138
- });
139
- }
140
- const existingBetas = isRecord(payload.extra_body) ? payload.extra_body.betas : undefined;
141
- const mergedBetas = Array.isArray(existingBetas)
142
- ? existingBetas.includes(ANTHROPIC_COMPUTER_USE_BETA)
143
- ? existingBetas
144
- : [...existingBetas, ANTHROPIC_COMPUTER_USE_BETA]
145
- : [ANTHROPIC_COMPUTER_USE_BETA];
146
- const headers = isRecord(payload.headers) ? payload.headers : {};
147
- const nextHeaders = {
148
- ...headers,
149
- "anthropic-beta": mergeBetaHeader(headers["anthropic-beta"]),
150
- };
151
- return {
152
- ...payload,
153
- tools: sanitizedTools,
154
- headers: nextHeaders,
155
- extra_body: {
156
- ...(isRecord(payload.extra_body) ? payload.extra_body : {}),
157
- betas: mergedBetas,
158
- },
159
- };
160
- }
161
- function imageResult(base64) {
162
- return {
163
- content: [
164
- {
165
- type: "image",
166
- data: base64,
167
- mimeType: "image/png",
168
- },
169
- ],
170
- };
171
- }
172
- function errorResult(message) {
173
- return {
174
- isError: true,
175
- content: [{ type: "text", text: message }],
176
- };
177
- }
178
- function parseCoordinate(coordinate, action) {
179
- if (!coordinate || coordinate.length !== 2) {
180
- throw new Error(`${action} requires coordinate [x, y]`);
181
- }
182
- return [coordinate[0] ?? 0, coordinate[1] ?? 0];
183
- }
184
- function parseDuration(duration, action) {
185
- if (duration === undefined || Number.isNaN(duration) || duration < 0) {
186
- throw new Error(`${action} requires duration >= 0`);
187
- }
188
- return duration;
189
- }
190
- function parseText(text, action) {
191
- if (!text) {
192
- throw new Error(`${action} requires text`);
193
- }
194
- return text;
195
- }
196
- export async function executeComputerAction(input, ops) {
197
- try {
198
- switch (input.action) {
199
- case "screenshot": {
200
- const screenshot = await ops.screenshot();
201
- return imageResult(screenshot.base64);
202
- }
203
- case "key": {
204
- const combo = parseText(input.text ?? input.key, "key");
205
- await ops.keyPress(combo);
206
- break;
207
- }
208
- case "type": {
209
- await ops.type(parseText(input.text, "type"));
210
- break;
211
- }
212
- case "mouse_move": {
213
- const [x, y] = parseCoordinate(input.coordinate, "mouse_move");
214
- await ops.mouseMove(x, y);
215
- break;
216
- }
217
- case "left_click": {
218
- const coordinate = input.coordinate;
219
- if (coordinate) {
220
- const [x, y] = parseCoordinate(coordinate, "left_click");
221
- await ops.click("left", x, y);
222
- }
223
- else {
224
- await ops.click("left");
225
- }
226
- break;
227
- }
228
- case "right_click": {
229
- const coordinate = input.coordinate;
230
- if (coordinate) {
231
- const [x, y] = parseCoordinate(coordinate, "right_click");
232
- await ops.click("right", x, y);
233
- }
234
- else {
235
- await ops.click("right");
236
- }
237
- break;
238
- }
239
- case "middle_click": {
240
- const coordinate = input.coordinate;
241
- if (coordinate) {
242
- const [x, y] = parseCoordinate(coordinate, "middle_click");
243
- await ops.click("middle", x, y);
244
- }
245
- else {
246
- await ops.click("middle");
247
- }
248
- break;
249
- }
250
- case "double_click": {
251
- const coordinate = input.coordinate;
252
- if (coordinate) {
253
- const [x, y] = parseCoordinate(coordinate, "double_click");
254
- await ops.doubleClick(x, y);
255
- }
256
- else {
257
- await ops.doubleClick();
258
- }
259
- break;
260
- }
261
- case "triple_click": {
262
- const coordinate = input.coordinate;
263
- if (coordinate) {
264
- const [x, y] = parseCoordinate(coordinate, "triple_click");
265
- await ops.tripleClick(x, y);
266
- }
267
- else {
268
- await ops.tripleClick();
269
- }
270
- break;
271
- }
272
- case "left_click_drag": {
273
- const [startX, startY] = parseCoordinate(input.start_coordinate, "left_click_drag.start_coordinate");
274
- const [endX, endY] = parseCoordinate(input.coordinate, "left_click_drag.coordinate");
275
- await ops.drag(startX, startY, endX, endY);
276
- break;
277
- }
278
- case "cursor_position": {
279
- const position = await ops.cursorPosition();
280
- return { content: [{ type: "text", text: `X=${position.x},Y=${position.y}` }] };
281
- }
282
- case "left_mouse_down": {
283
- const coordinate = input.coordinate;
284
- if (coordinate) {
285
- const [x, y] = parseCoordinate(coordinate, "left_mouse_down");
286
- await ops.mouseDown("left", x, y);
287
- }
288
- else {
289
- await ops.mouseDown("left");
290
- }
291
- break;
292
- }
293
- case "left_mouse_up": {
294
- const coordinate = input.coordinate;
295
- if (coordinate) {
296
- const [x, y] = parseCoordinate(coordinate, "left_mouse_up");
297
- await ops.mouseUp("left", x, y);
298
- }
299
- else {
300
- await ops.mouseUp("left");
301
- }
302
- break;
303
- }
304
- case "scroll": {
305
- if (!input.scroll_direction) {
306
- throw new Error("scroll requires scroll_direction");
307
- }
308
- if (input.scroll_amount === undefined || input.scroll_amount <= 0) {
309
- throw new Error("scroll requires positive scroll_amount");
310
- }
311
- const coordinate = input.coordinate;
312
- if (coordinate) {
313
- const [x, y] = parseCoordinate(coordinate, "scroll");
314
- await ops.scroll(input.scroll_direction, input.scroll_amount, x, y);
315
- }
316
- else {
317
- await ops.scroll(input.scroll_direction, input.scroll_amount);
318
- }
319
- break;
320
- }
321
- case "hold_key": {
322
- await ops.holdKey(parseText(input.text ?? input.key, "hold_key"), parseDuration(input.duration, "hold_key"));
323
- break;
324
- }
325
- case "wait": {
326
- await ops.wait(parseDuration(input.duration, "wait"));
327
- break;
328
- }
329
- }
330
- const screenshot = await ops.screenshot();
331
- return imageResult(screenshot.base64);
332
- }
333
- catch (error) {
334
- const message = error instanceof Error ? error.message : String(error);
335
- return errorResult(message);
336
- }
337
- }
338
- async function commandExists(command) {
339
- try {
340
- await execFileAsync("which", [command]);
341
- return true;
342
- }
343
- catch {
344
- return false;
345
- }
346
- }
347
- async function run(command, args) {
348
- const result = await execFileAsync(command, args);
349
- return result.stdout;
350
- }
351
- function parseKeyComboToAppleScript(combo) {
352
- const parts = combo
353
- .split("+")
354
- .map((part) => part.trim().toLowerCase())
355
- .filter(Boolean);
356
- if (parts.length === 0) {
357
- throw new Error("Empty key combo");
358
- }
359
- const main = parts[parts.length - 1] ?? "";
360
- const modifiers = new Set(parts.slice(0, -1));
361
- const usingParts = [];
362
- if (modifiers.has("ctrl") || modifiers.has("control"))
363
- usingParts.push("control down");
364
- if (modifiers.has("cmd") || modifiers.has("command"))
365
- usingParts.push("command down");
366
- if (modifiers.has("alt") || modifiers.has("option"))
367
- usingParts.push("option down");
368
- if (modifiers.has("shift"))
369
- usingParts.push("shift down");
370
- const targetKey = main.length === 1 ? `keystroke ${JSON.stringify(main)}` : `key code ${mapKeyCode(main)}`;
371
- if (usingParts.length === 0) {
372
- return `tell application "System Events" to ${targetKey}`;
373
- }
374
- return `tell application "System Events" to ${targetKey} using {${usingParts.join(", ")}}`;
375
- }
376
- function mapKeyCode(key) {
377
- const map = { enter: 36, return: 36, tab: 48, space: 49, esc: 53, escape: 53 };
378
- const code = map[key];
379
- if (code === undefined) {
380
- throw new Error(`Unsupported macOS special key: ${key}`);
381
- }
382
- return code;
383
- }
384
- export function createUnsupportedOps() {
385
- const fail = async () => {
386
- throw new Error("Computer use not supported on Windows");
387
- };
388
- return {
389
- screenshot: fail,
390
- cursorPosition: fail,
391
- mouseMove: fail,
392
- click: fail,
393
- doubleClick: fail,
394
- tripleClick: fail,
395
- drag: fail,
396
- mouseDown: fail,
397
- mouseUp: fail,
398
- scroll: fail,
399
- keyPress: fail,
400
- type: fail,
401
- holdKey: fail,
402
- wait: fail,
403
- };
404
- }
405
- export function createMacOSComputerOps() {
406
- return {
407
- async screenshot() {
408
- const filePath = path.join(tmpdir(), `senpi-computer-${randomUUID()}.png`);
409
- try {
410
- await run("screencapture", ["-x", "-t", "png", filePath]);
411
- const buffer = await readFile(filePath);
412
- return { base64: buffer.toString("base64") };
413
- }
414
- finally {
415
- await rm(filePath, { force: true });
416
- }
417
- },
418
- async cursorPosition() {
419
- const output = await run("osascript", [
420
- "-e",
421
- 'tell app "System Events" to return position of pointer as text',
422
- ]);
423
- const parts = output.trim().split(",");
424
- const xRaw = Number.parseInt((parts[0] ?? "0").trim(), 10);
425
- const yRaw = Number.parseInt((parts[1] ?? "0").trim(), 10);
426
- return { x: Number.isFinite(xRaw) ? xRaw : 0, y: Number.isFinite(yRaw) ? yRaw : 0 };
427
- },
428
- async mouseMove(x, y) {
429
- await run("cliclick", [`m:${x},${y}`]);
430
- },
431
- async click(button, x, y) {
432
- if (x !== undefined && y !== undefined) {
433
- await run("cliclick", [`m:${x},${y}`]);
434
- }
435
- const command = button === "left" ? "c:." : button === "right" ? "rc:." : "mc:.";
436
- await run("cliclick", [command]);
437
- },
438
- async doubleClick(x, y) {
439
- if (x !== undefined && y !== undefined) {
440
- await run("cliclick", [`m:${x},${y}`]);
441
- }
442
- await run("cliclick", ["dc:."]);
443
- },
444
- async tripleClick(x, y) {
445
- if (x !== undefined && y !== undefined) {
446
- await run("cliclick", [`m:${x},${y}`]);
447
- }
448
- await run("cliclick", ["tc:."]);
449
- },
450
- async drag(startX, startY, endX, endY) {
451
- await run("cliclick", [`dd:${startX},${startY}`, `du:${endX},${endY}`]);
452
- },
453
- async mouseDown(_button, x, y) {
454
- if (x !== undefined && y !== undefined) {
455
- await run("cliclick", [`m:${x},${y}`]);
456
- }
457
- await run("cliclick", ["dd:."]);
458
- },
459
- async mouseUp(_button, x, y) {
460
- if (x !== undefined && y !== undefined) {
461
- await run("cliclick", [`m:${x},${y}`]);
462
- }
463
- await run("cliclick", ["du:."]);
464
- },
465
- async scroll(direction, amount, x, y) {
466
- if (x !== undefined && y !== undefined) {
467
- await run("cliclick", [`m:${x},${y}`]);
468
- }
469
- const clicks = Math.max(1, Math.round(amount));
470
- const wheel = direction === "up" ? "wd" : direction === "down" ? "wu" : direction === "left" ? "wl" : "wr";
471
- await run("cliclick", [`${wheel}:${clicks}`]);
472
- },
473
- async keyPress(combo) {
474
- await run("osascript", ["-e", parseKeyComboToAppleScript(combo)]);
475
- },
476
- async type(text) {
477
- await run("osascript", ["-e", `tell application "System Events" to keystroke ${JSON.stringify(text)}`]);
478
- },
479
- async holdKey(combo, durationSec) {
480
- await run("osascript", ["-e", parseKeyComboToAppleScript(combo)]);
481
- await new Promise((resolve) => setTimeout(resolve, durationSec * 1000));
482
- },
483
- async wait(durationSec) {
484
- await new Promise((resolve) => setTimeout(resolve, durationSec * 1000));
485
- },
486
- };
487
- }
488
- export function createLinuxComputerOps() {
489
- return {
490
- async screenshot() {
491
- const filePath = path.join(tmpdir(), `senpi-computer-${randomUUID()}.png`);
492
- try {
493
- await run("scrot", [filePath]);
494
- const buffer = await readFile(filePath);
495
- return { base64: buffer.toString("base64") };
496
- }
497
- finally {
498
- await rm(filePath, { force: true });
499
- }
500
- },
501
- async cursorPosition() {
502
- const output = await run("xdotool", ["getmouselocation", "--shell"]);
503
- const xMatch = output.match(/^X=(\d+)$/m);
504
- const yMatch = output.match(/^Y=(\d+)$/m);
505
- return {
506
- x: xMatch ? Number.parseInt(xMatch[1] ?? "0", 10) : 0,
507
- y: yMatch ? Number.parseInt(yMatch[1] ?? "0", 10) : 0,
508
- };
509
- },
510
- async mouseMove(x, y) {
511
- await run("xdotool", ["mousemove", `${x}`, `${y}`]);
512
- },
513
- async click(button, x, y) {
514
- if (x !== undefined && y !== undefined) {
515
- await run("xdotool", ["mousemove", `${x}`, `${y}`]);
516
- }
517
- const buttonNumber = button === "left" ? "1" : button === "middle" ? "2" : "3";
518
- await run("xdotool", ["click", buttonNumber]);
519
- },
520
- async doubleClick(x, y) {
521
- if (x !== undefined && y !== undefined) {
522
- await run("xdotool", ["mousemove", `${x}`, `${y}`]);
523
- }
524
- await run("xdotool", ["click", "--repeat", "2", "1"]);
525
- },
526
- async tripleClick(x, y) {
527
- if (x !== undefined && y !== undefined) {
528
- await run("xdotool", ["mousemove", `${x}`, `${y}`]);
529
- }
530
- await run("xdotool", ["click", "--repeat", "3", "1"]);
531
- },
532
- async drag(startX, startY, endX, endY) {
533
- await run("xdotool", [
534
- "mousemove",
535
- `${startX}`,
536
- `${startY}`,
537
- "mousedown",
538
- "1",
539
- "mousemove",
540
- `${endX}`,
541
- `${endY}`,
542
- "mouseup",
543
- "1",
544
- ]);
545
- },
546
- async mouseDown(_button, x, y) {
547
- if (x !== undefined && y !== undefined) {
548
- await run("xdotool", ["mousemove", `${x}`, `${y}`]);
549
- }
550
- await run("xdotool", ["mousedown", "1"]);
551
- },
552
- async mouseUp(_button, x, y) {
553
- if (x !== undefined && y !== undefined) {
554
- await run("xdotool", ["mousemove", `${x}`, `${y}`]);
555
- }
556
- await run("xdotool", ["mouseup", "1"]);
557
- },
558
- async scroll(direction, amount, x, y) {
559
- if (x !== undefined && y !== undefined) {
560
- await run("xdotool", ["mousemove", `${x}`, `${y}`]);
561
- }
562
- const button = direction === "up" ? "4" : direction === "down" ? "5" : direction === "left" ? "6" : "7";
563
- const repeat = `${Math.max(1, Math.round(amount))}`;
564
- await run("xdotool", ["click", "--repeat", repeat, button]);
565
- },
566
- async keyPress(combo) {
567
- await run("xdotool", ["key", combo]);
568
- },
569
- async type(text) {
570
- await run("xdotool", ["type", "--delay", "12", "--", text]);
571
- },
572
- async holdKey(combo, durationSec) {
573
- await run("xdotool", ["keydown", combo]);
574
- await new Promise((resolve) => setTimeout(resolve, durationSec * 1000));
575
- await run("xdotool", ["keyup", combo]);
576
- },
577
- async wait(durationSec) {
578
- await new Promise((resolve) => setTimeout(resolve, durationSec * 1000));
579
- },
580
- };
581
- }
582
- export function createComputerOps(platform = process.platform) {
583
- if (platform === "darwin") {
584
- return createMacOSComputerOps();
585
- }
586
- if (platform === "linux") {
587
- return createLinuxComputerOps();
588
- }
589
- return createUnsupportedOps();
590
- }
591
- async function validateCliDependencies(platform) {
592
- const missing = [];
593
- if (platform === "darwin") {
594
- if (!(await commandExists("cliclick"))) {
595
- missing.push("cliclick");
596
- }
597
- }
598
- else if (platform === "linux") {
599
- if (!(await commandExists("xdotool"))) {
600
- missing.push("xdotool");
601
- }
602
- if (!(await commandExists("scrot"))) {
603
- missing.push("scrot");
604
- }
605
- }
606
- return missing;
607
- }
608
- export const ANTHROPIC_COMPUTER_USE_SECTION = `
609
- ## Computer Use
610
-
611
- The native computer tool is available in this session. The model can
612
- control the screen via screenshot, key, type, mouse actions, scroll,
613
- and wait commands.
614
- `;
615
- function buildComputerUseSection(width, height) {
616
- return `${ANTHROPIC_COMPUTER_USE_SECTION.trimEnd()} Display dimensions: ${width}x${height}. Use computer when the user asks to interact with GUI applications.\n`;
617
- }
618
- export default function anthropicComputerUseExtension(pi) {
619
- let extensionDisabledForSession = false;
620
- pi.on("session_start", async (_event) => {
621
- if (!enabledByEnv(process.env[ANTHROPIC_COMPUTER_USE_ENV])) {
622
- extensionDisabledForSession = true;
623
- return undefined;
624
- }
625
- if (!getComputerDisplayConfig()) {
626
- extensionDisabledForSession = true;
627
- console.error(`[anthropic-computer-use] ${ANTHROPIC_COMPUTER_USE_WIDTH_ENV} and ${ANTHROPIC_COMPUTER_USE_HEIGHT_ENV} must be positive integers; extension disabled for this session.`);
628
- return undefined;
629
- }
630
- extensionDisabledForSession = false;
631
- const missingTools = await validateCliDependencies(process.platform);
632
- if (missingTools.length > 0) {
633
- console.warn(`[anthropic-computer-use] Missing OS automation dependencies: ${missingTools.join(", ")}. Install them for full functionality.`);
634
- }
635
- return undefined;
636
- });
637
- if (enabledByEnv(process.env[ANTHROPIC_COMPUTER_USE_ENV]) && getComputerDisplayConfig()) {
638
- const ops = createComputerOps();
639
- pi.registerTool({
640
- name: ANTHROPIC_NATIVE_COMPUTER_TOOL_NAME,
641
- label: "Computer Use",
642
- description: "Actions: screenshot, key, type, mouse_move, left/right/middle click, double/triple click, drag, cursor_position, mouse down/up, scroll, hold_key, wait.",
643
- parameters: computerSchema,
644
- async execute(_toolCallId, params) {
645
- const result = await executeComputerAction(params, ops);
646
- if (result.isError) {
647
- const firstContent = result.content[0];
648
- throw new Error(firstContent?.type === "text" ? firstContent.text : "Computer action failed");
649
- }
650
- return { content: result.content, details: undefined };
651
- },
652
- });
653
- }
654
- pi.on("before_provider_request", (event, ctx) => {
655
- if (extensionDisabledForSession) {
656
- return event.payload;
657
- }
658
- return addAnthropicComputerUseToPayload(ctx.model?.api, event.payload);
659
- });
660
- pi.on("before_agent_start", async (event, ctx) => {
661
- if (ctx.model?.api !== "anthropic-messages") {
662
- return undefined;
663
- }
664
- if (extensionDisabledForSession) {
665
- return undefined;
666
- }
667
- const config = getComputerDisplayConfig();
668
- if (!enabledByEnv(process.env[ANTHROPIC_COMPUTER_USE_ENV]) || !config) {
669
- return undefined;
670
- }
671
- return {
672
- systemPrompt: `${event.systemPrompt}\n${buildComputerUseSection(config.width, config.height)}`,
673
- };
674
- });
675
- }
676
- //# sourceMappingURL=index.js.map