@timetotest/cli 0.2.3 → 0.3.0

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 (200) hide show
  1. package/README.md +49 -40
  2. package/dist/bin/ttt.js +0 -2
  3. package/dist/bin/ttt.js.map +1 -1
  4. package/dist/package.json +13 -6
  5. package/dist/src/commands/chat/ChatApp.js +270 -100
  6. package/dist/src/commands/chat/ChatApp.js.map +1 -1
  7. package/dist/src/commands/chat/components/Banner.js +1 -1
  8. package/dist/src/commands/chat/components/ChatInput.js +97 -36
  9. package/dist/src/commands/chat/components/ChatInput.js.map +1 -1
  10. package/dist/src/commands/chat/components/ChatMessage.js +102 -0
  11. package/dist/src/commands/chat/components/ChatMessage.js.map +1 -0
  12. package/dist/src/commands/chat/components/MessageBubble.js +2 -1
  13. package/dist/src/commands/chat/components/MessageBubble.js.map +1 -1
  14. package/dist/src/commands/chat/components/PermissionPrompt.js +92 -0
  15. package/dist/src/commands/chat/components/PermissionPrompt.js.map +1 -0
  16. package/dist/src/commands/chat/components/StatusIndicator.js +21 -5
  17. package/dist/src/commands/chat/components/StatusIndicator.js.map +1 -1
  18. package/dist/src/commands/chat/components/ToolCallDisplay.js +141 -0
  19. package/dist/src/commands/chat/components/ToolCallDisplay.js.map +1 -0
  20. package/dist/src/commands/chat-ink.js +389 -61
  21. package/dist/src/commands/chat-ink.js.map +1 -1
  22. package/dist/src/commands/login.js +5 -5
  23. package/dist/src/commands/login.js.map +1 -1
  24. package/dist/src/commands/test.js +14 -194
  25. package/dist/src/commands/test.js.map +1 -1
  26. package/dist/src/lib/__tests__/code-mode-integration.test.js +381 -0
  27. package/dist/src/lib/__tests__/code-mode-integration.test.js.map +1 -0
  28. package/dist/src/lib/__tests__/config-manager.test.js +81 -0
  29. package/dist/src/lib/__tests__/config-manager.test.js.map +1 -0
  30. package/dist/src/lib/__tests__/mode-persistence-integration.test.js +75 -0
  31. package/dist/src/lib/__tests__/mode-persistence-integration.test.js.map +1 -0
  32. package/dist/src/lib/__tests__/permission-flow-integration.test.js +145 -0
  33. package/dist/src/lib/__tests__/permission-flow-integration.test.js.map +1 -0
  34. package/dist/src/lib/__tests__/permissions.test.js +132 -0
  35. package/dist/src/lib/__tests__/permissions.test.js.map +1 -0
  36. package/dist/src/lib/agent-orchestrator.js +263 -4
  37. package/dist/src/lib/agent-orchestrator.js.map +1 -1
  38. package/dist/src/lib/config.js +40 -0
  39. package/dist/src/lib/config.js.map +1 -1
  40. package/dist/src/lib/context-compactor.js +310 -0
  41. package/dist/src/lib/context-compactor.js.map +1 -0
  42. package/dist/src/lib/http.js +8 -0
  43. package/dist/src/lib/http.js.map +1 -1
  44. package/dist/src/lib/local-tools/code/__tests__/grep-search.test.js +146 -0
  45. package/dist/src/lib/local-tools/code/__tests__/grep-search.test.js.map +1 -0
  46. package/dist/src/lib/local-tools/code/__tests__/list-directory.test.js +192 -0
  47. package/dist/src/lib/local-tools/code/__tests__/list-directory.test.js.map +1 -0
  48. package/dist/src/lib/local-tools/code/__tests__/read-file.test.js +169 -0
  49. package/dist/src/lib/local-tools/code/__tests__/read-file.test.js.map +1 -0
  50. package/dist/src/lib/local-tools/code/__tests__/run-command.test.js +101 -0
  51. package/dist/src/lib/local-tools/code/__tests__/run-command.test.js.map +1 -0
  52. package/dist/src/lib/local-tools/code/__tests__/search-files.test.js +191 -0
  53. package/dist/src/lib/local-tools/code/__tests__/search-files.test.js.map +1 -0
  54. package/dist/src/lib/local-tools/code/grep-search.js +404 -0
  55. package/dist/src/lib/local-tools/code/grep-search.js.map +1 -0
  56. package/dist/src/lib/local-tools/code/index.js +11 -0
  57. package/dist/src/lib/local-tools/code/index.js.map +1 -0
  58. package/dist/src/lib/local-tools/code/list-directory.js +276 -0
  59. package/dist/src/lib/local-tools/code/list-directory.js.map +1 -0
  60. package/dist/src/lib/local-tools/code/read-file.js +301 -0
  61. package/dist/src/lib/local-tools/code/read-file.js.map +1 -0
  62. package/dist/src/lib/local-tools/code/run-command.js +235 -0
  63. package/dist/src/lib/local-tools/code/run-command.js.map +1 -0
  64. package/dist/src/lib/local-tools/code/search-files.js +297 -0
  65. package/dist/src/lib/local-tools/code/search-files.js.map +1 -0
  66. package/dist/src/lib/local-tools/code/types.js +6 -0
  67. package/dist/src/lib/local-tools/code/types.js.map +1 -0
  68. package/dist/src/lib/local-tools/ui/playwright-mcp.js +1 -1
  69. package/dist/src/lib/permissions.js +94 -0
  70. package/dist/src/lib/permissions.js.map +1 -0
  71. package/dist/src/lib/prompts/builder.js +13 -10
  72. package/dist/src/lib/prompts/builder.js.map +1 -1
  73. package/dist/src/lib/prompts/templates.js +78 -0
  74. package/dist/src/lib/prompts/templates.js.map +1 -1
  75. package/dist/src/lib/session-manager.js.map +1 -1
  76. package/dist/src/lib/testing-mode.js +2 -2
  77. package/dist/src/lib/testing-mode.js.map +1 -1
  78. package/dist/src/lib/tool-executor.js +131 -2
  79. package/dist/src/lib/tool-executor.js.map +1 -1
  80. package/dist/src/lib/tool-registry.js +171 -3
  81. package/dist/src/lib/tool-registry.js.map +1 -1
  82. package/dist/src/lib/tool-result-pruner.js +4 -4
  83. package/dist/src/lib/tool-result-pruner.js.map +1 -1
  84. package/dist/src/lib/tui/ink/components/AppFrame.js +17 -0
  85. package/dist/src/lib/tui/ink/components/AppFrame.js.map +1 -0
  86. package/dist/src/lib/tui/ink/components/CommandPalette.js +24 -0
  87. package/dist/src/lib/tui/ink/components/CommandPalette.js.map +1 -0
  88. package/dist/src/lib/tui/ink/components/Pill.js +19 -0
  89. package/dist/src/lib/tui/ink/components/Pill.js.map +1 -0
  90. package/dist/src/lib/tui/ink/components/TimetoTestLogo.js +30 -0
  91. package/dist/src/lib/tui/ink/components/TimetoTestLogo.js.map +1 -0
  92. package/dist/src/lib/tui/ink/theme.js +28 -0
  93. package/dist/src/lib/tui/ink/theme.js.map +1 -0
  94. package/dist/src/lib/tui/interactive-chat.js +35 -35
  95. package/dist/src/lib/tui/interactive-chat.js.map +1 -1
  96. package/dist/src/lib/tui/print.js +18 -18
  97. package/dist/src/lib/tui/print.js.map +1 -1
  98. package/dist/src/lib/tui/prompt.js +3 -3
  99. package/dist/src/lib/tui/prompt.js.map +1 -1
  100. package/dist/src/lib/tui/status.js +1 -1
  101. package/dist/src/lib/tui/status.js.map +1 -1
  102. package/dist/src/lib/update.js +10 -10
  103. package/dist/src/lib/update.js.map +1 -1
  104. package/package.json +13 -6
  105. package/dist/src/commands/ask/AskApp.js +0 -121
  106. package/dist/src/commands/ask/AskApp.js.map +0 -1
  107. package/dist/src/commands/ask/components/AssistantResponse.js +0 -31
  108. package/dist/src/commands/ask/components/AssistantResponse.js.map +0 -1
  109. package/dist/src/commands/ask/components/Banner.js +0 -15
  110. package/dist/src/commands/ask/components/Banner.js.map +0 -1
  111. package/dist/src/commands/ask/components/ChatInput.js +0 -93
  112. package/dist/src/commands/ask/components/ChatInput.js.map +0 -1
  113. package/dist/src/commands/ask/components/Divider.js +0 -17
  114. package/dist/src/commands/ask/components/Divider.js.map +0 -1
  115. package/dist/src/commands/ask/components/IntroTips.js +0 -19
  116. package/dist/src/commands/ask/components/IntroTips.js.map +0 -1
  117. package/dist/src/commands/ask/components/MessageBubble.js +0 -47
  118. package/dist/src/commands/ask/components/MessageBubble.js.map +0 -1
  119. package/dist/src/commands/ask/components/SessionInfo.js +0 -20
  120. package/dist/src/commands/ask/components/SessionInfo.js.map +0 -1
  121. package/dist/src/commands/ask/components/StatusIndicator.js +0 -67
  122. package/dist/src/commands/ask/components/StatusIndicator.js.map +0 -1
  123. package/dist/src/commands/ask-ink.js +0 -380
  124. package/dist/src/commands/ask-ink.js.map +0 -1
  125. package/dist/src/commands/ask.js +0 -991
  126. package/dist/src/commands/ask.js.map +0 -1
  127. package/dist/src/commands/chat/components/Divider.js +0 -7
  128. package/dist/src/commands/chat/components/Divider.js.map +0 -1
  129. package/dist/src/commands/chat/components/SessionInfo.js +0 -11
  130. package/dist/src/commands/chat/components/SessionInfo.js.map +0 -1
  131. package/dist/src/commands/chat.js +0 -82
  132. package/dist/src/commands/chat.js.map +0 -1
  133. package/dist/src/commands/start-test.js +0 -119
  134. package/dist/src/commands/start-test.js.map +0 -1
  135. package/dist/src/commands/stream.js +0 -17
  136. package/dist/src/commands/stream.js.map +0 -1
  137. package/dist/src/lib/legacy-chat-runner.js +0 -37
  138. package/dist/src/lib/legacy-chat-runner.js.map +0 -1
  139. package/dist/src/lib/local-tools/ui/click-element.js +0 -105
  140. package/dist/src/lib/local-tools/ui/click-element.js.map +0 -1
  141. package/dist/src/lib/local-tools/ui/dom-rag.js +0 -201
  142. package/dist/src/lib/local-tools/ui/dom-rag.js.map +0 -1
  143. package/dist/src/lib/local-tools/ui/find-element.js +0 -31
  144. package/dist/src/lib/local-tools/ui/find-element.js.map +0 -1
  145. package/dist/src/lib/local-tools/ui/hover-element.js +0 -94
  146. package/dist/src/lib/local-tools/ui/hover-element.js.map +0 -1
  147. package/dist/src/lib/local-tools/ui/manage-tab.js +0 -65
  148. package/dist/src/lib/local-tools/ui/manage-tab.js.map +0 -1
  149. package/dist/src/lib/local-tools/ui/navigate.js +0 -35
  150. package/dist/src/lib/local-tools/ui/navigate.js.map +0 -1
  151. package/dist/src/lib/local-tools/ui/page-discovery.js +0 -32
  152. package/dist/src/lib/local-tools/ui/page-discovery.js.map +0 -1
  153. package/dist/src/lib/local-tools/ui/screenshot.js +0 -19
  154. package/dist/src/lib/local-tools/ui/screenshot.js.map +0 -1
  155. package/dist/src/lib/local-tools/ui/search-interactive-elements.js +0 -18
  156. package/dist/src/lib/local-tools/ui/search-interactive-elements.js.map +0 -1
  157. package/dist/src/lib/local-tools/ui/selector-resolver.js +0 -153
  158. package/dist/src/lib/local-tools/ui/selector-resolver.js.map +0 -1
  159. package/dist/src/lib/local-tools/ui/type-text.js +0 -40
  160. package/dist/src/lib/local-tools/ui/type-text.js.map +0 -1
  161. package/dist/src/lib/tui/components/AskIntro.js +0 -6
  162. package/dist/src/lib/tui/components/AskIntro.js.map +0 -1
  163. package/dist/src/lib/tui/components/Banner.js +0 -15
  164. package/dist/src/lib/tui/components/Banner.js.map +0 -1
  165. package/dist/src/lib/tui/components/Divider.js +0 -17
  166. package/dist/src/lib/tui/components/Divider.js.map +0 -1
  167. package/dist/src/lib/tui/components/EventLine.js +0 -110
  168. package/dist/src/lib/tui/components/EventLine.js.map +0 -1
  169. package/dist/src/lib/tui/components/Header.js +0 -15
  170. package/dist/src/lib/tui/components/Header.js.map +0 -1
  171. package/dist/src/lib/tui/components/InputBox.js +0 -9
  172. package/dist/src/lib/tui/components/InputBox.js.map +0 -1
  173. package/dist/src/lib/tui/components/Mapping.js +0 -8
  174. package/dist/src/lib/tui/components/Mapping.js.map +0 -1
  175. package/dist/src/lib/tui/components/ProjectList.js +0 -6
  176. package/dist/src/lib/tui/components/ProjectList.js.map +0 -1
  177. package/dist/src/lib/tui/components/Spinner.js +0 -20
  178. package/dist/src/lib/tui/components/Spinner.js.map +0 -1
  179. package/dist/src/lib/tui/components/StatusBanner.js +0 -12
  180. package/dist/src/lib/tui/components/StatusBanner.js.map +0 -1
  181. package/dist/src/lib/tui/components/StatusBar.js +0 -11
  182. package/dist/src/lib/tui/components/StatusBar.js.map +0 -1
  183. package/dist/src/lib/tui/components/UserBubble.js +0 -6
  184. package/dist/src/lib/tui/components/UserBubble.js.map +0 -1
  185. package/dist/src/lib/tui/components/index.js +0 -16
  186. package/dist/src/lib/tui/components/index.js.map +0 -1
  187. package/dist/src/lib/tui/ink-print.js +0 -41
  188. package/dist/src/lib/tui/ink-print.js.map +0 -1
  189. package/dist/src/test-agent-flow.js +0 -148
  190. package/dist/src/test-agent-flow.js.map +0 -1
  191. package/dist/src/test-browser-session.js +0 -152
  192. package/dist/src/test-browser-session.js.map +0 -1
  193. package/dist/src/test-browser-snapshot.js +0 -187
  194. package/dist/src/test-browser-snapshot.js.map +0 -1
  195. package/dist/src/test-snapshot-detailed.js +0 -219
  196. package/dist/src/test-snapshot-detailed.js.map +0 -1
  197. package/dist/src/test-snapshot-simple.js +0 -85
  198. package/dist/src/test-snapshot-simple.js.map +0 -1
  199. package/dist/src/test-snapshot-tabs.js +0 -110
  200. package/dist/src/test-snapshot-tabs.js.map +0 -1
@@ -0,0 +1,310 @@
1
+ /**
2
+ * Context Compactor - Industry-standard conversation history management
3
+ *
4
+ * Features:
5
+ * - Accurate token counting using tiktoken
6
+ * - Conversation turn preservation (keeps user-assistant pairs intact)
7
+ * - LLM-based summarization for old context
8
+ * - Importance scoring to preserve critical messages
9
+ * - Tool result preservation for recent tools
10
+ */
11
+ import { encoding_for_model } from "tiktoken";
12
+ export class ContextCompactor {
13
+ config;
14
+ encoder = null;
15
+ constructor(config) {
16
+ this.config = {
17
+ maxTokens: config?.maxTokens ?? 200000,
18
+ targetTokens: config?.targetTokens ?? 150000,
19
+ preserveRecentTurns: config?.preserveRecentTurns ?? 10,
20
+ preserveRecentTools: config?.preserveRecentTools ?? 5,
21
+ enableSummarization: config?.enableSummarization ?? true,
22
+ model: config?.model ?? "gpt-4",
23
+ };
24
+ }
25
+ /**
26
+ * Get or initialize tokenizer
27
+ */
28
+ getEncoder() {
29
+ if (!this.encoder) {
30
+ try {
31
+ this.encoder = encoding_for_model(this.config.model);
32
+ }
33
+ catch {
34
+ // Fallback to cl100k_base (GPT-4/GPT-3.5-turbo)
35
+ this.encoder = encoding_for_model("gpt-4");
36
+ }
37
+ }
38
+ return this.encoder;
39
+ }
40
+ /**
41
+ * Accurate token counting using tiktoken
42
+ */
43
+ countTokens(messages) {
44
+ const encoder = this.getEncoder();
45
+ let totalTokens = 0;
46
+ for (const msg of messages) {
47
+ // Count role tokens
48
+ totalTokens += 4; // Every message has role overhead
49
+ // Count content tokens
50
+ if (typeof msg.content === "string") {
51
+ totalTokens += encoder.encode(msg.content).length;
52
+ }
53
+ else if (Array.isArray(msg.content)) {
54
+ totalTokens += encoder.encode(JSON.stringify(msg.content)).length;
55
+ }
56
+ // Count tool call tokens
57
+ if (msg.toolCalls) {
58
+ totalTokens += encoder.encode(JSON.stringify(msg.toolCalls)).length;
59
+ }
60
+ // Count metadata tokens
61
+ if (msg.metadata) {
62
+ totalTokens += encoder.encode(JSON.stringify(msg.metadata)).length;
63
+ }
64
+ // Count name/tool_call_id
65
+ if (msg.toolCall) {
66
+ totalTokens += encoder.encode(JSON.stringify(msg.toolCall)).length;
67
+ }
68
+ }
69
+ // Add overhead for message formatting
70
+ totalTokens += 3; // Every reply is primed with assistant
71
+ return totalTokens;
72
+ }
73
+ /**
74
+ * Check if compaction is needed
75
+ */
76
+ needsCompaction(messages) {
77
+ const tokens = this.countTokens(messages);
78
+ return tokens >= this.config.maxTokens;
79
+ }
80
+ /**
81
+ * Group messages into conversation turns
82
+ * A turn = user message + assistant response + any tool calls
83
+ */
84
+ groupIntoTurns(messages) {
85
+ const turns = [];
86
+ let i = 0;
87
+ while (i < messages.length) {
88
+ const msg = messages[i];
89
+ // Skip system messages (they're not part of turns)
90
+ if (msg.role === "system") {
91
+ i++;
92
+ continue;
93
+ }
94
+ // Start of a turn (user message)
95
+ if (msg.role === "user") {
96
+ const turn = {
97
+ userMessage: msg,
98
+ toolMessages: [],
99
+ startIndex: i,
100
+ endIndex: i,
101
+ tokens: 0,
102
+ importance: 0,
103
+ };
104
+ i++;
105
+ // Collect assistant response
106
+ if (i < messages.length && messages[i].role === "assistant") {
107
+ turn.assistantMessage = messages[i];
108
+ turn.endIndex = i;
109
+ i++;
110
+ }
111
+ // Collect tool messages
112
+ while (i < messages.length && messages[i].role === "tool") {
113
+ turn.toolMessages.push(messages[i]);
114
+ turn.endIndex = i;
115
+ i++;
116
+ }
117
+ // Calculate tokens for this turn
118
+ const turnMessages = messages.slice(turn.startIndex, turn.endIndex + 1);
119
+ turn.tokens = this.countTokens(turnMessages);
120
+ // Calculate importance score
121
+ turn.importance = this.calculateImportance(turn);
122
+ turns.push(turn);
123
+ }
124
+ else {
125
+ // Orphaned message (shouldn't happen but handle gracefully)
126
+ i++;
127
+ }
128
+ }
129
+ return turns;
130
+ }
131
+ /**
132
+ * Calculate importance score for a conversation turn
133
+ * Higher score = more important to preserve
134
+ */
135
+ calculateImportance(turn) {
136
+ let score = 1.0; // Base score
137
+ // Boost if contains errors
138
+ const hasError = turn.assistantMessage?.content
139
+ ?.toString()
140
+ .toLowerCase()
141
+ .includes("error") ||
142
+ turn.toolMessages.some((t) => t.content?.toString().toLowerCase().includes("error"));
143
+ if (hasError)
144
+ score += 2.0;
145
+ // Boost if user corrected the agent
146
+ const hasCorrection = turn.userMessage.content
147
+ ?.toString()
148
+ .toLowerCase()
149
+ .match(/no|wrong|incorrect|actually|fix|correct/);
150
+ if (hasCorrection)
151
+ score += 1.5;
152
+ // Boost if contains important tool calls
153
+ const importantTools = ["run_command", "write_file", "delete_file"];
154
+ const hasImportantTool = turn.toolMessages.some((t) => importantTools.includes(t.toolCall?.name || ""));
155
+ if (hasImportantTool)
156
+ score += 1.0;
157
+ // Penalize very long tool results (likely verbose output)
158
+ const hasLongToolResult = turn.toolMessages.some((t) => (t.content?.toString().length || 0) > 5000);
159
+ if (hasLongToolResult)
160
+ score -= 0.5;
161
+ return Math.max(0, score);
162
+ }
163
+ /**
164
+ * Main compaction method
165
+ */
166
+ async compact(messages, httpClient) {
167
+ const tokensBeforeCompaction = this.countTokens(messages);
168
+ if (tokensBeforeCompaction < this.config.maxTokens) {
169
+ return {
170
+ compactedMessages: messages,
171
+ removedCount: 0,
172
+ tokensBeforeCompaction,
173
+ tokensAfterCompaction: tokensBeforeCompaction,
174
+ strategy: "none",
175
+ summaryGenerated: false,
176
+ };
177
+ }
178
+ // Separate system messages from conversation
179
+ const systemMessages = messages.filter((m) => m.role === "system");
180
+ const conversationMessages = messages.filter((m) => m.role !== "system");
181
+ // Group into turns
182
+ const turns = this.groupIntoTurns(conversationMessages);
183
+ // Keep recent turns
184
+ const recentTurns = turns.slice(-this.config.preserveRecentTurns);
185
+ const oldTurns = turns.slice(0, -this.config.preserveRecentTurns);
186
+ // Extract recent messages
187
+ const recentMessages = [];
188
+ for (const turn of recentTurns) {
189
+ recentMessages.push(...conversationMessages.slice(turn.startIndex, turn.endIndex + 1));
190
+ }
191
+ // Preserve recent tool results
192
+ const recentToolMessages = recentMessages.filter((m) => m.role === "tool");
193
+ const toolsToPreserve = recentToolMessages.slice(-this.config.preserveRecentTools);
194
+ let compactedMessages;
195
+ let summaryGenerated = false;
196
+ if (this.config.enableSummarization && oldTurns.length > 0 && httpClient) {
197
+ // Generate LLM summary of old context
198
+ const summary = await this.generateSummary(oldTurns, httpClient);
199
+ summaryGenerated = true;
200
+ compactedMessages = [
201
+ ...systemMessages,
202
+ {
203
+ role: "system",
204
+ content: summary,
205
+ timestamp: Date.now(),
206
+ metadata: {
207
+ type: "conversation_summary",
208
+ turns_summarized: oldTurns.length,
209
+ tokens_before: this.countTokens(conversationMessages.slice(0, oldTurns[oldTurns.length - 1].endIndex + 1)),
210
+ },
211
+ },
212
+ ...recentMessages,
213
+ ];
214
+ }
215
+ else {
216
+ // Fallback: Keep high-importance turns from old context
217
+ const importantOldTurns = oldTurns
218
+ .sort((a, b) => b.importance - a.importance)
219
+ .slice(0, 3); // Keep top 3 important turns
220
+ const importantMessages = [];
221
+ for (const turn of importantOldTurns) {
222
+ importantMessages.push(...conversationMessages.slice(turn.startIndex, turn.endIndex + 1));
223
+ }
224
+ compactedMessages = [
225
+ ...systemMessages,
226
+ {
227
+ role: "system",
228
+ content: `[Earlier conversation: ${oldTurns.length} turns compacted. Preserved ${importantOldTurns.length} important turns.]`,
229
+ timestamp: Date.now(),
230
+ metadata: {
231
+ type: "compaction_marker",
232
+ turns_removed: oldTurns.length - importantOldTurns.length,
233
+ },
234
+ },
235
+ ...importantMessages,
236
+ ...recentMessages,
237
+ ];
238
+ }
239
+ const tokensAfterCompaction = this.countTokens(compactedMessages);
240
+ return {
241
+ compactedMessages,
242
+ removedCount: messages.length - compactedMessages.length,
243
+ tokensBeforeCompaction,
244
+ tokensAfterCompaction,
245
+ strategy: summaryGenerated ? "llm-summarization" : "importance-based",
246
+ summaryGenerated,
247
+ };
248
+ }
249
+ /**
250
+ * Generate LLM summary of old conversation turns
251
+ */
252
+ async generateSummary(turns, httpClient) {
253
+ // Build a concise representation of the turns
254
+ const turnSummaries = turns.map((turn, idx) => {
255
+ const userContent = typeof turn.userMessage.content === "string"
256
+ ? turn.userMessage.content
257
+ : JSON.stringify(turn.userMessage.content);
258
+ const assistantContent = turn.assistantMessage
259
+ ? typeof turn.assistantMessage.content === "string"
260
+ ? turn.assistantMessage.content
261
+ : JSON.stringify(turn.assistantMessage.content)
262
+ : "[No response]";
263
+ const toolsUsed = turn.toolMessages
264
+ .map((t) => t.toolCall?.name)
265
+ .filter(Boolean)
266
+ .join(", ");
267
+ return `Turn ${idx + 1}:\nUser: ${userContent.substring(0, 200)}${userContent.length > 200 ? "..." : ""}\nAssistant: ${assistantContent.substring(0, 200)}${assistantContent.length > 200 ? "..." : ""}${toolsUsed ? `\nTools: ${toolsUsed}` : ""}`;
268
+ });
269
+ const conversationText = turnSummaries.join("\n\n");
270
+ try {
271
+ // Call backend to generate summary
272
+ const response = await httpClient.post("/api/v1/ai/agent/summarize", {
273
+ conversation: conversationText,
274
+ max_tokens: 500,
275
+ });
276
+ return (response.data?.summary ||
277
+ `[Summary of ${turns.length} conversation turns]`);
278
+ }
279
+ catch (error) {
280
+ // Fallback to simple summary if API fails
281
+ const userMessages = turns.length;
282
+ const toolCalls = turns.reduce((sum, t) => sum + t.toolMessages.length, 0);
283
+ return `[Earlier conversation: ${userMessages} user messages, ${toolCalls} tool executions. Context preserved for continuity.]`;
284
+ }
285
+ }
286
+ /**
287
+ * Get compaction statistics
288
+ */
289
+ getStats(messages) {
290
+ const tokens = this.countTokens(messages);
291
+ const turns = this.groupIntoTurns(messages.filter((m) => m.role !== "system"));
292
+ return {
293
+ totalMessages: messages.length,
294
+ tokens,
295
+ needsCompaction: tokens >= this.config.maxTokens,
296
+ utilizationPercent: (tokens / this.config.maxTokens) * 100,
297
+ conversationTurns: turns.length,
298
+ };
299
+ }
300
+ /**
301
+ * Clean up tokenizer
302
+ */
303
+ dispose() {
304
+ if (this.encoder) {
305
+ this.encoder.free();
306
+ this.encoder = null;
307
+ }
308
+ }
309
+ }
310
+ //# sourceMappingURL=context-compactor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-compactor.js","sourceRoot":"","sources":["../../../src/lib/context-compactor.ts"],"names":[],"mappings":"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"}
@@ -36,6 +36,14 @@ export function createAgentHttpClient(options) {
36
36
  const response = await instance.post("/api/v1/ai/agent/reason", payload, { signal });
37
37
  return response.data;
38
38
  },
39
+ async getAvailableModels() {
40
+ const response = await instance.get("/api/v1/ai/models");
41
+ return response.data;
42
+ },
43
+ async setPreferredModel(modelId) {
44
+ const response = await instance.put("/api/v1/ai/preferred-model", { model_id: modelId });
45
+ return response.data;
46
+ },
39
47
  async startTest(payload, params) {
40
48
  const response = await instance.post("/api/v1/start-test", payload, { params });
41
49
  return response.data;
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/lib/http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAsB,MAAM,OAAO,CAAC;AAC3C,OAAO,EAAC,YAAY,EAAE,aAAa,EAAC,MAAM,aAAa,CAAC;AAGxD,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,YAAY,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,EAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAC,CAAC,CAAC;IAClE,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAC3C,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;YACtC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,KAAK,EAAE,CAAC;QACtD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC;AAClB,CAAC;AAwDD,MAAM,UAAU,qBAAqB,CAAC,OAAyB;IAC7D,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC;QAC5B,OAAO;QACP,OAAO,EAAE,OAAO,CAAC,SAAS,IAAI,MAAM;KACrC,CAAC,CAAC;IAEH,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,EAAE,CAAC;QAC9C,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;YACtC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,KAAK,EAAE,CAAC;QACtD,CAAC;QACD,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;YACpC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;QACtD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,KAAK,CAAC,eAAe,CACnB,OAA2B,EAC3B,MAAoB;YAEpB,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,IAAI,CAClC,yBAAyB,EACzB,OAAO,EACP,EAAC,MAAM,EAAC,CACT,CAAC;YACF,OAAO,QAAQ,CAAC,IAAI,CAAC;QACvB,CAAC;QAID,KAAK,CAAC,SAAS,CACb,OAAyB,EACzB,MAA2D;YAE3D,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,IAAI,CAClC,oBAAoB,EACpB,OAAO,EACP,EAAC,MAAM,EAAC,CACT,CAAC;YACF,OAAO,QAAQ,CAAC,IAAI,CAAC;QACvB,CAAC;QAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,MAAY;YACjC,OAAO,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACnC,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/lib/http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Unit tests for grep_search tool.
3
+ * Tests text search, regex search, case sensitivity, and context lines.
4
+ */
5
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
6
+ import * as fs from "fs/promises";
7
+ import * as path from "path";
8
+ import * as os from "os";
9
+ import { grepSearch } from "../grep-search.js";
10
+ describe("grepSearch", () => {
11
+ let tempDir;
12
+ let context;
13
+ beforeEach(async () => {
14
+ tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "grep-search-test-"));
15
+ context = { workingDirectory: tempDir };
16
+ });
17
+ afterEach(async () => {
18
+ await fs.rm(tempDir, { recursive: true, force: true });
19
+ });
20
+ describe("text search", () => {
21
+ it("should find text matches in files", async () => {
22
+ await fs.writeFile(path.join(tempDir, "test.txt"), "hello world\nfoo bar\nhello again");
23
+ const result = await grepSearch({ query: "hello" }, context);
24
+ expect(result.success).toBe(true);
25
+ expect(result.total_matches).toBe(2);
26
+ expect(result.matches[0].content).toContain("hello");
27
+ });
28
+ it("should return file path and line number", async () => {
29
+ await fs.writeFile(path.join(tempDir, "test.txt"), "line1\nmatch here\nline3");
30
+ const result = await grepSearch({ query: "match" }, context);
31
+ expect(result.success).toBe(true);
32
+ expect(result.matches[0].file).toBe("test.txt");
33
+ expect(result.matches[0].line).toBe(2);
34
+ });
35
+ it("should return column position", async () => {
36
+ await fs.writeFile(path.join(tempDir, "test.txt"), "prefix match suffix");
37
+ const result = await grepSearch({ query: "match" }, context);
38
+ expect(result.success).toBe(true);
39
+ expect(result.matches[0].column).toBe(8); // 1-indexed
40
+ });
41
+ it("should return error for empty query", async () => {
42
+ const result = await grepSearch({ query: "" }, context);
43
+ expect(result.success).toBe(false);
44
+ expect(result.error).toBe("Search query cannot be empty");
45
+ });
46
+ it("should search multiple files", async () => {
47
+ await fs.writeFile(path.join(tempDir, "file1.txt"), "match here");
48
+ await fs.writeFile(path.join(tempDir, "file2.txt"), "match there");
49
+ const result = await grepSearch({ query: "match" }, context);
50
+ expect(result.success).toBe(true);
51
+ expect(result.total_matches).toBe(2);
52
+ expect(result.files_searched).toBeGreaterThanOrEqual(2);
53
+ });
54
+ });
55
+ describe("regex search", () => {
56
+ it("should support regex patterns when is_regex is true", async () => {
57
+ await fs.writeFile(path.join(tempDir, "test.txt"), "test123\ntest456\nother");
58
+ const result = await grepSearch({ query: "test\\d+", is_regex: true }, context);
59
+ expect(result.success).toBe(true);
60
+ expect(result.total_matches).toBe(2);
61
+ });
62
+ it("should return error for invalid regex", async () => {
63
+ const result = await grepSearch({ query: "[invalid", is_regex: true }, context);
64
+ expect(result.success).toBe(false);
65
+ expect(result.error).toBe("Invalid regex pattern");
66
+ });
67
+ it("should escape special characters in non-regex mode", async () => {
68
+ await fs.writeFile(path.join(tempDir, "test.txt"), "test.file\ntest-file");
69
+ const result = await grepSearch({ query: "test.file", is_regex: false }, context);
70
+ expect(result.success).toBe(true);
71
+ expect(result.total_matches).toBe(1);
72
+ });
73
+ });
74
+ describe("case sensitivity", () => {
75
+ it("should be case-insensitive by default", async () => {
76
+ await fs.writeFile(path.join(tempDir, "test.txt"), "Hello\nHELLO\nhello");
77
+ const result = await grepSearch({ query: "hello" }, context);
78
+ expect(result.success).toBe(true);
79
+ expect(result.total_matches).toBe(3);
80
+ });
81
+ it("should be case-sensitive when case_sensitive is true", async () => {
82
+ await fs.writeFile(path.join(tempDir, "test.txt"), "Hello\nHELLO\nhello");
83
+ const result = await grepSearch({ query: "hello", case_sensitive: true }, context);
84
+ expect(result.success).toBe(true);
85
+ expect(result.total_matches).toBe(1);
86
+ });
87
+ });
88
+ describe("context lines", () => {
89
+ it("should include context lines when specified", async () => {
90
+ const content = "line1\nline2\nmatch\nline4\nline5";
91
+ await fs.writeFile(path.join(tempDir, "test.txt"), content);
92
+ const result = await grepSearch({ query: "match", context_lines: 1 }, context);
93
+ expect(result.success).toBe(true);
94
+ expect(result.matches[0].context_before).toEqual(["line2"]);
95
+ expect(result.matches[0].context_after).toEqual(["line4"]);
96
+ });
97
+ it("should handle context at file boundaries", async () => {
98
+ await fs.writeFile(path.join(tempDir, "test.txt"), "match\nline2");
99
+ const result = await grepSearch({ query: "match", context_lines: 2 }, context);
100
+ expect(result.success).toBe(true);
101
+ expect(result.matches[0].context_before).toBeUndefined();
102
+ expect(result.matches[0].context_after).toEqual(["line2"]);
103
+ });
104
+ });
105
+ describe("file pattern filtering", () => {
106
+ it("should filter by file pattern", async () => {
107
+ await fs.writeFile(path.join(tempDir, "test.ts"), "match");
108
+ await fs.writeFile(path.join(tempDir, "test.js"), "match");
109
+ const result = await grepSearch({ query: "match", pattern: "*.ts" }, context);
110
+ expect(result.success).toBe(true);
111
+ expect(result.total_matches).toBe(1);
112
+ expect(result.matches[0].file).toBe("test.ts");
113
+ });
114
+ });
115
+ describe("max_results limit", () => {
116
+ it("should limit results to max_results", async () => {
117
+ let content = "";
118
+ for (let i = 0; i < 20; i++) {
119
+ content += `match line ${i}\n`;
120
+ }
121
+ await fs.writeFile(path.join(tempDir, "test.txt"), content);
122
+ const result = await grepSearch({ query: "match", max_results: 5 }, context);
123
+ expect(result.success).toBe(true);
124
+ expect(result.total_matches).toBe(5);
125
+ expect(result.truncated).toBe(true);
126
+ });
127
+ });
128
+ describe("path validation (security)", () => {
129
+ it("should prevent directory traversal", async () => {
130
+ const result = await grepSearch({ query: "test", path: "../../../" }, context);
131
+ expect(result.success).toBe(false);
132
+ expect(result.error).toBe("Path validation failed: access denied");
133
+ });
134
+ });
135
+ describe("single file search", () => {
136
+ it("should search a single file when path is a file", async () => {
137
+ await fs.writeFile(path.join(tempDir, "target.txt"), "match here");
138
+ await fs.writeFile(path.join(tempDir, "other.txt"), "match there");
139
+ const result = await grepSearch({ query: "match", path: "target.txt" }, context);
140
+ expect(result.success).toBe(true);
141
+ expect(result.total_matches).toBe(1);
142
+ expect(result.files_searched).toBe(1);
143
+ });
144
+ });
145
+ });
146
+ //# sourceMappingURL=grep-search.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grep-search.test.js","sourceRoot":"","sources":["../../../../../../src/lib/local-tools/code/__tests__/grep-search.test.ts"],"names":[],"mappings":"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"}