@timetotest/cli 0.1.11 → 0.2.1

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 (185) hide show
  1. package/README.md +201 -190
  2. package/dist/bin/ttt.js +4 -2
  3. package/dist/bin/ttt.js.map +1 -1
  4. package/dist/package.json +13 -2
  5. package/dist/src/commands/ask/AskApp.js +121 -0
  6. package/dist/src/commands/ask/AskApp.js.map +1 -0
  7. package/dist/src/commands/ask/components/AssistantResponse.js +31 -0
  8. package/dist/src/commands/ask/components/AssistantResponse.js.map +1 -0
  9. package/dist/src/commands/ask/components/Banner.js +15 -0
  10. package/dist/src/commands/ask/components/Banner.js.map +1 -0
  11. package/dist/src/commands/ask/components/ChatInput.js +93 -0
  12. package/dist/src/commands/ask/components/ChatInput.js.map +1 -0
  13. package/dist/src/commands/ask/components/Divider.js +17 -0
  14. package/dist/src/commands/ask/components/Divider.js.map +1 -0
  15. package/dist/src/commands/ask/components/IntroTips.js +19 -0
  16. package/dist/src/commands/ask/components/IntroTips.js.map +1 -0
  17. package/dist/src/commands/ask/components/MessageBubble.js +47 -0
  18. package/dist/src/commands/ask/components/MessageBubble.js.map +1 -0
  19. package/dist/src/commands/ask/components/SessionInfo.js +20 -0
  20. package/dist/src/commands/ask/components/SessionInfo.js.map +1 -0
  21. package/dist/src/commands/ask/components/StatusIndicator.js +67 -0
  22. package/dist/src/commands/ask/components/StatusIndicator.js.map +1 -0
  23. package/dist/src/commands/ask-ink.js +380 -0
  24. package/dist/src/commands/ask-ink.js.map +1 -0
  25. package/dist/src/commands/ask.js +73 -60
  26. package/dist/src/commands/ask.js.map +1 -1
  27. package/dist/src/commands/chat/ChatApp.js +125 -0
  28. package/dist/src/commands/chat/ChatApp.js.map +1 -0
  29. package/dist/src/commands/chat-ink.js +436 -0
  30. package/dist/src/commands/chat-ink.js.map +1 -0
  31. package/dist/src/commands/chat.js +82 -0
  32. package/dist/src/commands/chat.js.map +1 -0
  33. package/dist/src/commands/login.js +6 -4
  34. package/dist/src/commands/login.js.map +1 -1
  35. package/dist/src/commands/start-test.js +62 -88
  36. package/dist/src/commands/start-test.js.map +1 -1
  37. package/dist/src/commands/stream.js +9 -9
  38. package/dist/src/commands/stream.js.map +1 -1
  39. package/dist/src/commands/test.js +58 -125
  40. package/dist/src/commands/test.js.map +1 -1
  41. package/dist/src/lib/agent-orchestrator.js +546 -0
  42. package/dist/src/lib/agent-orchestrator.js.map +1 -0
  43. package/dist/src/lib/cloudinary-service.js +65 -0
  44. package/dist/src/lib/cloudinary-service.js.map +1 -0
  45. package/dist/src/lib/events.js +73 -60
  46. package/dist/src/lib/events.js.map +1 -1
  47. package/dist/src/lib/http.js +34 -1
  48. package/dist/src/lib/http.js.map +1 -1
  49. package/dist/src/lib/legacy-chat-runner.js +37 -0
  50. package/dist/src/lib/legacy-chat-runner.js.map +1 -0
  51. package/dist/src/lib/local-tools/api/api-discovery.js +17 -0
  52. package/dist/src/lib/local-tools/api/api-discovery.js.map +1 -0
  53. package/dist/src/lib/local-tools/api/build-request.js +20 -0
  54. package/dist/src/lib/local-tools/api/build-request.js.map +1 -0
  55. package/dist/src/lib/local-tools/api/extract-response-fields.js +26 -0
  56. package/dist/src/lib/local-tools/api/extract-response-fields.js.map +1 -0
  57. package/dist/src/lib/local-tools/api/generate-api-test.js +20 -0
  58. package/dist/src/lib/local-tools/api/generate-api-test.js.map +1 -0
  59. package/dist/src/lib/local-tools/api/generate-curl.js +8 -0
  60. package/dist/src/lib/local-tools/api/generate-curl.js.map +1 -0
  61. package/dist/src/lib/local-tools/api/get-api-parameters.js +17 -0
  62. package/dist/src/lib/local-tools/api/get-api-parameters.js.map +1 -0
  63. package/dist/src/lib/local-tools/api/index.js +10 -0
  64. package/dist/src/lib/local-tools/api/index.js.map +1 -0
  65. package/dist/src/lib/local-tools/api/request.js +43 -0
  66. package/dist/src/lib/local-tools/api/request.js.map +1 -0
  67. package/dist/src/lib/local-tools/api/set-auth-header.js +8 -0
  68. package/dist/src/lib/local-tools/api/set-auth-header.js.map +1 -0
  69. package/dist/src/lib/local-tools/api/types.js +2 -0
  70. package/dist/src/lib/local-tools/api/types.js.map +1 -0
  71. package/dist/src/lib/local-tools/api/utils.js +33 -0
  72. package/dist/src/lib/local-tools/api/utils.js.map +1 -0
  73. package/dist/src/lib/local-tools/api/validate-response.js +41 -0
  74. package/dist/src/lib/local-tools/api/validate-response.js.map +1 -0
  75. package/dist/src/lib/local-tools/file-tools.js +45 -0
  76. package/dist/src/lib/local-tools/file-tools.js.map +1 -0
  77. package/dist/src/lib/local-tools/general/discover-local-services.js +95 -0
  78. package/dist/src/lib/local-tools/general/discover-local-services.js.map +1 -0
  79. package/dist/src/lib/local-tools/general/index.js +2 -0
  80. package/dist/src/lib/local-tools/general/index.js.map +1 -0
  81. package/dist/src/lib/local-tools/ui/click-element.js +105 -0
  82. package/dist/src/lib/local-tools/ui/click-element.js.map +1 -0
  83. package/dist/src/lib/local-tools/ui/dom-rag.js +201 -0
  84. package/dist/src/lib/local-tools/ui/dom-rag.js.map +1 -0
  85. package/dist/src/lib/local-tools/ui/find-element.js +31 -0
  86. package/dist/src/lib/local-tools/ui/find-element.js.map +1 -0
  87. package/dist/src/lib/local-tools/ui/hover-element.js +94 -0
  88. package/dist/src/lib/local-tools/ui/hover-element.js.map +1 -0
  89. package/dist/src/lib/local-tools/ui/index.js +3 -0
  90. package/dist/src/lib/local-tools/ui/index.js.map +1 -0
  91. package/dist/src/lib/local-tools/ui/manage-tab.js +65 -0
  92. package/dist/src/lib/local-tools/ui/manage-tab.js.map +1 -0
  93. package/dist/src/lib/local-tools/ui/navigate.js +35 -0
  94. package/dist/src/lib/local-tools/ui/navigate.js.map +1 -0
  95. package/dist/src/lib/local-tools/ui/page-discovery.js +32 -0
  96. package/dist/src/lib/local-tools/ui/page-discovery.js.map +1 -0
  97. package/dist/src/lib/local-tools/ui/playwright-mcp.js +217 -0
  98. package/dist/src/lib/local-tools/ui/playwright-mcp.js.map +1 -0
  99. package/dist/src/lib/local-tools/ui/screenshot.js +19 -0
  100. package/dist/src/lib/local-tools/ui/screenshot.js.map +1 -0
  101. package/dist/src/lib/local-tools/ui/search-interactive-elements.js +18 -0
  102. package/dist/src/lib/local-tools/ui/search-interactive-elements.js.map +1 -0
  103. package/dist/src/lib/local-tools/ui/selector-resolver.js +153 -0
  104. package/dist/src/lib/local-tools/ui/selector-resolver.js.map +1 -0
  105. package/dist/src/lib/local-tools/ui/snapshot-query.js +129 -0
  106. package/dist/src/lib/local-tools/ui/snapshot-query.js.map +1 -0
  107. package/dist/src/lib/local-tools/ui/type-text.js +40 -0
  108. package/dist/src/lib/local-tools/ui/type-text.js.map +1 -0
  109. package/dist/src/lib/local-tools/ui/types.js +2 -0
  110. package/dist/src/lib/local-tools/ui/types.js.map +1 -0
  111. package/dist/src/lib/local-tools/utility/finish-overall-test.js +12 -0
  112. package/dist/src/lib/local-tools/utility/finish-overall-test.js.map +1 -0
  113. package/dist/src/lib/local-tools/utility/index.js +2 -0
  114. package/dist/src/lib/local-tools/utility/index.js.map +1 -0
  115. package/dist/src/lib/prompts/builder.js +38 -0
  116. package/dist/src/lib/prompts/builder.js.map +1 -0
  117. package/dist/src/lib/prompts/index.js +7 -0
  118. package/dist/src/lib/prompts/index.js.map +1 -0
  119. package/dist/src/lib/prompts/templates.js +166 -0
  120. package/dist/src/lib/prompts/templates.js.map +1 -0
  121. package/dist/src/lib/session-manager.js +201 -0
  122. package/dist/src/lib/session-manager.js.map +1 -0
  123. package/dist/src/lib/socket.js +70 -9
  124. package/dist/src/lib/socket.js.map +1 -1
  125. package/dist/src/lib/testing-mode.js +33 -0
  126. package/dist/src/lib/testing-mode.js.map +1 -0
  127. package/dist/src/lib/tool-descriptions.js +59 -0
  128. package/dist/src/lib/tool-descriptions.js.map +1 -0
  129. package/dist/src/lib/tool-executor.js +537 -0
  130. package/dist/src/lib/tool-executor.js.map +1 -0
  131. package/dist/src/lib/tool-registry.js +803 -0
  132. package/dist/src/lib/tool-registry.js.map +1 -0
  133. package/dist/src/lib/tool-result-pruner.js +384 -0
  134. package/dist/src/lib/tool-result-pruner.js.map +1 -0
  135. package/dist/src/lib/tui/components/AskIntro.js +6 -0
  136. package/dist/src/lib/tui/components/AskIntro.js.map +1 -0
  137. package/dist/src/lib/tui/components/Banner.js +15 -0
  138. package/dist/src/lib/tui/components/Banner.js.map +1 -0
  139. package/dist/src/lib/tui/components/Divider.js +17 -0
  140. package/dist/src/lib/tui/components/Divider.js.map +1 -0
  141. package/dist/src/lib/tui/components/EventLine.js +110 -0
  142. package/dist/src/lib/tui/components/EventLine.js.map +1 -0
  143. package/dist/src/lib/tui/components/Header.js +15 -0
  144. package/dist/src/lib/tui/components/Header.js.map +1 -0
  145. package/dist/src/lib/tui/components/InputBox.js +9 -0
  146. package/dist/src/lib/tui/components/InputBox.js.map +1 -0
  147. package/dist/src/lib/tui/components/Mapping.js +8 -0
  148. package/dist/src/lib/tui/components/Mapping.js.map +1 -0
  149. package/dist/src/lib/tui/components/ProjectList.js +6 -0
  150. package/dist/src/lib/tui/components/ProjectList.js.map +1 -0
  151. package/dist/src/lib/tui/components/Spinner.js +20 -0
  152. package/dist/src/lib/tui/components/Spinner.js.map +1 -0
  153. package/dist/src/lib/tui/components/StatusBanner.js +12 -0
  154. package/dist/src/lib/tui/components/StatusBanner.js.map +1 -0
  155. package/dist/src/lib/tui/components/StatusBar.js +11 -0
  156. package/dist/src/lib/tui/components/StatusBar.js.map +1 -0
  157. package/dist/src/lib/tui/components/UserBubble.js +6 -0
  158. package/dist/src/lib/tui/components/UserBubble.js.map +1 -0
  159. package/dist/src/lib/tui/components/index.js +16 -0
  160. package/dist/src/lib/tui/components/index.js.map +1 -0
  161. package/dist/src/lib/tui/events.js +716 -76
  162. package/dist/src/lib/tui/events.js.map +1 -1
  163. package/dist/src/lib/tui/icons.js +14 -0
  164. package/dist/src/lib/tui/icons.js.map +1 -1
  165. package/dist/src/lib/tui/ink-print.js +41 -0
  166. package/dist/src/lib/tui/ink-print.js.map +1 -0
  167. package/dist/src/lib/tui/interactive-chat.js +345 -0
  168. package/dist/src/lib/tui/interactive-chat.js.map +1 -0
  169. package/dist/src/lib/tui/print.js +31 -26
  170. package/dist/src/lib/tui/print.js.map +1 -1
  171. package/dist/src/lib/tui/prompt.js +21 -18
  172. package/dist/src/lib/tui/prompt.js.map +1 -1
  173. package/dist/src/test-agent-flow.js +148 -0
  174. package/dist/src/test-agent-flow.js.map +1 -0
  175. package/dist/src/test-browser-session.js +152 -0
  176. package/dist/src/test-browser-session.js.map +1 -0
  177. package/dist/src/test-browser-snapshot.js +187 -0
  178. package/dist/src/test-browser-snapshot.js.map +1 -0
  179. package/dist/src/test-snapshot-detailed.js +219 -0
  180. package/dist/src/test-snapshot-detailed.js.map +1 -0
  181. package/dist/src/test-snapshot-simple.js +85 -0
  182. package/dist/src/test-snapshot-simple.js.map +1 -0
  183. package/dist/src/test-snapshot-tabs.js +110 -0
  184. package/dist/src/test-snapshot-tabs.js.map +1 -0
  185. package/package.json +13 -2
@@ -0,0 +1,546 @@
1
+ /**
2
+ * Agent Orchestrator - Main chat loop and backend integration
3
+ * Manages conversation, tool calling, and execution
4
+ */
5
+ import { EventEmitter } from "events";
6
+ import { SessionManager } from "./session-manager.js";
7
+ import { ToolExecutor } from "./tool-executor.js";
8
+ import { getToolSchemasByDomain } from "./tool-registry.js";
9
+ import { isTestingMode } from "./testing-mode.js";
10
+ import { toolResultPruner } from "./tool-result-pruner.js";
11
+ import { createAgentHttpClient, } from "./http.js";
12
+ import { build_cli_system_prompt } from "./prompts/builder.js";
13
+ export class AgentOrchestrator extends EventEmitter {
14
+ sessionManager;
15
+ toolExecutor;
16
+ config;
17
+ conversationId;
18
+ httpClient;
19
+ remoteConversationId = null;
20
+ remoteProjectId;
21
+ isCancelled = false;
22
+ constructor(config, sessionId) {
23
+ super(); // Initialize EventEmitter
24
+ this.config = config;
25
+ this.sessionManager = new SessionManager(sessionId);
26
+ this.conversationId = this.sessionManager.getSessionId();
27
+ this.httpClient = createAgentHttpClient({
28
+ baseUrl: config.apiUrl,
29
+ token: config.token,
30
+ });
31
+ // Initialize execution context
32
+ const executionContext = {
33
+ sessionManager: this.sessionManager,
34
+ testingMode: config.testingMode,
35
+ apiContext: {},
36
+ browserContext: {},
37
+ };
38
+ this.toolExecutor = new ToolExecutor(executionContext);
39
+ // Update session config
40
+ this.sessionManager.updateConfig({
41
+ mode: config.mode,
42
+ testingMode: config.testingMode,
43
+ baseUrl: config.baseUrl,
44
+ apiBaseUrl: config.apiBaseUrl,
45
+ });
46
+ }
47
+ async chat(userMessage) {
48
+ this.isCancelled = false; // Reset cancellation flag
49
+ // Add user message to history
50
+ this.sessionManager.addMessage({
51
+ role: "user",
52
+ content: userMessage,
53
+ });
54
+ const messages = this.sessionManager.getMessages();
55
+ const toolSchemas = this.getAvailableToolSchemas();
56
+ try {
57
+ if (this.config.mode === "local") {
58
+ return await this.handleLocalMode(messages, toolSchemas);
59
+ }
60
+ else {
61
+ return await this.handleRemoteMode(userMessage);
62
+ }
63
+ }
64
+ catch (error) {
65
+ return `Error: ${error.message}`;
66
+ }
67
+ }
68
+ cancel() {
69
+ this.isCancelled = true;
70
+ this.emit("agent_cancelled", {
71
+ message: "Agent execution cancelled",
72
+ data: { cancelled: true },
73
+ });
74
+ }
75
+ async refreshHttpClient() {
76
+ // Refresh HTTP client with current token from config file
77
+ const { getAuthToken } = await import("./config.js");
78
+ const currentToken = getAuthToken();
79
+ if (currentToken) {
80
+ this.config.token = currentToken; // Update instance config
81
+ }
82
+ this.httpClient = createAgentHttpClient({
83
+ baseUrl: this.config.apiUrl,
84
+ token: this.config.token,
85
+ });
86
+ }
87
+ async handleLocalMode(messages, toolSchemas) {
88
+ // Build system prompt with context
89
+ const systemPrompt = build_cli_system_prompt("unified_agent_react", {
90
+ user_goal: "Help the user with testing and automation tasks",
91
+ base_url: this.config.baseUrl,
92
+ api_base_url: this.config.apiBaseUrl,
93
+ test_type: this.config.testingMode,
94
+ mode: "local",
95
+ });
96
+ // Format messages and prepend system prompt
97
+ const formattedMessages = this.formatMessages(messages);
98
+ const messagesWithSystem = [
99
+ {
100
+ role: "system",
101
+ content: systemPrompt,
102
+ },
103
+ ...formattedMessages,
104
+ ];
105
+ // Add latest screenshot to context if available
106
+ const messagesWithScreenshot = this.addLatestScreenshotToContext(messagesWithSystem);
107
+ const payload = {
108
+ messages: messagesWithScreenshot,
109
+ tools: toolSchemas,
110
+ tool_choice: "auto",
111
+ context: {
112
+ test_id: this.conversationId,
113
+ mode: "local",
114
+ },
115
+ mode: "local",
116
+ };
117
+ // Check for cancellation before HTTP request
118
+ if (this.isCancelled) {
119
+ return "Agent execution cancelled";
120
+ }
121
+ let result;
122
+ try {
123
+ result = await this.httpClient.postAgentReason(payload);
124
+ }
125
+ catch (error) {
126
+ // Handle 401 errors by refreshing the HTTP client and retrying once
127
+ if (error?.response?.status === 401) {
128
+ await this.refreshHttpClient();
129
+ result = await this.httpClient.postAgentReason(payload);
130
+ }
131
+ else {
132
+ throw error;
133
+ }
134
+ }
135
+ // Check for cancellation after HTTP request
136
+ if (this.isCancelled) {
137
+ return "Agent execution cancelled";
138
+ }
139
+ const toolCall = this.extractToolCall(result);
140
+ if (toolCall) {
141
+ // Extract and emit assistant reasoning text first
142
+ const assistantReasoning = this.extractAssistantText(result);
143
+ if (assistantReasoning) {
144
+ this.emit("assistant_reasoning", {
145
+ message: assistantReasoning,
146
+ data: {
147
+ reasoning: assistantReasoning,
148
+ },
149
+ });
150
+ this.sessionManager.addMessage({
151
+ role: "assistant",
152
+ content: assistantReasoning,
153
+ });
154
+ }
155
+ // Parse arguments for both event emission and tool execution
156
+ const parsedArguments = typeof toolCall.arguments === "string"
157
+ ? JSON.parse(toolCall.arguments)
158
+ : toolCall.arguments;
159
+ // Emit tool start event
160
+ this.emit("tool_start", {
161
+ tool: toolCall.name,
162
+ message: `Running ${toolCall.name}...`,
163
+ data: {
164
+ tool: toolCall.name,
165
+ arguments: parsedArguments,
166
+ },
167
+ });
168
+ // Check for cancellation before tool execution
169
+ if (this.isCancelled) {
170
+ return "Agent execution cancelled";
171
+ }
172
+ const toolResult = await this.toolExecutor.execute({
173
+ name: toolCall.name,
174
+ arguments: parsedArguments,
175
+ });
176
+ const pendingScreenshot = this.toolExecutor.consumePendingScreenshot();
177
+ // Check for cancellation after tool execution
178
+ if (this.isCancelled) {
179
+ return "Agent execution cancelled";
180
+ }
181
+ // Emit tool result event
182
+ this.emit("tool_result", {
183
+ tool: toolCall.name,
184
+ message: `Completed ${toolCall.name}`,
185
+ data: {
186
+ tool: toolCall.name,
187
+ result: toolResult,
188
+ success: toolResult?.success !== false,
189
+ },
190
+ });
191
+ if (toolCall.name === "set_testing_mode" &&
192
+ toolResult?.success &&
193
+ isTestingMode(toolResult.mode)) {
194
+ this.config.testingMode = toolResult.mode;
195
+ }
196
+ // Handle finish tool - stop the agent loop
197
+ if (toolCall.name === "finish" && toolResult?.finished) {
198
+ this.sessionManager.addMessage({
199
+ role: "tool",
200
+ content: JSON.stringify(toolResult),
201
+ toolCall: {
202
+ id: toolCall.id || `${Date.now()}`,
203
+ name: toolCall.name,
204
+ arguments: toolCall.arguments,
205
+ },
206
+ });
207
+ return toolResult.summary || toolResult.message || "Task completed";
208
+ }
209
+ this.sessionManager.addMessage({
210
+ role: "tool",
211
+ content: JSON.stringify(toolResult),
212
+ toolCall: {
213
+ id: toolCall.id || `${Date.now()}`,
214
+ name: toolCall.name,
215
+ arguments: toolCall.arguments,
216
+ },
217
+ });
218
+ if (pendingScreenshot) {
219
+ const screenshotMessageId = this.handleScreenshotInHistory(pendingScreenshot.data, pendingScreenshot.action);
220
+ if (toolCall.name === "browser_take_screenshot" && screenshotMessageId) {
221
+ this.sessionManager.addMessage({
222
+ role: "tool",
223
+ content: JSON.stringify({
224
+ success: true,
225
+ screenshot_message_id: screenshotMessageId,
226
+ }),
227
+ toolCall: {
228
+ id: `${toolCall.id || Date.now()}-link`,
229
+ name: toolCall.name,
230
+ arguments: { linked_message_id: screenshotMessageId },
231
+ },
232
+ });
233
+ }
234
+ }
235
+ // Prune tool results to optimize conversation history
236
+ this.pruneToolResults(toolCall.name);
237
+ // Check for cancellation before continuing
238
+ if (this.isCancelled) {
239
+ return "Agent execution cancelled";
240
+ }
241
+ return this.handleLocalMode(this.sessionManager.getMessages(), this.getAvailableToolSchemas());
242
+ }
243
+ const assistantMessage = this.extractAssistantText(result);
244
+ this.sessionManager.addMessage({
245
+ role: "assistant",
246
+ content: assistantMessage,
247
+ });
248
+ return assistantMessage;
249
+ }
250
+ async handleRemoteMode(userMessage) {
251
+ const conversationId = this.remoteConversationId || this.sessionManager.getSessionId();
252
+ // Check for cancellation before starting remote mode
253
+ if (this.isCancelled) {
254
+ return "Agent execution cancelled";
255
+ }
256
+ try {
257
+ let result;
258
+ try {
259
+ result = await this.httpClient.postAskMessage(conversationId, {
260
+ message: userMessage,
261
+ project_id: this.remoteProjectId,
262
+ surface: "cli",
263
+ });
264
+ }
265
+ catch (error) {
266
+ // Handle 401 errors by refreshing the HTTP client and retrying once
267
+ if (error?.response?.status === 401) {
268
+ await this.refreshHttpClient();
269
+ result = await this.httpClient.postAskMessage(conversationId, {
270
+ message: userMessage,
271
+ project_id: this.remoteProjectId,
272
+ surface: "cli",
273
+ });
274
+ }
275
+ else {
276
+ throw error;
277
+ }
278
+ }
279
+ // Check for cancellation after HTTP request
280
+ if (this.isCancelled) {
281
+ return "Agent execution cancelled";
282
+ }
283
+ this.remoteConversationId = conversationId;
284
+ const assistantReply = result.response || result.message || "";
285
+ this.sessionManager.addMessage({
286
+ role: "assistant",
287
+ content: assistantReply,
288
+ });
289
+ return assistantReply;
290
+ }
291
+ catch (error) {
292
+ // Check for cancellation before creating session
293
+ if (this.isCancelled) {
294
+ return "Agent execution cancelled";
295
+ }
296
+ if (!this.remoteConversationId) {
297
+ try {
298
+ const session = await this.httpClient.createAskSession({
299
+ question: userMessage,
300
+ surface: "cli",
301
+ });
302
+ this.remoteConversationId = session.conversation_id;
303
+ this.remoteProjectId = session.project_id;
304
+ return this.handleRemoteMode(userMessage);
305
+ }
306
+ catch (sessionError) {
307
+ // Handle 401 errors by refreshing the HTTP client and retrying once
308
+ if (sessionError?.response?.status === 401) {
309
+ await this.refreshHttpClient();
310
+ const session = await this.httpClient.createAskSession({
311
+ question: userMessage,
312
+ surface: "cli",
313
+ });
314
+ this.remoteConversationId = session.conversation_id;
315
+ this.remoteProjectId = session.project_id;
316
+ return this.handleRemoteMode(userMessage);
317
+ }
318
+ else {
319
+ throw sessionError;
320
+ }
321
+ }
322
+ }
323
+ throw error;
324
+ }
325
+ }
326
+ getAvailableToolSchemas() {
327
+ const testingMode = this.config.testingMode;
328
+ const schemas = getToolSchemasByDomain(testingMode);
329
+ return Object.values(schemas).map((schema) => ({
330
+ type: "function",
331
+ function: schema,
332
+ }));
333
+ }
334
+ formatMessages(messages) {
335
+ return messages
336
+ .filter((msg) => msg.metadata?.type !== "screenshot")
337
+ .map((msg) => {
338
+ const base = {
339
+ role: msg.role,
340
+ content: typeof msg.content === "string"
341
+ ? msg.content
342
+ : JSON.stringify(msg.content),
343
+ };
344
+ if (msg.role === "tool" && msg.toolCall) {
345
+ base.name = msg.toolCall.name;
346
+ base.tool_call_id = msg.toolCall.id;
347
+ }
348
+ return base;
349
+ });
350
+ }
351
+ getMode() {
352
+ return this.config.mode;
353
+ }
354
+ getTestingMode() {
355
+ return this.config.testingMode;
356
+ }
357
+ getSessionId() {
358
+ return this.sessionManager.getSessionId();
359
+ }
360
+ getSessionPath() {
361
+ return this.sessionManager.getSessionPath();
362
+ }
363
+ getConversationHistory() {
364
+ return this.sessionManager.getMessages();
365
+ }
366
+ extractToolCall(result) {
367
+ // Check for single function call first
368
+ if (result.function_call &&
369
+ result.function_call.name &&
370
+ result.function_call.arguments) {
371
+ return {
372
+ id: result.function_call.id,
373
+ name: result.function_call.name,
374
+ arguments: result.function_call.arguments,
375
+ };
376
+ }
377
+ // Check for multiple function calls
378
+ if (result.multiple &&
379
+ Array.isArray(result.multiple) &&
380
+ result.multiple.length > 0) {
381
+ const call = result.multiple[0];
382
+ if (call && call.name && call.arguments) {
383
+ return {
384
+ id: call.id,
385
+ name: call.name,
386
+ arguments: call.arguments,
387
+ };
388
+ }
389
+ }
390
+ // Legacy support for old format
391
+ if (result.name && result.arguments) {
392
+ return {
393
+ id: result.context?.tool_call_id,
394
+ name: result.name,
395
+ arguments: result.arguments,
396
+ };
397
+ }
398
+ return null;
399
+ }
400
+ extractAssistantText(result) {
401
+ if (typeof result.content === "string") {
402
+ return result.content;
403
+ }
404
+ if (Array.isArray(result.content)) {
405
+ const text = result.content
406
+ .map((chunk) => {
407
+ if (!chunk)
408
+ return "";
409
+ if (typeof chunk === "string")
410
+ return chunk;
411
+ if (typeof chunk?.text === "string")
412
+ return chunk.text;
413
+ return "";
414
+ })
415
+ .filter(Boolean)
416
+ .join("\n")
417
+ .trim();
418
+ if (text) {
419
+ return text;
420
+ }
421
+ }
422
+ // Check reasoning field as fallback
423
+ if (result.reasoning) {
424
+ return result.reasoning;
425
+ }
426
+ return result.message || "";
427
+ }
428
+ handleScreenshotInHistory(screenshotData, actionName) {
429
+ try {
430
+ // Create a screenshot message for the conversation history
431
+ const screenshotMessage = {
432
+ id: `screenshot-${Date.now()}`,
433
+ role: "assistant",
434
+ content: "",
435
+ timestamp: Date.now(),
436
+ metadata: {
437
+ type: "screenshot",
438
+ action_name: actionName,
439
+ screenshot_data: screenshotData,
440
+ page_url: screenshotData.page_url,
441
+ page_title: screenshotData.page_title,
442
+ image_url: screenshotData.image_url, // CDN URL for AI usage
443
+ cloudinary_uploaded: screenshotData.cloudinary_uploaded,
444
+ },
445
+ };
446
+ // Add screenshot message to conversation history
447
+ this.sessionManager.addMessage(screenshotMessage);
448
+ // Remove any previous screenshot messages to keep only the latest
449
+ this.removePreviousScreenshotMessages(screenshotMessage.id);
450
+ return screenshotMessage.id;
451
+ }
452
+ catch (error) {
453
+ // Don't fail the main flow if screenshot handling fails
454
+ return null;
455
+ }
456
+ }
457
+ removePreviousScreenshotMessages(currentScreenshotId) {
458
+ try {
459
+ const messages = this.sessionManager.getMessages();
460
+ const filteredMessages = messages.filter((msg) => {
461
+ // Keep the current screenshot message
462
+ if (msg.id === currentScreenshotId) {
463
+ return true;
464
+ }
465
+ // Remove other screenshot messages
466
+ if (msg.metadata?.type === "screenshot") {
467
+ return false;
468
+ }
469
+ return true;
470
+ });
471
+ // Clear and re-add filtered messages
472
+ this.sessionManager.clearMessages();
473
+ filteredMessages.forEach((msg) => this.sessionManager.addMessage(msg));
474
+ }
475
+ catch (error) {
476
+ // Ignore cleanup errors
477
+ }
478
+ }
479
+ addLatestScreenshotToContext(messages) {
480
+ // Only add screenshots for UI testing mode
481
+ if (this.config.testingMode !== "ui") {
482
+ return messages;
483
+ }
484
+ try {
485
+ const conversationMessages = this.sessionManager.getMessages();
486
+ // Find the latest screenshot message
487
+ const latestScreenshotMessage = conversationMessages
488
+ .filter((msg) => msg.metadata?.type === "screenshot")
489
+ .sort((a, b) => (b.timestamp || 0) - (a.timestamp || 0))[0];
490
+ if (!latestScreenshotMessage?.metadata?.image_url) {
491
+ return messages;
492
+ }
493
+ const imageUrl = latestScreenshotMessage.metadata.image_url;
494
+ const pageUrl = latestScreenshotMessage.metadata.page_url ??
495
+ latestScreenshotMessage.metadata.screenshot_data?.url ??
496
+ latestScreenshotMessage.metadata.screenshot_data?.page_url ??
497
+ "unknown";
498
+ const pageTitle = latestScreenshotMessage.metadata.page_title ??
499
+ latestScreenshotMessage.metadata.screenshot_data?.page_title ??
500
+ "unknown";
501
+ const actionName = latestScreenshotMessage.metadata.action_name ??
502
+ latestScreenshotMessage.metadata.screenshot_data?.action_name ??
503
+ "snapshot_refresh";
504
+ // Add screenshot as image message (similar to backend)
505
+ const screenshotMessage = {
506
+ role: "user",
507
+ content: [
508
+ {
509
+ type: "image_url",
510
+ image_url: {
511
+ url: imageUrl,
512
+ detail: "low",
513
+ },
514
+ },
515
+ {
516
+ type: "text",
517
+ text: `Current page screenshot after ${actionName?.replace(/_/g, " ")}: ${pageTitle} (${pageUrl})`,
518
+ },
519
+ ],
520
+ };
521
+ return [...messages, screenshotMessage];
522
+ }
523
+ catch (error) {
524
+ // Don't fail if screenshot context addition fails
525
+ return messages;
526
+ }
527
+ }
528
+ pruneToolResults(toolName) {
529
+ try {
530
+ const messages = this.sessionManager.getMessages();
531
+ // Prune tool results
532
+ const prunedMessages = toolResultPruner.pruneToolResults(messages, toolName);
533
+ // Cap conversation history if needed
534
+ const cappedMessages = toolResultPruner.capConversationHistory(prunedMessages);
535
+ // Update session with pruned messages
536
+ if (cappedMessages.length !== messages.length) {
537
+ this.sessionManager.clearMessages();
538
+ cappedMessages.forEach((msg) => this.sessionManager.addMessage(msg));
539
+ }
540
+ }
541
+ catch (error) {
542
+ // Don't fail on pruning errors
543
+ }
544
+ }
545
+ }
546
+ //# sourceMappingURL=agent-orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-orchestrator.js","sourceRoot":"","sources":["../../../src/lib/agent-orchestrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import cloudinary from "cloudinary";
2
+ import { config } from "dotenv";
3
+ // Load environment variables
4
+ config();
5
+ export class CloudinaryService {
6
+ initialized = false;
7
+ constructor() {
8
+ this.initialize();
9
+ }
10
+ initialize() {
11
+ const cloudName = process.env.CLOUDINARY_CLOUD_NAME;
12
+ const apiKey = process.env.CLOUDINARY_API_KEY;
13
+ const apiSecret = process.env.CLOUDINARY_API_SECRET;
14
+ if (!cloudName || !apiKey || !apiSecret) {
15
+ return;
16
+ }
17
+ try {
18
+ cloudinary.v2.config({
19
+ cloud_name: cloudName,
20
+ api_key: apiKey,
21
+ api_secret: apiSecret,
22
+ secure: true,
23
+ });
24
+ this.initialized = true;
25
+ }
26
+ catch (error) {
27
+ // Silent initialization failure
28
+ }
29
+ }
30
+ async uploadScreenshot(base64Data, options = {}) {
31
+ const mimeType = options.mimeType || "image/jpeg";
32
+ const dataUrl = `data:${mimeType};base64,${base64Data}`;
33
+ if (!this.initialized) {
34
+ return { url: dataUrl, uploaded: false };
35
+ }
36
+ try {
37
+ const folder = options.folder || process.env.CLOUDINARY_FOLDER || "cli-screenshots";
38
+ const publicId = options.publicId || `screenshot_${Date.now()}`;
39
+ const quality = options.quality || 50;
40
+ const format = options.mimeType?.split("/")[1]?.toLowerCase() || "jpg";
41
+ const result = await cloudinary.v2.uploader.upload(dataUrl, {
42
+ folder,
43
+ public_id: publicId,
44
+ resource_type: "image",
45
+ overwrite: true,
46
+ quality,
47
+ format,
48
+ });
49
+ const imageUrl = result.secure_url || result.url;
50
+ if (imageUrl) {
51
+ return { url: imageUrl, uploaded: true };
52
+ }
53
+ return { url: dataUrl, uploaded: false };
54
+ }
55
+ catch (error) {
56
+ return { url: dataUrl, uploaded: false };
57
+ }
58
+ }
59
+ isAvailable() {
60
+ return this.initialized;
61
+ }
62
+ }
63
+ // Export singleton instance
64
+ export const cloudinaryService = new CloudinaryService();
65
+ //# sourceMappingURL=cloudinary-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudinary-service.js","sourceRoot":"","sources":["../../../src/lib/cloudinary-service.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAC,MAAM,EAAC,MAAM,QAAQ,CAAC;AAE9B,6BAA6B;AAC7B,MAAM,EAAE,CAAC;AAYT,MAAM,OAAO,iBAAiB;IACpB,WAAW,GAAG,KAAK,CAAC;IAE5B;QACE,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;IAEO,UAAU;QAChB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;QACpD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;QAC9C,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;QAEpD,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACxC,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC;gBACnB,UAAU,EAAE,SAAS;gBACrB,OAAO,EAAE,MAAM;gBACf,UAAU,EAAE,SAAS;gBACrB,MAAM,EAAE,IAAI;aACb,CAAC,CAAC;YACH,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,gCAAgC;QAClC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB,CACpB,UAAkB,EAClB,UAKI,EAAE;QAEN,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,YAAY,CAAC;QAClD,MAAM,OAAO,GAAG,QAAQ,QAAQ,WAAW,UAAU,EAAE,CAAC;QAExD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAO,EAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAC,CAAC;QACzC,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GACV,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,iBAAiB,CAAC;YACvE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,cAAc,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YAChE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;YACtC,MAAM,MAAM,GACV,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,KAAK,CAAC;YAE1D,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE;gBAC1D,MAAM;gBACN,SAAS,EAAE,QAAQ;gBACnB,aAAa,EAAE,OAAO;gBACtB,SAAS,EAAE,IAAI;gBACf,OAAO;gBACP,MAAM;aACP,CAAC,CAAC;YAEH,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,GAAG,CAAC;YACjD,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,EAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC;YACzC,CAAC;YACD,OAAO,EAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAC,CAAC;QACzC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,4BAA4B;AAC5B,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,EAAE,CAAC"}