@tyvm/knowhow 0.0.146 → 0.0.148

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 (271) hide show
  1. package/autodoc/cli-reference.md +36 -7
  2. package/bin/knowhow.js +8 -6
  3. package/package.json +1 -1
  4. package/src/agents/base/base.ts +51 -23
  5. package/src/agents/historyRollback.ts +36 -0
  6. package/src/agents/tools/execCommand.ts +102 -320
  7. package/src/agents/tools/list.ts +2 -2
  8. package/src/agents/tools/startAgentTask.ts +91 -34
  9. package/src/ai.ts +4 -1
  10. package/src/auth/browserLogin.ts +9 -3
  11. package/src/auth/keyAuth.ts +115 -0
  12. package/src/auth/keyManager.ts +166 -0
  13. package/src/chat/CliChatService.ts +23 -2
  14. package/src/chat/modules/AgentModule.ts +114 -33
  15. package/src/chat/modules/AskModule.ts +2 -0
  16. package/src/chat/modules/BaseChatModule.ts +0 -1
  17. package/src/chat/modules/CustomCommandsModule.ts +2 -0
  18. package/src/chat/modules/InternalChatModule.ts +7 -0
  19. package/src/chat/modules/RemoteSyncModule.ts +4 -0
  20. package/src/chat/modules/RendererModule.ts +2 -0
  21. package/src/chat/modules/SearchModule.ts +2 -0
  22. package/src/chat/modules/SessionsModule.ts +103 -34
  23. package/src/chat/modules/SetupModule.ts +2 -0
  24. package/src/chat/modules/ShellCommandModule.ts +2 -0
  25. package/src/chat/modules/SystemModule.ts +2 -0
  26. package/src/chat/modules/ToolCommandModule.ts +102 -0
  27. package/src/chat/modules/index.ts +1 -0
  28. package/src/chat/types.ts +3 -1
  29. package/src/cli.ts +10 -3
  30. package/src/clients/http.ts +67 -7
  31. package/src/clients/index.ts +4 -0
  32. package/src/commands/agent.ts +1 -38
  33. package/src/commands/agents.ts +455 -60
  34. package/src/commands/misc.ts +3 -2
  35. package/src/commands/processes.ts +138 -0
  36. package/src/commands/services.ts +23 -1
  37. package/src/index.ts +1 -0
  38. package/src/login.ts +89 -28
  39. package/src/processes/ProcessManager.ts +95 -0
  40. package/src/processes/managedProcessShim.ts +115 -0
  41. package/src/services/AgentService.ts +2 -0
  42. package/src/services/AgentSyncFs.ts +77 -1
  43. package/src/services/AgentSyncKnowhowWeb.ts +22 -4
  44. package/src/services/BehaviorsService.ts +2 -0
  45. package/src/services/DockerService.ts +2 -0
  46. package/src/services/EmbeddingService.ts +2 -0
  47. package/src/services/EmbeddingsService.ts +3 -0
  48. package/src/services/ExtensionsService.ts +25 -0
  49. package/src/services/KnowhowClient.ts +68 -7
  50. package/src/services/LazyToolsService.ts +24 -20
  51. package/src/services/Mcp.ts +2 -0
  52. package/src/services/McpServer.ts +2 -0
  53. package/src/services/MessageProcessor.ts +2 -0
  54. package/src/services/MinimalToolsService.ts +2 -0
  55. package/src/services/SessionManager.ts +5 -0
  56. package/src/services/SkillsService.ts +2 -0
  57. package/src/services/SyncedAgentWatcher.ts +2 -0
  58. package/src/services/SyncerService.ts +23 -8
  59. package/src/services/TaskRegistry.ts +2 -0
  60. package/src/services/Tools.ts +12 -0
  61. package/src/services/index.ts +6 -0
  62. package/src/services/modules/index.ts +10 -1
  63. package/src/services/modules/types.ts +4 -0
  64. package/src/types.ts +2 -0
  65. package/src/util/Trace.ts +1 -1
  66. package/src/utils/http.ts +18 -2
  67. package/tests/unit/agents/historyRollback.test.ts +53 -0
  68. package/tests/unit/auth/keyAuth.test.ts +102 -0
  69. package/tests/unit/auth/keyManager.test.ts +67 -0
  70. package/tests/unit/chat/ToolCommandModule.test.ts +71 -0
  71. package/tests/unit/chat/historyCommandArgs.test.ts +37 -0
  72. package/tests/unit/commands/agents.test.ts +111 -0
  73. package/tests/unit/login.test.ts +119 -0
  74. package/tests/unit/services/AgentSyncKnowhowWeb.test.ts +38 -0
  75. package/tests/unit/services/LazyToolsService.test.ts +53 -0
  76. package/tests/unit/services/SessionManager.test.ts +43 -0
  77. package/tests/unit/services/SyncerService.test.ts +45 -0
  78. package/tests/unit/util/Trace.test.ts +119 -0
  79. package/tests/unit/utils/http.test.ts +43 -0
  80. package/ts_build/package.json +1 -1
  81. package/ts_build/src/agents/base/base.d.ts +2 -1
  82. package/ts_build/src/agents/base/base.js +47 -14
  83. package/ts_build/src/agents/base/base.js.map +1 -1
  84. package/ts_build/src/agents/historyRollback.d.ts +2 -0
  85. package/ts_build/src/agents/historyRollback.js +22 -0
  86. package/ts_build/src/agents/historyRollback.js.map +1 -0
  87. package/ts_build/src/agents/tools/execCommand.d.ts +4 -1
  88. package/ts_build/src/agents/tools/execCommand.js +100 -223
  89. package/ts_build/src/agents/tools/execCommand.js.map +1 -1
  90. package/ts_build/src/agents/tools/list.js +2 -2
  91. package/ts_build/src/agents/tools/list.js.map +1 -1
  92. package/ts_build/src/agents/tools/startAgentTask.d.ts +16 -1
  93. package/ts_build/src/agents/tools/startAgentTask.js +71 -28
  94. package/ts_build/src/agents/tools/startAgentTask.js.map +1 -1
  95. package/ts_build/src/ai.js +2 -1
  96. package/ts_build/src/ai.js.map +1 -1
  97. package/ts_build/src/auth/browserLogin.d.ts +1 -0
  98. package/ts_build/src/auth/browserLogin.js +5 -2
  99. package/ts_build/src/auth/browserLogin.js.map +1 -1
  100. package/ts_build/src/auth/keyAuth.d.ts +5 -0
  101. package/ts_build/src/auth/keyAuth.js +79 -0
  102. package/ts_build/src/auth/keyAuth.js.map +1 -0
  103. package/ts_build/src/auth/keyManager.d.ts +14 -0
  104. package/ts_build/src/auth/keyManager.js +145 -0
  105. package/ts_build/src/auth/keyManager.js.map +1 -0
  106. package/ts_build/src/chat/CliChatService.d.ts +6 -0
  107. package/ts_build/src/chat/CliChatService.js +17 -2
  108. package/ts_build/src/chat/CliChatService.js.map +1 -1
  109. package/ts_build/src/chat/modules/AgentModule.d.ts +13 -1
  110. package/ts_build/src/chat/modules/AgentModule.js +83 -24
  111. package/ts_build/src/chat/modules/AgentModule.js.map +1 -1
  112. package/ts_build/src/chat/modules/AskModule.js +12 -2
  113. package/ts_build/src/chat/modules/AskModule.js.map +1 -1
  114. package/ts_build/src/chat/modules/BaseChatModule.js.map +1 -1
  115. package/ts_build/src/chat/modules/CustomCommandsModule.js +12 -2
  116. package/ts_build/src/chat/modules/CustomCommandsModule.js.map +1 -1
  117. package/ts_build/src/chat/modules/InternalChatModule.d.ts +1 -0
  118. package/ts_build/src/chat/modules/InternalChatModule.js +21 -2
  119. package/ts_build/src/chat/modules/InternalChatModule.js.map +1 -1
  120. package/ts_build/src/chat/modules/RemoteSyncModule.js +19 -2
  121. package/ts_build/src/chat/modules/RemoteSyncModule.js.map +1 -1
  122. package/ts_build/src/chat/modules/RendererModule.js +17 -2
  123. package/ts_build/src/chat/modules/RendererModule.js.map +1 -1
  124. package/ts_build/src/chat/modules/SearchModule.js +12 -2
  125. package/ts_build/src/chat/modules/SearchModule.js.map +1 -1
  126. package/ts_build/src/chat/modules/SessionsModule.d.ts +6 -0
  127. package/ts_build/src/chat/modules/SessionsModule.js +113 -18
  128. package/ts_build/src/chat/modules/SessionsModule.js.map +1 -1
  129. package/ts_build/src/chat/modules/SetupModule.js +17 -2
  130. package/ts_build/src/chat/modules/SetupModule.js.map +1 -1
  131. package/ts_build/src/chat/modules/ShellCommandModule.js +12 -2
  132. package/ts_build/src/chat/modules/ShellCommandModule.js.map +1 -1
  133. package/ts_build/src/chat/modules/SystemModule.js +12 -2
  134. package/ts_build/src/chat/modules/SystemModule.js.map +1 -1
  135. package/ts_build/src/chat/modules/ToolCommandModule.d.ts +10 -0
  136. package/ts_build/src/chat/modules/ToolCommandModule.js +86 -0
  137. package/ts_build/src/chat/modules/ToolCommandModule.js.map +1 -0
  138. package/ts_build/src/chat/modules/index.d.ts +1 -0
  139. package/ts_build/src/chat/modules/index.js +3 -1
  140. package/ts_build/src/chat/modules/index.js.map +1 -1
  141. package/ts_build/src/chat/types.d.ts +3 -1
  142. package/ts_build/src/cli.js +7 -3
  143. package/ts_build/src/cli.js.map +1 -1
  144. package/ts_build/src/clients/http.d.ts +4 -0
  145. package/ts_build/src/clients/http.js +68 -6
  146. package/ts_build/src/clients/http.js.map +1 -1
  147. package/ts_build/src/clients/index.js +23 -4
  148. package/ts_build/src/clients/index.js.map +1 -1
  149. package/ts_build/src/commands/agent.js +1 -21
  150. package/ts_build/src/commands/agent.js.map +1 -1
  151. package/ts_build/src/commands/agents.d.ts +2 -1
  152. package/ts_build/src/commands/agents.js +216 -23
  153. package/ts_build/src/commands/agents.js.map +1 -1
  154. package/ts_build/src/commands/misc.js +3 -2
  155. package/ts_build/src/commands/misc.js.map +1 -1
  156. package/ts_build/src/commands/processes.d.ts +2 -0
  157. package/ts_build/src/commands/processes.js +213 -0
  158. package/ts_build/src/commands/processes.js.map +1 -0
  159. package/ts_build/src/commands/services.js +11 -1
  160. package/ts_build/src/commands/services.js.map +1 -1
  161. package/ts_build/src/index.d.ts +1 -0
  162. package/ts_build/src/index.js +1 -0
  163. package/ts_build/src/index.js.map +1 -1
  164. package/ts_build/src/login.d.ts +1 -1
  165. package/ts_build/src/login.js +53 -15
  166. package/ts_build/src/login.js.map +1 -1
  167. package/ts_build/src/processes/ProcessManager.d.ts +51 -0
  168. package/ts_build/src/processes/ProcessManager.js +160 -0
  169. package/ts_build/src/processes/ProcessManager.js.map +1 -0
  170. package/ts_build/src/processes/managedProcessShim.d.ts +1 -0
  171. package/ts_build/src/processes/managedProcessShim.js +161 -0
  172. package/ts_build/src/processes/managedProcessShim.js.map +1 -0
  173. package/ts_build/src/services/AgentService.js +18 -2
  174. package/ts_build/src/services/AgentService.js.map +1 -1
  175. package/ts_build/src/services/AgentSyncFs.d.ts +3 -0
  176. package/ts_build/src/services/AgentSyncFs.js +68 -16
  177. package/ts_build/src/services/AgentSyncFs.js.map +1 -1
  178. package/ts_build/src/services/AgentSyncKnowhowWeb.d.ts +2 -0
  179. package/ts_build/src/services/AgentSyncKnowhowWeb.js +28 -6
  180. package/ts_build/src/services/AgentSyncKnowhowWeb.js.map +1 -1
  181. package/ts_build/src/services/BehaviorsService.js +12 -2
  182. package/ts_build/src/services/BehaviorsService.js.map +1 -1
  183. package/ts_build/src/services/DockerService.js +20 -8
  184. package/ts_build/src/services/DockerService.js.map +1 -1
  185. package/ts_build/src/services/EmbeddingService.js +16 -2
  186. package/ts_build/src/services/EmbeddingService.js.map +1 -1
  187. package/ts_build/src/services/EmbeddingsService.js +12 -2
  188. package/ts_build/src/services/EmbeddingsService.js.map +1 -1
  189. package/ts_build/src/services/ExtensionsService.d.ts +10 -0
  190. package/ts_build/src/services/ExtensionsService.js +17 -0
  191. package/ts_build/src/services/ExtensionsService.js.map +1 -0
  192. package/ts_build/src/services/KnowhowClient.d.ts +7 -2
  193. package/ts_build/src/services/KnowhowClient.js +108 -10
  194. package/ts_build/src/services/KnowhowClient.js.map +1 -1
  195. package/ts_build/src/services/LazyToolsService.d.ts +2 -0
  196. package/ts_build/src/services/LazyToolsService.js +26 -9
  197. package/ts_build/src/services/LazyToolsService.js.map +1 -1
  198. package/ts_build/src/services/Mcp.js +12 -2
  199. package/ts_build/src/services/Mcp.js.map +1 -1
  200. package/ts_build/src/services/McpServer.js +17 -2
  201. package/ts_build/src/services/McpServer.js.map +1 -1
  202. package/ts_build/src/services/MessageProcessor.js +16 -2
  203. package/ts_build/src/services/MessageProcessor.js.map +1 -1
  204. package/ts_build/src/services/MinimalToolsService.js +16 -2
  205. package/ts_build/src/services/MinimalToolsService.js.map +1 -1
  206. package/ts_build/src/services/SessionManager.js +19 -2
  207. package/ts_build/src/services/SessionManager.js.map +1 -1
  208. package/ts_build/src/services/SkillsService.js +16 -2
  209. package/ts_build/src/services/SkillsService.js.map +1 -1
  210. package/ts_build/src/services/SyncedAgentWatcher.js +16 -2
  211. package/ts_build/src/services/SyncedAgentWatcher.js.map +1 -1
  212. package/ts_build/src/services/SyncerService.d.ts +1 -0
  213. package/ts_build/src/services/SyncerService.js +27 -5
  214. package/ts_build/src/services/SyncerService.js.map +1 -1
  215. package/ts_build/src/services/TaskRegistry.js +12 -2
  216. package/ts_build/src/services/TaskRegistry.js.map +1 -1
  217. package/ts_build/src/services/Tools.d.ts +1 -0
  218. package/ts_build/src/services/Tools.js +19 -2
  219. package/ts_build/src/services/Tools.js.map +1 -1
  220. package/ts_build/src/services/index.d.ts +5 -0
  221. package/ts_build/src/services/index.js +7 -2
  222. package/ts_build/src/services/index.js.map +1 -1
  223. package/ts_build/src/services/modules/index.d.ts +4 -1
  224. package/ts_build/src/services/modules/index.js +6 -1
  225. package/ts_build/src/services/modules/index.js.map +1 -1
  226. package/ts_build/src/services/modules/types.d.ts +3 -0
  227. package/ts_build/src/types.d.ts +1 -0
  228. package/ts_build/src/types.js.map +1 -1
  229. package/ts_build/src/util/Trace.d.ts +1 -3
  230. package/ts_build/src/utils/http.d.ts +6 -2
  231. package/ts_build/src/utils/http.js +8 -2
  232. package/ts_build/src/utils/http.js.map +1 -1
  233. package/ts_build/tests/unit/agents/historyRollback.test.d.ts +1 -0
  234. package/ts_build/tests/unit/agents/historyRollback.test.js +42 -0
  235. package/ts_build/tests/unit/agents/historyRollback.test.js.map +1 -0
  236. package/ts_build/tests/unit/auth/keyAuth.test.d.ts +1 -0
  237. package/ts_build/tests/unit/auth/keyAuth.test.js +77 -0
  238. package/ts_build/tests/unit/auth/keyAuth.test.js.map +1 -0
  239. package/ts_build/tests/unit/auth/keyManager.test.d.ts +1 -0
  240. package/ts_build/tests/unit/auth/keyManager.test.js +52 -0
  241. package/ts_build/tests/unit/auth/keyManager.test.js.map +1 -0
  242. package/ts_build/tests/unit/chat/ToolCommandModule.test.d.ts +1 -0
  243. package/ts_build/tests/unit/chat/ToolCommandModule.test.js +61 -0
  244. package/ts_build/tests/unit/chat/ToolCommandModule.test.js.map +1 -0
  245. package/ts_build/tests/unit/chat/historyCommandArgs.test.d.ts +1 -0
  246. package/ts_build/tests/unit/chat/historyCommandArgs.test.js +29 -0
  247. package/ts_build/tests/unit/chat/historyCommandArgs.test.js.map +1 -0
  248. package/ts_build/tests/unit/commands/agents.test.d.ts +1 -0
  249. package/ts_build/tests/unit/commands/agents.test.js +119 -0
  250. package/ts_build/tests/unit/commands/agents.test.js.map +1 -0
  251. package/ts_build/tests/unit/login.test.d.ts +1 -0
  252. package/ts_build/tests/unit/login.test.js +97 -0
  253. package/ts_build/tests/unit/login.test.js.map +1 -0
  254. package/ts_build/tests/unit/services/AgentSyncKnowhowWeb.test.d.ts +1 -0
  255. package/ts_build/tests/unit/services/AgentSyncKnowhowWeb.test.js +32 -0
  256. package/ts_build/tests/unit/services/AgentSyncKnowhowWeb.test.js.map +1 -0
  257. package/ts_build/tests/unit/services/LazyToolsService.test.d.ts +1 -0
  258. package/ts_build/tests/unit/services/LazyToolsService.test.js +47 -0
  259. package/ts_build/tests/unit/services/LazyToolsService.test.js.map +1 -0
  260. package/ts_build/tests/unit/services/SessionManager.test.d.ts +1 -0
  261. package/ts_build/tests/unit/services/SessionManager.test.js +72 -0
  262. package/ts_build/tests/unit/services/SessionManager.test.js.map +1 -0
  263. package/ts_build/tests/unit/services/SyncerService.test.d.ts +1 -0
  264. package/ts_build/tests/unit/services/SyncerService.test.js +40 -0
  265. package/ts_build/tests/unit/services/SyncerService.test.js.map +1 -0
  266. package/ts_build/tests/unit/util/Trace.test.d.ts +1 -0
  267. package/ts_build/tests/unit/util/Trace.test.js +107 -0
  268. package/ts_build/tests/unit/util/Trace.test.js.map +1 -0
  269. package/ts_build/tests/unit/utils/http.test.d.ts +1 -0
  270. package/ts_build/tests/unit/utils/http.test.js +69 -0
  271. package/ts_build/tests/unit/utils/http.test.js.map +1 -0
@@ -86,7 +86,7 @@ knowhow chat
86
86
  ---
87
87
 
88
88
  ### `knowhow agent`
89
- **Purpose:** Run a one-shot agent task directly from the CLI (default agent: `Patcher`). Can also resume a previously started task.
89
+ **Purpose:** Start a new one-shot agent task directly from the CLI (default agent: `Patcher`).
90
90
 
91
91
  **Usage:**
92
92
  ```bash
@@ -114,8 +114,6 @@ knowhow agent [options]
114
114
  Custom prompt template file with a `{text}` placeholder
115
115
  - `--input <text>`
116
116
  Task input (fallback to stdin if not provided)
117
- - `--resume`
118
- Resume a previously started task using `--task-id` (local FS or remote)
119
117
  - `--renderer <name>`
120
118
  Renderer to use: `basic`, `compact`, `fancy`, or a path/package
121
119
  (default: from config or `basic`)
@@ -136,14 +134,45 @@ Use a custom prompt template file:
136
134
  knowhow agent --prompt-file .knowhow/prompts/BasicCodeDocumenter.mdx --input "src/index.ts"
137
135
  ```
138
136
 
139
- Resume a task:
137
+ Choose provider + renderer:
140
138
  ```bash
141
- knowhow agent --resume --task-id 123 --message-id 456 --input "Continue where you left off"
139
+ knowhow agent --provider openai --model gpt-4.1-mini --renderer fancy --input "Fix the failing tests"
142
140
  ```
143
141
 
144
- Choose provider + renderer:
142
+ ---
143
+
144
+ ### `knowhow agents resume` / `knowhow agents fork`
145
+ **Purpose:** Continue an existing agent task, or branch its history into a new task without modifying the source.
146
+
147
+ **Usage:**
145
148
  ```bash
146
- knowhow agent --provider openai --model gpt-4.1-mini --renderer fancy --input "Fix the failing tests"
149
+ knowhow agents resume [taskId] [options]
150
+ knowhow agents fork [sourceTaskId] [options]
151
+ ```
152
+
153
+ Both commands accept a full or partial task ID. Use `-i <number>` instead to select the corresponding row from `knowhow agents list`.
154
+
155
+ #### Options
156
+ - `-i, --index <number>` — Select a task by row number from `knowhow agents list`
157
+ - `--rollback <count>` — Discard the newest N agent interactions before continuing (default: `0`)
158
+ - `--input <text>` — Message to send after restoring history
159
+ - `--message-id <messageId>` — Knowhow message ID for remote task lookup
160
+ - `--sync-fs` — Enable filesystem-based synchronization
161
+ - `--provider <provider>` — Override the saved AI provider
162
+ - `--model <model>` — Override the saved model
163
+ - `--agent-name <name>` — Override the saved agent
164
+ - `--reasoning-effort <effort>` — Override the saved reasoning effort
165
+ - `--renderer <name>` — Renderer to use (default: from config or `basic`)
166
+ - `--task-id <taskId>` — Explicit destination task ID (`fork` only)
167
+
168
+ Resume the first listed task after removing its newest assistant interaction:
169
+ ```bash
170
+ knowhow agents resume -i 1 --rollback 1
171
+ ```
172
+
173
+ Fork the third listed task into an explicit destination task ID:
174
+ ```bash
175
+ knowhow agents fork -i 3 --rollback 1 --task-id my-new-task
147
176
  ```
148
177
 
149
178
  ---
package/bin/knowhow.js CHANGED
@@ -1,12 +1,14 @@
1
- #!/usr/bin/env node --no-node-snapshot
1
+ #!/usr/bin/env node
2
2
 
3
3
  // knowhow CLI entry point.
4
4
  //
5
- // --no-node-snapshot is required for isolated-vm (used by executeScript).
6
- // It is declared in the shebang above so that Node starts with it directly —
7
- // no re-exec needed. This means the process stays as a direct child of the
8
- // terminal (e.g. Ghostty) and inherits its macOS TCC (Screen Recording /
9
- // Accessibility) permissions without needing to grant them to node itself.
5
+ // --no-node-snapshot is NOT needed here. The script module (knowhow-module-script)
6
+ // forks a child process with --no-node-snapshot only when executeScript is actually
7
+ // called. This means:
8
+ // - The shebang works on Linux (GNU env) and macOS without any argument-splitting tricks.
9
+ // - Ghostty (or whichever terminal launched knowhow) remains the TCC subject for
10
+ // macOS Screen Recording / Accessibility permissions — computer-use features work
11
+ // without having to grant those permissions to the node binary itself.
10
12
 
11
13
  const path = require("node:path");
12
14
  const cliJs = path.join(__dirname, "../ts_build/src/cli.js");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tyvm/knowhow",
3
- "version": "0.0.146",
3
+ "version": "0.0.148",
4
4
  "description": "ai cli with plugins and agents",
5
5
  "main": "ts_build/src/index.js",
6
6
  "bin": {
@@ -22,6 +22,7 @@ import { Models } from "../../ai";
22
22
  import { MessageProcessor } from "../../services/MessageProcessor";
23
23
  import { DEFAULT_CONTEXT_LIMIT } from "../../clients/contextLimits";
24
24
  import { Marked } from "../../utils";
25
+ import { TraceAll } from "../../util/Trace";
25
26
 
26
27
  export { Message, Tool, ToolCall };
27
28
  export interface ModelPreference {
@@ -83,6 +84,7 @@ interface ActiveObservation {
83
84
  expiry?: NodeJS.Timeout;
84
85
  }
85
86
 
87
+ @TraceAll()
86
88
  export abstract class BaseAgent implements IAgent {
87
89
  abstract name: string;
88
90
  abstract description: string;
@@ -471,6 +473,28 @@ export abstract class BaseAgent implements IAgent {
471
473
  return this.getEnabledTools().map((t) => t.function.name);
472
474
  }
473
475
 
476
+ /** Restore the exact request-visible tool list persisted for a prior run. */
477
+ restoreEnabledTools(names: string[]) {
478
+ const uniqueNames = [...new Set(names)];
479
+ const lazyTools = this.tools as ToolsService & {
480
+ enableTools?: (patterns: string[]) => unknown;
481
+ restoreEnabledTools?: (names: string[]) => void;
482
+ };
483
+
484
+ // LazyToolsService only exposes explicitly enabled tools. Materialize the
485
+ // saved concrete names before applying the agent-level exact-set filter.
486
+ if (lazyTools.restoreEnabledTools) {
487
+ lazyTools.restoreEnabledTools(uniqueNames);
488
+ } else {
489
+ lazyTools.enableTools?.(uniqueNames);
490
+ }
491
+ const savedNames = new Set(uniqueNames);
492
+ this.disabledTools = this.tools
493
+ .getTools()
494
+ .map((tool) => tool.function.name)
495
+ .filter((name) => !savedNames.has(name));
496
+ }
497
+
474
498
  disableTool(toolName: string) {
475
499
  this.disabledTools.push(toolName);
476
500
  }
@@ -1011,9 +1035,6 @@ export abstract class BaseAgent implements IAgent {
1011
1035
  this.updateCurrentThread(messages);
1012
1036
  const isMissingTool = this.isRequiredToolMissing();
1013
1037
 
1014
- const startIndex = 0;
1015
- const endIndex = messages.length;
1016
-
1017
1038
  // Process messages before each AI call
1018
1039
  messages = await this.messageProcessor.processMessages(
1019
1040
  messages,
@@ -1259,14 +1280,14 @@ export abstract class BaseAgent implements IAgent {
1259
1280
  : `Compressing messages: ${contextTokens} tokens exceeds ${this.getCompressThreshold()}`
1260
1281
  );
1261
1282
  this._forceCompact = false;
1262
- messages = await this.compressMessages(messages, startIndex, endIndex);
1283
+ messages = await this.compressMessages(messages);
1263
1284
  this.startNewThread(messages);
1264
1285
  // Reset the real-token tracker. compressMessages() ran a completion over
1265
- // the FULL (pre-compression) thread, so lastPromptTokens now reflects
1266
- // that large context — not the small compressed thread. Zeroing it makes
1267
- // getContextTokenCount() fall back to the whitespace estimate of the new
1268
- // (small) thread until the next real completion reports fresh usage,
1269
- // preventing an immediate false re-compaction on the following iteration.
1286
+ // the older history, so lastPromptTokens reflects the compression input
1287
+ // rather than the newly reconstructed thread. Zeroing it makes
1288
+ // getContextTokenCount() estimate the new thread until the next regular
1289
+ // completion reports fresh usage, preventing an immediate false
1290
+ // re-compaction on the following iteration.
1270
1291
  this.lastPromptTokens = 0;
1271
1292
  }
1272
1293
 
@@ -1665,15 +1686,24 @@ export abstract class BaseAgent implements IAgent {
1665
1686
  return this.taskBreakdown;
1666
1687
  }
1667
1688
 
1668
- async compressMessages(
1669
- messages: Message[],
1670
- startIndex: number,
1671
- endIndex: number
1672
- ) {
1689
+ async compressMessages(messages: Message[]) {
1690
+ // Preserve the latest agent interaction exactly. Starting the resumed thread
1691
+ // at the final assistant message keeps its tool calls, every tool response,
1692
+ // and any subsequent user messages together as one protocol-valid unit.
1693
+ let resumeIndex = messages.length - 1;
1694
+ while (
1695
+ resumeIndex >= 0 &&
1696
+ messages[resumeIndex].role !== "assistant"
1697
+ ) {
1698
+ resumeIndex--;
1699
+ }
1700
+ const compressionEnd = resumeIndex === -1 ? messages.length : resumeIndex;
1701
+ const toCompress = messages.slice(0, compressionEnd);
1702
+ const resumeMessages = messages.slice(compressionEnd);
1703
+
1673
1704
  this.log(
1674
- `Compressing messages from ${startIndex} to ${endIndex}, total messages: ${messages.length}`
1705
+ `Compressing messages from 0 to ${compressionEnd}, resuming from ${resumeIndex}, total messages: ${messages.length}`
1675
1706
  );
1676
- const toCompress = messages.slice(startIndex, endIndex);
1677
1707
  const toCompressPrompt = `We are compressing our conversation to save memory.
1678
1708
  Please summarize the conversation so far, so that we may continue the original task with a smaller context
1679
1709
 
@@ -1685,14 +1715,12 @@ export abstract class BaseAgent implements IAgent {
1685
1715
 
1686
1716
  Our initial task breakdown: ${this.taskBreakdown}
1687
1717
 
1688
- This summary will become the agent's only memory of the past, all other messages will be dropped:
1718
+ This summary will replace the older history. The latest agent interaction will remain verbatim:
1689
1719
 
1690
1720
  `;
1691
1721
 
1692
- const model = this.getModel();
1693
-
1694
1722
  const compressMessagesPayload = [
1695
- ...messages,
1723
+ ...toCompress,
1696
1724
  {
1697
1725
  role: "user",
1698
1726
  content: toCompressPrompt,
@@ -1720,12 +1748,12 @@ export abstract class BaseAgent implements IAgent {
1720
1748
  `,
1721
1749
  },
1722
1750
  ] as Message[];
1723
- const systemMesasges = toCompress.filter((m) => m.role === "system");
1751
+ const systemMessages = toCompress.filter((m) => m.role === "system");
1724
1752
 
1725
1753
  const newMessages = [
1726
- ...systemMesasges,
1754
+ ...systemMessages,
1727
1755
  ...startMessages,
1728
- ...messages.slice(endIndex),
1756
+ ...resumeMessages,
1729
1757
  ];
1730
1758
 
1731
1759
  const oldLength = this.getMessagesLength(messages);
@@ -0,0 +1,36 @@
1
+ import { Message } from "../clients/types";
2
+
3
+ /**
4
+ * Remove the newest agent interactions from the final persisted thread.
5
+ *
6
+ * An interaction starts with an assistant message and includes every following
7
+ * tool result up to (but not including) the next assistant message. Cutting at
8
+ * the assistant boundary keeps tool_call/tool-result pairs valid and makes
9
+ * `rollback: 1` useful for recovering from a failed final tool-use turn.
10
+ */
11
+ export function rollbackAgentInteractions(
12
+ threads: Message[][],
13
+ rollback: number = 0
14
+ ): Message[][] {
15
+ if (!Number.isInteger(rollback) || rollback < 0) {
16
+ throw new Error("rollback must be a non-negative integer");
17
+ }
18
+
19
+ const cloned = threads.map((thread) => thread.map((message) => ({ ...message })));
20
+ if (rollback === 0 || cloned.length === 0) return cloned;
21
+
22
+ const lastThread = cloned[cloned.length - 1];
23
+ const assistantIndexes = lastThread
24
+ .map((message, index) => (message.role === "assistant" ? index : -1))
25
+ .filter((index) => index >= 0);
26
+
27
+ if (rollback > assistantIndexes.length) {
28
+ throw new Error(
29
+ `Cannot rollback ${rollback} interaction(s); the latest thread only has ${assistantIndexes.length} assistant interaction(s).`
30
+ );
31
+ }
32
+
33
+ const cutIndex = assistantIndexes[assistantIndexes.length - rollback];
34
+ cloned[cloned.length - 1] = lastThread.slice(0, cutIndex);
35
+ return cloned;
36
+ }