@qduc/term2 0.1.7 → 0.1.8

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 (322) hide show
  1. package/dist/app.model-command-feedback.test.d.ts +2 -0
  2. package/dist/app.model-command-feedback.test.d.ts.map +1 -0
  3. package/dist/app.model-command-feedback.test.js +19 -0
  4. package/dist/app.model-command-feedback.test.js.map +1 -0
  5. package/dist/cli.js +5 -0
  6. package/dist/cli.js.map +1 -1
  7. package/dist/components/BottomArea.d.ts +1 -8
  8. package/dist/components/BottomArea.d.ts.map +1 -1
  9. package/dist/components/BottomArea.js.map +1 -1
  10. package/dist/components/InputBox.d.ts +6 -0
  11. package/dist/components/InputBox.d.ts.map +1 -1
  12. package/dist/components/InputBox.js +25 -3
  13. package/dist/components/InputBox.js.map +1 -1
  14. package/dist/components/InputBox.test.js +10 -1
  15. package/dist/components/InputBox.test.js.map +1 -1
  16. package/dist/components/MentorMode.test.d.ts +2 -0
  17. package/dist/components/MentorMode.test.d.ts.map +1 -0
  18. package/dist/components/MentorMode.test.js.map +1 -0
  19. package/dist/components/StatusBar.test.d.ts +2 -0
  20. package/dist/components/StatusBar.test.d.ts.map +1 -0
  21. package/dist/components/StatusBar.test.js +19 -0
  22. package/dist/components/StatusBar.test.js.map +1 -0
  23. package/dist/components/TextInput.d.ts.map +1 -1
  24. package/dist/components/TextInput.js +1 -2
  25. package/dist/components/TextInput.js.map +1 -1
  26. package/dist/components/TextInput.test.js.map +1 -1
  27. package/dist/contracts/conversation.d.ts +27 -0
  28. package/dist/contracts/conversation.d.ts.map +1 -0
  29. package/dist/contracts/conversation.js +2 -0
  30. package/dist/contracts/conversation.js.map +1 -0
  31. package/dist/debug-schema.d.ts +2 -0
  32. package/dist/debug-schema.d.ts.map +1 -0
  33. package/dist/debug-schema.js +22 -0
  34. package/dist/debug-schema.js.map +1 -0
  35. package/dist/hooks/use-conversation.d.ts +3 -14
  36. package/dist/hooks/use-conversation.d.ts.map +1 -1
  37. package/dist/hooks/use-conversation.js +15 -87
  38. package/dist/hooks/use-conversation.js.map +1 -1
  39. package/dist/hooks/use-model-selection.test.d.ts +2 -0
  40. package/dist/hooks/use-model-selection.test.d.ts.map +1 -0
  41. package/dist/hooks/use-model-selection.test.js +28 -0
  42. package/dist/hooks/use-model-selection.test.js.map +1 -0
  43. package/dist/hooks/use-path-completion.test.d.ts +2 -0
  44. package/dist/hooks/use-path-completion.test.d.ts.map +1 -0
  45. package/dist/hooks/use-path-completion.test.js +29 -0
  46. package/dist/hooks/use-path-completion.test.js.map +1 -0
  47. package/dist/lib/mentor-client.d.ts +41 -0
  48. package/dist/lib/mentor-client.d.ts.map +1 -0
  49. package/dist/lib/mentor-client.js +146 -0
  50. package/dist/lib/mentor-client.js.map +1 -0
  51. package/dist/lib/mentor-client.test.d.ts +2 -0
  52. package/dist/lib/mentor-client.test.d.ts.map +1 -0
  53. package/dist/lib/mentor-client.test.js +440 -0
  54. package/dist/lib/mentor-client.test.js.map +1 -0
  55. package/dist/lib/retry-strategy.d.ts +43 -0
  56. package/dist/lib/retry-strategy.d.ts.map +1 -0
  57. package/dist/lib/retry-strategy.js +93 -0
  58. package/dist/lib/retry-strategy.js.map +1 -0
  59. package/dist/lib/retry-strategy.test.d.ts +2 -0
  60. package/dist/lib/retry-strategy.test.d.ts.map +1 -0
  61. package/dist/lib/retry-strategy.test.js +200 -0
  62. package/dist/lib/retry-strategy.test.js.map +1 -0
  63. package/dist/lib/tool-invoke.d.ts +13 -0
  64. package/dist/lib/tool-invoke.d.ts.map +1 -1
  65. package/dist/lib/tool-invoke.js +61 -3
  66. package/dist/lib/tool-invoke.js.map +1 -1
  67. package/dist/lib/tool-invoke.test.js +139 -1
  68. package/dist/lib/tool-invoke.test.js.map +1 -1
  69. package/dist/prompts/default.md.bak +77 -0
  70. package/dist/prompts/simple-mentor.md +0 -8
  71. package/dist/prompts/simple.md +4 -0
  72. package/dist/providers/github-copilot/model-direct.d.ts +34 -0
  73. package/dist/providers/github-copilot/model-direct.d.ts.map +1 -0
  74. package/dist/providers/github-copilot/model-direct.js +443 -0
  75. package/dist/providers/github-copilot/model-direct.js.map +1 -0
  76. package/dist/providers/github-copilot/model.d.ts.map +1 -1
  77. package/dist/providers/github-copilot/model.js +108 -25
  78. package/dist/providers/github-copilot/model.js.map +1 -1
  79. package/dist/providers/github-copilot/provider.d.ts +5 -0
  80. package/dist/providers/github-copilot/provider.d.ts.map +1 -1
  81. package/dist/providers/github-copilot/provider.js +7 -2
  82. package/dist/providers/github-copilot/provider.js.map +1 -1
  83. package/dist/providers/openrouter/merge-messages.test.d.ts +2 -0
  84. package/dist/providers/openrouter/merge-messages.test.d.ts.map +1 -0
  85. package/dist/providers/openrouter/merge-messages.test.js +83 -0
  86. package/dist/providers/openrouter/merge-messages.test.js.map +1 -0
  87. package/dist/providers/openrouter.history.test.d.ts +2 -0
  88. package/dist/providers/openrouter.history.test.d.ts.map +1 -0
  89. package/dist/providers/openrouter.history.test.js +533 -0
  90. package/dist/providers/openrouter.history.test.js.map +1 -0
  91. package/dist/reproduce_issue.test.d.ts +2 -0
  92. package/dist/reproduce_issue.test.d.ts.map +1 -0
  93. package/dist/reproduce_issue.test.js +31 -0
  94. package/dist/reproduce_issue.test.js.map +1 -0
  95. package/dist/services/approval-presentation-policy.d.ts +17 -0
  96. package/dist/services/approval-presentation-policy.d.ts.map +1 -0
  97. package/dist/services/approval-presentation-policy.js +44 -0
  98. package/dist/services/approval-presentation-policy.js.map +1 -0
  99. package/dist/services/approval-presentation-policy.test.d.ts +2 -0
  100. package/dist/services/approval-presentation-policy.test.d.ts.map +1 -0
  101. package/dist/services/approval-presentation-policy.test.js +74 -0
  102. package/dist/services/approval-presentation-policy.test.js.map +1 -0
  103. package/dist/services/approval-state.d.ts +4 -4
  104. package/dist/services/approval-state.d.ts.map +1 -1
  105. package/dist/services/conversation-events.d.ts +12 -9
  106. package/dist/services/conversation-events.d.ts.map +1 -1
  107. package/dist/services/conversation-result-builder.d.ts +41 -0
  108. package/dist/services/conversation-result-builder.d.ts.map +1 -0
  109. package/dist/services/conversation-result-builder.js +110 -0
  110. package/dist/services/conversation-result-builder.js.map +1 -0
  111. package/dist/services/conversation-result-builder.test.d.ts +2 -0
  112. package/dist/services/conversation-result-builder.test.d.ts.map +1 -0
  113. package/dist/services/conversation-result-builder.test.js +76 -0
  114. package/dist/services/conversation-result-builder.test.js.map +1 -0
  115. package/dist/services/conversation-service.d.ts +7 -5
  116. package/dist/services/conversation-service.d.ts.map +1 -1
  117. package/dist/services/conversation-service.js +1 -1
  118. package/dist/services/conversation-service.js.map +1 -1
  119. package/dist/services/conversation-service.test.js +183 -149
  120. package/dist/services/conversation-session.d.ts +4 -24
  121. package/dist/services/conversation-session.d.ts.map +1 -1
  122. package/dist/services/conversation-session.js +172 -229
  123. package/dist/services/conversation-session.js.map +1 -1
  124. package/dist/services/conversation-session.usage.test.d.ts +2 -0
  125. package/dist/services/conversation-session.usage.test.d.ts.map +1 -0
  126. package/dist/services/conversation-session.usage.test.js +59 -0
  127. package/dist/services/conversation-session.usage.test.js.map +1 -0
  128. package/dist/services/conversation-store.d.ts +6 -0
  129. package/dist/services/conversation-store.d.ts.map +1 -1
  130. package/dist/services/conversation-store.js +13 -0
  131. package/dist/services/conversation-store.js.map +1 -1
  132. package/dist/services/stream-event-processor.d.ts +32 -0
  133. package/dist/services/stream-event-processor.d.ts.map +1 -0
  134. package/dist/services/stream-event-processor.js +344 -0
  135. package/dist/services/stream-event-processor.js.map +1 -0
  136. package/dist/services/stream-event-processor.test.d.ts +2 -0
  137. package/dist/services/stream-event-processor.test.d.ts.map +1 -0
  138. package/dist/services/stream-event-processor.test.js +117 -0
  139. package/dist/services/stream-event-processor.test.js.map +1 -0
  140. package/dist/test-search-tool.d.ts +2 -0
  141. package/dist/test-search-tool.d.ts.map +1 -0
  142. package/dist/test-search-tool.js +36 -0
  143. package/dist/test-search-tool.js.map +1 -0
  144. package/dist/tools/read-file.test.js +15 -0
  145. package/dist/tools/read-file.test.js.map +1 -1
  146. package/dist/tools/search-replace.d.ts.map +1 -1
  147. package/dist/tools/search-replace.js +157 -1
  148. package/dist/tools/search-replace.js.map +1 -1
  149. package/dist/tools/search-replace.test.js +177 -0
  150. package/dist/tools/search-replace.test.js.map +1 -1
  151. package/dist/tools/tool-capabilities.d.ts +6 -0
  152. package/dist/tools/tool-capabilities.d.ts.map +1 -0
  153. package/dist/tools/tool-capabilities.js +17 -0
  154. package/dist/tools/tool-capabilities.js.map +1 -0
  155. package/dist/tools/types.d.ts +4 -2
  156. package/dist/tools/types.d.ts.map +1 -1
  157. package/dist/tools/utils.d.ts.map +1 -1
  158. package/dist/tools/utils.js +4 -1
  159. package/dist/tools/utils.js.map +1 -1
  160. package/dist/tools/utils.test.d.ts +2 -0
  161. package/dist/tools/utils.test.d.ts.map +1 -0
  162. package/dist/tools/utils.test.js +26 -0
  163. package/dist/tools/utils.test.js.map +1 -0
  164. package/dist/types/messages.d.ts +29 -0
  165. package/dist/types/messages.d.ts.map +1 -0
  166. package/dist/types/messages.js +2 -0
  167. package/dist/types/messages.js.map +1 -0
  168. package/dist/utils/command-safety.d.ts.map +1 -1
  169. package/dist/utils/command-safety.js +364 -10
  170. package/dist/utils/command-safety.js.map +1 -1
  171. package/dist/utils/conversation-event-handler.d.ts +16 -10
  172. package/dist/utils/conversation-event-handler.d.ts.map +1 -1
  173. package/dist/utils/conversation-event-handler.js +4 -0
  174. package/dist/utils/conversation-event-handler.js.map +1 -1
  175. package/dist/utils/extract-command-messages.repro.test.d.ts +2 -0
  176. package/dist/utils/extract-command-messages.repro.test.d.ts.map +1 -0
  177. package/dist/utils/extract-command-messages.repro.test.js +31 -0
  178. package/dist/utils/extract-command-messages.repro.test.js.map +1 -0
  179. package/dist/utils/extract-command-messages.test.js +51 -58
  180. package/dist/utils/message-utils.d.ts +17 -0
  181. package/dist/utils/message-utils.d.ts.map +1 -0
  182. package/dist/utils/message-utils.js +52 -0
  183. package/dist/utils/message-utils.js.map +1 -0
  184. package/dist/utils/message-utils.test.d.ts +2 -0
  185. package/dist/utils/message-utils.test.d.ts.map +1 -0
  186. package/dist/utils/message-utils.test.js +48 -0
  187. package/dist/utils/message-utils.test.js.map +1 -0
  188. package/dist/utils/streaming-session-factory.d.ts +9 -9
  189. package/dist/utils/streaming-session-factory.d.ts.map +1 -1
  190. package/dist/utils/streaming-session-factory.js +7 -2
  191. package/dist/utils/streaming-session-factory.js.map +1 -1
  192. package/dist/utils/synchronized-output.d.ts +35 -0
  193. package/dist/utils/synchronized-output.d.ts.map +1 -0
  194. package/dist/utils/synchronized-output.js +66 -0
  195. package/dist/utils/synchronized-output.js.map +1 -0
  196. package/dist/utils/synchronized-output.test.d.ts +2 -0
  197. package/dist/utils/synchronized-output.test.d.ts.map +1 -0
  198. package/dist/utils/synchronized-output.test.js +70 -0
  199. package/dist/utils/synchronized-output.test.js.map +1 -0
  200. package/package.json +1 -1
  201. package/dist/agent.lite-mode.test.d.ts +0 -2
  202. package/dist/agent.lite-mode.test.d.ts.map +0 -1
  203. package/dist/agent.lite-mode.test.js +0 -39
  204. package/dist/agent.lite-mode.test.js.map +0 -1
  205. package/dist/debug_ask_mentor.d.ts +0 -2
  206. package/dist/debug_ask_mentor.d.ts.map +0 -1
  207. package/dist/debug_ask_mentor.js +0 -73
  208. package/dist/debug_ask_mentor.js.map +0 -1
  209. package/dist/modes/companion/command-index.d.ts +0 -26
  210. package/dist/modes/companion/command-index.d.ts.map +0 -1
  211. package/dist/modes/companion/command-index.js +0 -50
  212. package/dist/modes/companion/command-index.js.map +0 -1
  213. package/dist/modes/companion/command-index.test.d.ts +0 -2
  214. package/dist/modes/companion/command-index.test.d.ts.map +0 -1
  215. package/dist/modes/companion/command-index.test.js +0 -86
  216. package/dist/modes/companion/command-index.test.js.map +0 -1
  217. package/dist/modes/companion/companion-app.d.ts +0 -12
  218. package/dist/modes/companion/companion-app.d.ts.map +0 -1
  219. package/dist/modes/companion/companion-app.js +0 -297
  220. package/dist/modes/companion/companion-app.js.map +0 -1
  221. package/dist/modes/companion/companion-session.d.ts +0 -63
  222. package/dist/modes/companion/companion-session.d.ts.map +0 -1
  223. package/dist/modes/companion/companion-session.js +0 -146
  224. package/dist/modes/companion/companion-session.js.map +0 -1
  225. package/dist/modes/companion/companion-session.test.d.ts +0 -2
  226. package/dist/modes/companion/companion-session.test.d.ts.map +0 -1
  227. package/dist/modes/companion/companion-session.test.js +0 -28
  228. package/dist/modes/companion/companion-session.test.js.map +0 -1
  229. package/dist/modes/companion/components/status-bar.d.ts +0 -13
  230. package/dist/modes/companion/components/status-bar.d.ts.map +0 -1
  231. package/dist/modes/companion/components/status-bar.js +0 -26
  232. package/dist/modes/companion/components/status-bar.js.map +0 -1
  233. package/dist/modes/companion/context-buffer.d.ts +0 -65
  234. package/dist/modes/companion/context-buffer.d.ts.map +0 -1
  235. package/dist/modes/companion/context-buffer.js +0 -156
  236. package/dist/modes/companion/context-buffer.js.map +0 -1
  237. package/dist/modes/companion/context-buffer.test.d.ts +0 -2
  238. package/dist/modes/companion/context-buffer.test.d.ts.map +0 -1
  239. package/dist/modes/companion/context-buffer.test.js +0 -154
  240. package/dist/modes/companion/context-buffer.test.js.map +0 -1
  241. package/dist/modes/companion/event-detector.d.ts +0 -46
  242. package/dist/modes/companion/event-detector.d.ts.map +0 -1
  243. package/dist/modes/companion/event-detector.js +0 -169
  244. package/dist/modes/companion/event-detector.js.map +0 -1
  245. package/dist/modes/companion/event-detector.test.d.ts +0 -2
  246. package/dist/modes/companion/event-detector.test.d.ts.map +0 -1
  247. package/dist/modes/companion/event-detector.test.js +0 -121
  248. package/dist/modes/companion/event-detector.test.js.map +0 -1
  249. package/dist/modes/companion/index.d.ts +0 -33
  250. package/dist/modes/companion/index.d.ts.map +0 -1
  251. package/dist/modes/companion/index.js +0 -21
  252. package/dist/modes/companion/index.js.map +0 -1
  253. package/dist/modes/companion/input-key-mapper.d.ts +0 -3
  254. package/dist/modes/companion/input-key-mapper.d.ts.map +0 -1
  255. package/dist/modes/companion/input-key-mapper.js +0 -31
  256. package/dist/modes/companion/input-key-mapper.js.map +0 -1
  257. package/dist/modes/companion/input-key-mapper.test.d.ts +0 -2
  258. package/dist/modes/companion/input-key-mapper.test.d.ts.map +0 -1
  259. package/dist/modes/companion/input-key-mapper.test.js +0 -26
  260. package/dist/modes/companion/input-key-mapper.test.js.map +0 -1
  261. package/dist/modes/companion/input-parser.d.ts +0 -53
  262. package/dist/modes/companion/input-parser.d.ts.map +0 -1
  263. package/dist/modes/companion/input-parser.js +0 -114
  264. package/dist/modes/companion/input-parser.js.map +0 -1
  265. package/dist/modes/companion/input-parser.test.d.ts +0 -2
  266. package/dist/modes/companion/input-parser.test.d.ts.map +0 -1
  267. package/dist/modes/companion/input-parser.test.js +0 -123
  268. package/dist/modes/companion/input-parser.test.js.map +0 -1
  269. package/dist/modes/companion/mode-manager.d.ts +0 -41
  270. package/dist/modes/companion/mode-manager.d.ts.map +0 -1
  271. package/dist/modes/companion/mode-manager.js +0 -56
  272. package/dist/modes/companion/mode-manager.js.map +0 -1
  273. package/dist/modes/companion/mode-manager.test.d.ts +0 -2
  274. package/dist/modes/companion/mode-manager.test.d.ts.map +0 -1
  275. package/dist/modes/companion/mode-manager.test.js +0 -65
  276. package/dist/modes/companion/mode-manager.test.js.map +0 -1
  277. package/dist/modes/companion/output-classifier.d.ts +0 -15
  278. package/dist/modes/companion/output-classifier.d.ts.map +0 -1
  279. package/dist/modes/companion/output-classifier.js +0 -77
  280. package/dist/modes/companion/output-classifier.js.map +0 -1
  281. package/dist/modes/companion/output-classifier.test.d.ts +0 -2
  282. package/dist/modes/companion/output-classifier.test.d.ts.map +0 -1
  283. package/dist/modes/companion/output-classifier.test.js +0 -133
  284. package/dist/modes/companion/output-classifier.test.js.map +0 -1
  285. package/dist/modes/companion/pty-wrapper.d.ts +0 -46
  286. package/dist/modes/companion/pty-wrapper.d.ts.map +0 -1
  287. package/dist/modes/companion/pty-wrapper.js +0 -143
  288. package/dist/modes/companion/pty-wrapper.js.map +0 -1
  289. package/dist/modes/companion/safety-classifier.d.ts +0 -31
  290. package/dist/modes/companion/safety-classifier.d.ts.map +0 -1
  291. package/dist/modes/companion/safety-classifier.js +0 -140
  292. package/dist/modes/companion/safety-classifier.js.map +0 -1
  293. package/dist/modes/companion/safety-classifier.test.d.ts +0 -2
  294. package/dist/modes/companion/safety-classifier.test.d.ts.map +0 -1
  295. package/dist/modes/companion/safety-classifier.test.js +0 -151
  296. package/dist/modes/companion/safety-classifier.test.js.map +0 -1
  297. package/dist/modes/companion/summarizer.d.ts +0 -24
  298. package/dist/modes/companion/summarizer.d.ts.map +0 -1
  299. package/dist/modes/companion/summarizer.js +0 -132
  300. package/dist/modes/companion/summarizer.js.map +0 -1
  301. package/dist/modes/companion/terminal-history.d.ts +0 -27
  302. package/dist/modes/companion/terminal-history.d.ts.map +0 -1
  303. package/dist/modes/companion/terminal-history.js +0 -142
  304. package/dist/modes/companion/terminal-history.js.map +0 -1
  305. package/dist/providers/github-copilot/model.test.d.ts +0 -2
  306. package/dist/providers/github-copilot/model.test.d.ts.map +0 -1
  307. package/dist/providers/github-copilot/model.test.js +0 -63
  308. package/dist/providers/github-copilot/model.test.js.map +0 -1
  309. package/dist/services/check_mock.d.ts +0 -2
  310. package/dist/services/check_mock.d.ts.map +0 -1
  311. package/dist/services/check_mock.js +0 -22
  312. package/dist/services/check_mock.js.map +0 -1
  313. package/dist/services/conversation-service.test.d.ts +0 -2
  314. package/dist/services/conversation-service.test.d.ts.map +0 -1
  315. package/dist/services/conversation-service.test.js.map +0 -1
  316. package/dist/utils/command-safety.devnull.test.d.ts +0 -2
  317. package/dist/utils/command-safety.devnull.test.d.ts.map +0 -1
  318. package/dist/utils/command-safety.devnull.test.js +0 -13
  319. package/dist/utils/command-safety.devnull.test.js.map +0 -1
  320. package/dist/utils/extract-command-messages.test.d.ts +0 -2
  321. package/dist/utils/extract-command-messages.test.d.ts.map +0 -1
  322. package/dist/utils/extract-command-messages.test.js.map +0 -1
@@ -0,0 +1,440 @@
1
+ import test from 'ava';
2
+ import { MentorClient } from './mentor-client.js';
3
+ // ========== Mock Utilities ==========
4
+ function createMockLogger() {
5
+ return {
6
+ debug: () => { },
7
+ info: () => { },
8
+ warn: () => { },
9
+ error: () => { },
10
+ security: () => { },
11
+ setCorrelationId: () => { },
12
+ clearCorrelationId: () => { },
13
+ getCorrelationId: () => undefined,
14
+ log: () => { },
15
+ };
16
+ }
17
+ function createMockSettings(values = {}) {
18
+ const store = {
19
+ 'agent.provider': 'test-provider',
20
+ 'agent.model': 'test-model',
21
+ 'agent.mentorModel': 'mentor-model',
22
+ 'agent.mentorProvider': 'test-mentor-provider',
23
+ 'agent.mentorReasoningEffort': 'default',
24
+ 'app.mentorMode': false,
25
+ ...values,
26
+ };
27
+ return {
28
+ get: (key) => store[key],
29
+ set: (key, value) => {
30
+ store[key] = value;
31
+ },
32
+ };
33
+ }
34
+ // ========== consult tests ==========
35
+ test('consult throws when mentorModel is not configured', async (t) => {
36
+ const settings = createMockSettings({ 'agent.mentorModel': undefined });
37
+ const runAgent = async () => ({ finalOutput: 'hi' });
38
+ const createRunner = () => null;
39
+ const mentor = new MentorClient({
40
+ runAgent,
41
+ createRunner,
42
+ logger: createMockLogger(),
43
+ settings,
44
+ });
45
+ await t.throwsAsync(() => mentor.consult('hello'), {
46
+ message: 'Mentor model is not configured',
47
+ });
48
+ });
49
+ test('consult returns finalOutput from agent result', async (t) => {
50
+ const runAgent = async () => ({
51
+ finalOutput: 'mentor says hello',
52
+ history: [],
53
+ messages: [],
54
+ });
55
+ const createRunner = () => ({ run: async () => ({}) });
56
+ const mentor = new MentorClient({
57
+ runAgent,
58
+ createRunner,
59
+ logger: createMockLogger(),
60
+ settings: createMockSettings(),
61
+ });
62
+ const result = await mentor.consult('hello');
63
+ t.is(result, 'mentor says hello');
64
+ });
65
+ test('consult extracts response from messages when finalOutput is missing', async (t) => {
66
+ const runAgent = async () => ({
67
+ finalOutput: undefined,
68
+ history: [],
69
+ messages: [{ content: 'fallback response' }],
70
+ });
71
+ const createRunner = () => ({ run: async () => ({}) });
72
+ const mentor = new MentorClient({
73
+ runAgent,
74
+ createRunner,
75
+ logger: createMockLogger(),
76
+ settings: createMockSettings(),
77
+ });
78
+ const result = await mentor.consult('hello');
79
+ t.is(result, 'fallback response');
80
+ });
81
+ test('consult extracts response from array message content', async (t) => {
82
+ const runAgent = async () => ({
83
+ finalOutput: undefined,
84
+ history: [],
85
+ messages: [{ content: [{ text: 'part1' }, { text: 'part2' }] }],
86
+ });
87
+ const createRunner = () => ({ run: async () => ({}) });
88
+ const mentor = new MentorClient({
89
+ runAgent,
90
+ createRunner,
91
+ logger: createMockLogger(),
92
+ settings: createMockSettings(),
93
+ });
94
+ const result = await mentor.consult('hello');
95
+ t.is(result, 'part1part2');
96
+ });
97
+ test('consult returns empty string when no output available', async (t) => {
98
+ const runAgent = async () => ({
99
+ finalOutput: undefined,
100
+ history: [],
101
+ messages: [],
102
+ });
103
+ const createRunner = () => ({ run: async () => ({}) });
104
+ const mentor = new MentorClient({
105
+ runAgent,
106
+ createRunner,
107
+ logger: createMockLogger(),
108
+ settings: createMockSettings(),
109
+ });
110
+ const result = await mentor.consult('hello');
111
+ t.is(result, '');
112
+ });
113
+ test('consult passes correct provider and options to runAgent', async (t) => {
114
+ const calls = [];
115
+ const mockRunner = { run: async () => ({}) };
116
+ const runAgent = async (providerId, runner, _agent, input, options) => {
117
+ calls.push({ providerId, runner, input, options });
118
+ return { finalOutput: 'ok', history: [], messages: [] };
119
+ };
120
+ const createRunner = () => mockRunner;
121
+ const mentor = new MentorClient({
122
+ runAgent,
123
+ createRunner,
124
+ logger: createMockLogger(),
125
+ settings: createMockSettings({ 'agent.mentorProvider': 'custom-provider' }),
126
+ });
127
+ await mentor.consult('test question');
128
+ t.is(calls.length, 1);
129
+ t.is(calls[0].providerId, 'custom-provider');
130
+ t.is(calls[0].runner, mockRunner);
131
+ t.deepEqual(calls[0].options, { stream: false, maxTurns: 1 });
132
+ // Non-OpenAI providers get full history array
133
+ t.true(Array.isArray(calls[0].input));
134
+ });
135
+ test('consult uses main provider when mentorProvider is not set', async (t) => {
136
+ const calls = [];
137
+ const runAgent = async (providerId, _runner, _agent, _input, _options) => {
138
+ calls.push({ providerId });
139
+ return { finalOutput: 'ok', history: [], messages: [] };
140
+ };
141
+ const createRunner = () => ({ run: async () => ({}) });
142
+ const mentor = new MentorClient({
143
+ runAgent,
144
+ createRunner,
145
+ logger: createMockLogger(),
146
+ settings: createMockSettings({
147
+ 'agent.provider': 'main-provider',
148
+ 'agent.mentorProvider': undefined,
149
+ }),
150
+ });
151
+ await mentor.consult('test');
152
+ t.is(calls[0].providerId, 'main-provider');
153
+ });
154
+ test('consult builds conversation history across calls for non-OpenAI provider', async (t) => {
155
+ const inputs = [];
156
+ let counter = 0;
157
+ const runAgent = async (_providerId, _runner, _agent, input, _options) => {
158
+ inputs.push(input);
159
+ counter++;
160
+ return {
161
+ finalOutput: `response-${counter}`,
162
+ history: [],
163
+ messages: [],
164
+ };
165
+ };
166
+ const createRunner = () => ({ run: async () => ({}) });
167
+ const mentor = new MentorClient({
168
+ runAgent,
169
+ createRunner,
170
+ logger: createMockLogger(),
171
+ settings: createMockSettings({ 'agent.mentorProvider': 'custom' }),
172
+ });
173
+ await mentor.consult('question 1');
174
+ await mentor.consult('question 2');
175
+ t.is(inputs.length, 2);
176
+ // First call: single message in history
177
+ t.true(Array.isArray(inputs[0]));
178
+ t.is(inputs[0].length, 1);
179
+ // Second call: two messages in history (first question + second question)
180
+ t.true(Array.isArray(inputs[1]));
181
+ t.true(inputs[1].length > 1);
182
+ });
183
+ test('consult passes previousResponseId for OpenAI provider', async (t) => {
184
+ const calls = [];
185
+ const runAgent = async (providerId, _runner, _agent, input, options) => {
186
+ calls.push({ providerId, input, options });
187
+ return {
188
+ finalOutput: 'ok',
189
+ responseId: 'resp-123',
190
+ history: [],
191
+ messages: [],
192
+ };
193
+ };
194
+ const createRunner = () => null;
195
+ const mentor = new MentorClient({
196
+ runAgent,
197
+ createRunner,
198
+ logger: createMockLogger(),
199
+ settings: createMockSettings({ 'agent.mentorProvider': 'openai' }),
200
+ });
201
+ await mentor.consult('first');
202
+ await mentor.consult('second');
203
+ // First call should not have previousResponseId
204
+ t.deepEqual(calls[0].options, { stream: false, maxTurns: 1 });
205
+ // Second call should include it
206
+ t.is(calls[1].options.previousResponseId, 'resp-123');
207
+ // OpenAI provider passes string input, not array
208
+ t.is(typeof calls[1].input, 'string');
209
+ });
210
+ // ========== reset tests ==========
211
+ test('reset clears conversation history', async (t) => {
212
+ const inputs = [];
213
+ const runAgent = async (_providerId, _runner, _agent, input, _options) => {
214
+ inputs.push(input);
215
+ return { finalOutput: 'ok', history: [], messages: [] };
216
+ };
217
+ const createRunner = () => ({ run: async () => ({}) });
218
+ const mentor = new MentorClient({
219
+ runAgent,
220
+ createRunner,
221
+ logger: createMockLogger(),
222
+ settings: createMockSettings({ 'agent.mentorProvider': 'custom' }),
223
+ });
224
+ await mentor.consult('question 1');
225
+ await mentor.consult('question 2');
226
+ t.true(inputs[1].length > 1); // history accumulated
227
+ mentor.reset();
228
+ await mentor.consult('question 3');
229
+ // After reset, history should be fresh (single message)
230
+ t.is(inputs[2].length, 1);
231
+ });
232
+ test('reset clears previousResponseId for OpenAI provider', async (t) => {
233
+ const calls = [];
234
+ const runAgent = async (_providerId, _runner, _agent, input, options) => {
235
+ calls.push({ input, options });
236
+ return {
237
+ finalOutput: 'ok',
238
+ responseId: 'resp-abc',
239
+ history: [],
240
+ messages: [],
241
+ };
242
+ };
243
+ const createRunner = () => null;
244
+ const mentor = new MentorClient({
245
+ runAgent,
246
+ createRunner,
247
+ logger: createMockLogger(),
248
+ settings: createMockSettings({ 'agent.mentorProvider': 'openai' }),
249
+ });
250
+ await mentor.consult('first');
251
+ t.falsy(calls[0].options.previousResponseId);
252
+ mentor.reset();
253
+ await mentor.consult('after reset');
254
+ // After reset, previousResponseId should be cleared
255
+ t.falsy(calls[1].options.previousResponseId);
256
+ });
257
+ test('reset can be called without prior consult', (t) => {
258
+ const mentor = new MentorClient({
259
+ runAgent: async () => ({}),
260
+ createRunner: () => null,
261
+ logger: createMockLogger(),
262
+ settings: createMockSettings(),
263
+ });
264
+ t.notThrows(() => mentor.reset());
265
+ });
266
+ // ========== provider switching tests ==========
267
+ test('consult resets state when mentor provider changes', async (t) => {
268
+ const inputs = [];
269
+ const settings = createMockSettings({ 'agent.mentorProvider': 'provider-a' });
270
+ const runAgent = async (_providerId, _runner, _agent, input, _options) => {
271
+ inputs.push(input);
272
+ return { finalOutput: 'ok', history: [], messages: [] };
273
+ };
274
+ const createRunner = () => ({ run: async () => ({}) });
275
+ const mentor = new MentorClient({
276
+ runAgent,
277
+ createRunner,
278
+ logger: createMockLogger(),
279
+ settings,
280
+ });
281
+ await mentor.consult('q1');
282
+ await mentor.consult('q2');
283
+ t.true(inputs[1].length > 1); // accumulated history
284
+ // Switch provider
285
+ settings.set('agent.mentorProvider', 'provider-b');
286
+ await mentor.consult('q3');
287
+ // After provider switch, history should be fresh
288
+ t.is(inputs[2].length, 1);
289
+ });
290
+ test('consult creates new runner when provider changes', async (t) => {
291
+ const runnersCreated = [];
292
+ const settings = createMockSettings({ 'agent.mentorProvider': 'provider-a' });
293
+ const createRunner = (providerId) => {
294
+ runnersCreated.push(providerId);
295
+ return { run: async () => ({}) };
296
+ };
297
+ const runAgent = async () => ({
298
+ finalOutput: 'ok',
299
+ history: [],
300
+ messages: [],
301
+ });
302
+ const mentor = new MentorClient({
303
+ runAgent,
304
+ createRunner,
305
+ logger: createMockLogger(),
306
+ settings,
307
+ });
308
+ await mentor.consult('q1');
309
+ t.deepEqual(runnersCreated, ['provider-a']);
310
+ // Switch provider
311
+ settings.set('agent.mentorProvider', 'provider-b');
312
+ await mentor.consult('q2');
313
+ t.deepEqual(runnersCreated, ['provider-a', 'provider-b']);
314
+ });
315
+ // ========== error handling ==========
316
+ test('consult propagates errors from runAgent', async (t) => {
317
+ const runAgent = async () => {
318
+ throw new Error('network failure');
319
+ };
320
+ const createRunner = () => ({ run: async () => ({}) });
321
+ const mentor = new MentorClient({
322
+ runAgent,
323
+ createRunner,
324
+ logger: createMockLogger(),
325
+ settings: createMockSettings(),
326
+ });
327
+ await t.throwsAsync(() => mentor.consult('hello'), {
328
+ message: 'network failure',
329
+ });
330
+ });
331
+ test('consult logs errors on failure', async (t) => {
332
+ const loggedErrors = [];
333
+ const logger = createMockLogger();
334
+ logger.error = (msg, meta) => {
335
+ loggedErrors.push({ msg, meta });
336
+ };
337
+ const runAgent = async () => {
338
+ throw new Error('boom');
339
+ };
340
+ const mentor = new MentorClient({
341
+ runAgent,
342
+ createRunner: () => ({ run: async () => ({}) }),
343
+ logger,
344
+ settings: createMockSettings(),
345
+ });
346
+ await t.throwsAsync(() => mentor.consult('test'));
347
+ t.is(loggedErrors.length, 1);
348
+ t.is(loggedErrors[0].msg, 'Mentor consultation failed');
349
+ });
350
+ // ========== reasoning effort ==========
351
+ test('consult applies mentorReasoningEffort to agent model settings', async (t) => {
352
+ let capturedAgent = null;
353
+ const runAgent = async (_providerId, _runner, agent, _input, _options) => {
354
+ capturedAgent = agent;
355
+ return { finalOutput: 'ok', history: [], messages: [] };
356
+ };
357
+ const mentor = new MentorClient({
358
+ runAgent,
359
+ createRunner: () => ({ run: async () => ({}) }),
360
+ logger: createMockLogger(),
361
+ settings: createMockSettings({ 'agent.mentorReasoningEffort': 'high' }),
362
+ });
363
+ await mentor.consult('test');
364
+ t.truthy(capturedAgent);
365
+ // The agent should have reasoning effort in modelSettings
366
+ t.deepEqual(capturedAgent.modelSettings?.reasoning, { effort: 'high', summary: 'auto' });
367
+ });
368
+ test('consult does not set reasoning when effort is default', async (t) => {
369
+ let capturedAgent = null;
370
+ const runAgent = async (_providerId, _runner, agent, _input, _options) => {
371
+ capturedAgent = agent;
372
+ return { finalOutput: 'ok', history: [], messages: [] };
373
+ };
374
+ const mentor = new MentorClient({
375
+ runAgent,
376
+ createRunner: () => ({ run: async () => ({}) }),
377
+ logger: createMockLogger(),
378
+ settings: createMockSettings({ 'agent.mentorReasoningEffort': 'default' }),
379
+ });
380
+ await mentor.consult('test');
381
+ t.truthy(capturedAgent);
382
+ // Should not have reasoning in modelSettings
383
+ t.falsy(capturedAgent.modelSettings?.reasoning);
384
+ });
385
+ // ========== mentor mode instructions ==========
386
+ test('consult uses mentor mode instructions when app.mentorMode is true', async (t) => {
387
+ let capturedAgent = null;
388
+ const runAgent = async (_providerId, _runner, agent, _input, _options) => {
389
+ capturedAgent = agent;
390
+ return { finalOutput: 'ok', history: [], messages: [] };
391
+ };
392
+ const mentor = new MentorClient({
393
+ runAgent,
394
+ createRunner: () => ({ run: async () => ({}) }),
395
+ logger: createMockLogger(),
396
+ settings: createMockSettings({ 'app.mentorMode': true }),
397
+ });
398
+ await mentor.consult('test');
399
+ t.truthy(capturedAgent);
400
+ t.true(capturedAgent.instructions.includes('senior architect'));
401
+ t.true(capturedAgent.instructions.includes('adversarial review'));
402
+ });
403
+ test('consult uses default mentor instructions when app.mentorMode is false', async (t) => {
404
+ let capturedAgent = null;
405
+ const runAgent = async (_providerId, _runner, agent, _input, _options) => {
406
+ capturedAgent = agent;
407
+ return { finalOutput: 'ok', history: [], messages: [] };
408
+ };
409
+ const mentor = new MentorClient({
410
+ runAgent,
411
+ createRunner: () => ({ run: async () => ({}) }),
412
+ logger: createMockLogger(),
413
+ settings: createMockSettings({ 'app.mentorMode': false }),
414
+ });
415
+ await mentor.consult('test');
416
+ t.truthy(capturedAgent);
417
+ t.true(capturedAgent.instructions.includes('helpful mentor assistant'));
418
+ });
419
+ // ========== skips runner creation for openai ==========
420
+ test('consult does not create runner for openai provider', async (t) => {
421
+ const runnersCreated = [];
422
+ const createRunner = (providerId) => {
423
+ runnersCreated.push(providerId);
424
+ return { run: async () => ({}) };
425
+ };
426
+ const runAgent = async () => ({
427
+ finalOutput: 'ok',
428
+ history: [],
429
+ messages: [],
430
+ });
431
+ const mentor = new MentorClient({
432
+ runAgent,
433
+ createRunner,
434
+ logger: createMockLogger(),
435
+ settings: createMockSettings({ 'agent.mentorProvider': 'openai' }),
436
+ });
437
+ await mentor.consult('test');
438
+ t.deepEqual(runnersCreated, []);
439
+ });
440
+ //# sourceMappingURL=mentor-client.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mentor-client.test.js","sourceRoot":"","sources":["../../source/lib/mentor-client.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Returns true when the error is transient and the request can be retried.
3
+ */
4
+ export declare function isTransientError(error: unknown): boolean;
5
+ /**
6
+ * Extracts the Retry-After header value (in ms) from a supported error type.
7
+ * Returns `undefined` when the header is absent.
8
+ */
9
+ export declare function getRetryAfterMs(error: unknown): number | undefined;
10
+ /**
11
+ * Computes an exponential-backoff delay with full jitter.
12
+ *
13
+ * Formula: random in [0, min(baseDelay * 2^attemptIndex, maxDelay)]
14
+ * where baseDelay ∈ [500, 1000) ms, maxDelay = 30 000 ms.
15
+ *
16
+ * @param attemptIndex Zero-based retry attempt (0 = first retry).
17
+ * @param random RNG returning [0, 1). Defaults to Math.random.
18
+ */
19
+ export declare function computeBackoffDelay(attemptIndex: number, random?: () => number): number;
20
+ export interface RetryOptions {
21
+ /** Maximum number of retries (default 2). */
22
+ retries: number;
23
+ /** RNG returning [0, 1). Defaults to Math.random. Primarily for deterministic tests. */
24
+ random?: () => number;
25
+ /** Sleep implementation. Defaults to setTimeout-based sleep. Primarily for tests. */
26
+ sleep?: (ms: number) => Promise<void>;
27
+ /**
28
+ * Called just before each retry sleep.
29
+ * Receives attempt metadata so callers can log / notify.
30
+ */
31
+ onRetry?: (info: {
32
+ attemptIndex: number;
33
+ delay: number;
34
+ error: unknown;
35
+ }) => void;
36
+ }
37
+ /**
38
+ * Runs `operation`, retrying on transient errors with exponential backoff + jitter.
39
+ *
40
+ * Mirrors the behaviour previously embedded in OpenAIAgentClient.#executeWithRetry.
41
+ */
42
+ export declare function executeWithRetry<T>(operation: () => Promise<T>, opts: RetryOptions): Promise<T>;
43
+ //# sourceMappingURL=retry-strategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry-strategy.d.ts","sourceRoot":"","sources":["../../source/lib/retry-strategy.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAmBxD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAmBlE;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,MAAoB,GAAG,MAAM,CAOpG;AAED,MAAM,WAAW,YAAY;IAC3B,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,wFAAwF;IACxF,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,qFAAqF;IACrF,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CACnF;AAMD;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CA0BrG"}
@@ -0,0 +1,93 @@
1
+ import { APIConnectionError, APIConnectionTimeoutError, InternalServerError, RateLimitError } from 'openai';
2
+ import { OpenRouterError } from '../providers/openrouter.js';
3
+ import { OpenAICompatibleError } from '../providers/openai-compatible/api.js';
4
+ /**
5
+ * Returns true when the error is transient and the request can be retried.
6
+ */
7
+ export function isTransientError(error) {
8
+ if (error instanceof APIConnectionError ||
9
+ error instanceof APIConnectionTimeoutError ||
10
+ error instanceof InternalServerError ||
11
+ error instanceof RateLimitError) {
12
+ return true;
13
+ }
14
+ if (error instanceof OpenRouterError && (error.status === 429 || error.status >= 500)) {
15
+ return true;
16
+ }
17
+ if (error instanceof OpenAICompatibleError && (error.status === 429 || error.status >= 500)) {
18
+ return true;
19
+ }
20
+ return false;
21
+ }
22
+ /**
23
+ * Extracts the Retry-After header value (in ms) from a supported error type.
24
+ * Returns `undefined` when the header is absent.
25
+ */
26
+ export function getRetryAfterMs(error) {
27
+ let header;
28
+ if (error instanceof RateLimitError) {
29
+ header = error.headers?.['retry-after'] ?? undefined;
30
+ }
31
+ else if (error instanceof OpenRouterError) {
32
+ header = error.headers['retry-after'];
33
+ }
34
+ else if (error instanceof OpenAICompatibleError) {
35
+ header = error.headers['retry-after'];
36
+ }
37
+ if (header) {
38
+ const seconds = parseInt(header, 10);
39
+ if (!Number.isNaN(seconds)) {
40
+ return seconds * 1000;
41
+ }
42
+ }
43
+ return undefined;
44
+ }
45
+ /**
46
+ * Computes an exponential-backoff delay with full jitter.
47
+ *
48
+ * Formula: random in [0, min(baseDelay * 2^attemptIndex, maxDelay)]
49
+ * where baseDelay ∈ [500, 1000) ms, maxDelay = 30 000 ms.
50
+ *
51
+ * @param attemptIndex Zero-based retry attempt (0 = first retry).
52
+ * @param random RNG returning [0, 1). Defaults to Math.random.
53
+ */
54
+ export function computeBackoffDelay(attemptIndex, random = Math.random) {
55
+ const baseDelay = 500 + random() * 500; // 500-1000ms
56
+ const exponentialDelay = baseDelay * Math.pow(2, attemptIndex);
57
+ const maxDelay = 30_000;
58
+ const cappedDelay = Math.min(exponentialDelay, maxDelay);
59
+ // Full jitter: random value between 0 and cappedDelay
60
+ return random() * cappedDelay;
61
+ }
62
+ function defaultSleep(ms) {
63
+ return new Promise((resolve) => setTimeout(resolve, ms));
64
+ }
65
+ /**
66
+ * Runs `operation`, retrying on transient errors with exponential backoff + jitter.
67
+ *
68
+ * Mirrors the behaviour previously embedded in OpenAIAgentClient.#executeWithRetry.
69
+ */
70
+ export async function executeWithRetry(operation, opts) {
71
+ let retriesRemaining = opts.retries;
72
+ let attemptIndex = 0;
73
+ const sleep = opts.sleep ?? defaultSleep;
74
+ const random = opts.random ?? Math.random;
75
+ // eslint-disable-next-line no-constant-condition
76
+ while (true) {
77
+ try {
78
+ return await operation();
79
+ }
80
+ catch (error) {
81
+ if (retriesRemaining <= 0 || !isTransientError(error)) {
82
+ throw error;
83
+ }
84
+ const retryAfter = getRetryAfterMs(error);
85
+ const delay = retryAfter ?? computeBackoffDelay(attemptIndex, random);
86
+ opts.onRetry?.({ attemptIndex, delay, error });
87
+ await sleep(delay);
88
+ retriesRemaining--;
89
+ attemptIndex++;
90
+ }
91
+ }
92
+ }
93
+ //# sourceMappingURL=retry-strategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry-strategy.js","sourceRoot":"","sources":["../../source/lib/retry-strategy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=retry-strategy.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry-strategy.test.d.ts","sourceRoot":"","sources":["../../source/lib/retry-strategy.test.ts"],"names":[],"mappings":""}