@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.
- package/README.md +201 -190
- package/dist/bin/ttt.js +4 -2
- package/dist/bin/ttt.js.map +1 -1
- package/dist/package.json +13 -2
- package/dist/src/commands/ask/AskApp.js +121 -0
- package/dist/src/commands/ask/AskApp.js.map +1 -0
- package/dist/src/commands/ask/components/AssistantResponse.js +31 -0
- package/dist/src/commands/ask/components/AssistantResponse.js.map +1 -0
- package/dist/src/commands/ask/components/Banner.js +15 -0
- package/dist/src/commands/ask/components/Banner.js.map +1 -0
- package/dist/src/commands/ask/components/ChatInput.js +93 -0
- package/dist/src/commands/ask/components/ChatInput.js.map +1 -0
- package/dist/src/commands/ask/components/Divider.js +17 -0
- package/dist/src/commands/ask/components/Divider.js.map +1 -0
- package/dist/src/commands/ask/components/IntroTips.js +19 -0
- package/dist/src/commands/ask/components/IntroTips.js.map +1 -0
- package/dist/src/commands/ask/components/MessageBubble.js +47 -0
- package/dist/src/commands/ask/components/MessageBubble.js.map +1 -0
- package/dist/src/commands/ask/components/SessionInfo.js +20 -0
- package/dist/src/commands/ask/components/SessionInfo.js.map +1 -0
- package/dist/src/commands/ask/components/StatusIndicator.js +67 -0
- package/dist/src/commands/ask/components/StatusIndicator.js.map +1 -0
- package/dist/src/commands/ask-ink.js +380 -0
- package/dist/src/commands/ask-ink.js.map +1 -0
- package/dist/src/commands/ask.js +73 -60
- package/dist/src/commands/ask.js.map +1 -1
- package/dist/src/commands/chat/ChatApp.js +125 -0
- package/dist/src/commands/chat/ChatApp.js.map +1 -0
- package/dist/src/commands/chat-ink.js +436 -0
- package/dist/src/commands/chat-ink.js.map +1 -0
- package/dist/src/commands/chat.js +82 -0
- package/dist/src/commands/chat.js.map +1 -0
- package/dist/src/commands/login.js +6 -4
- package/dist/src/commands/login.js.map +1 -1
- package/dist/src/commands/start-test.js +62 -88
- package/dist/src/commands/start-test.js.map +1 -1
- package/dist/src/commands/stream.js +9 -9
- package/dist/src/commands/stream.js.map +1 -1
- package/dist/src/commands/test.js +58 -125
- package/dist/src/commands/test.js.map +1 -1
- package/dist/src/lib/agent-orchestrator.js +546 -0
- package/dist/src/lib/agent-orchestrator.js.map +1 -0
- package/dist/src/lib/cloudinary-service.js +65 -0
- package/dist/src/lib/cloudinary-service.js.map +1 -0
- package/dist/src/lib/events.js +73 -60
- package/dist/src/lib/events.js.map +1 -1
- package/dist/src/lib/http.js +34 -1
- package/dist/src/lib/http.js.map +1 -1
- package/dist/src/lib/legacy-chat-runner.js +37 -0
- package/dist/src/lib/legacy-chat-runner.js.map +1 -0
- package/dist/src/lib/local-tools/api/api-discovery.js +17 -0
- package/dist/src/lib/local-tools/api/api-discovery.js.map +1 -0
- package/dist/src/lib/local-tools/api/build-request.js +20 -0
- package/dist/src/lib/local-tools/api/build-request.js.map +1 -0
- package/dist/src/lib/local-tools/api/extract-response-fields.js +26 -0
- package/dist/src/lib/local-tools/api/extract-response-fields.js.map +1 -0
- package/dist/src/lib/local-tools/api/generate-api-test.js +20 -0
- package/dist/src/lib/local-tools/api/generate-api-test.js.map +1 -0
- package/dist/src/lib/local-tools/api/generate-curl.js +8 -0
- package/dist/src/lib/local-tools/api/generate-curl.js.map +1 -0
- package/dist/src/lib/local-tools/api/get-api-parameters.js +17 -0
- package/dist/src/lib/local-tools/api/get-api-parameters.js.map +1 -0
- package/dist/src/lib/local-tools/api/index.js +10 -0
- package/dist/src/lib/local-tools/api/index.js.map +1 -0
- package/dist/src/lib/local-tools/api/request.js +43 -0
- package/dist/src/lib/local-tools/api/request.js.map +1 -0
- package/dist/src/lib/local-tools/api/set-auth-header.js +8 -0
- package/dist/src/lib/local-tools/api/set-auth-header.js.map +1 -0
- package/dist/src/lib/local-tools/api/types.js +2 -0
- package/dist/src/lib/local-tools/api/types.js.map +1 -0
- package/dist/src/lib/local-tools/api/utils.js +33 -0
- package/dist/src/lib/local-tools/api/utils.js.map +1 -0
- package/dist/src/lib/local-tools/api/validate-response.js +41 -0
- package/dist/src/lib/local-tools/api/validate-response.js.map +1 -0
- package/dist/src/lib/local-tools/file-tools.js +45 -0
- package/dist/src/lib/local-tools/file-tools.js.map +1 -0
- package/dist/src/lib/local-tools/general/discover-local-services.js +95 -0
- package/dist/src/lib/local-tools/general/discover-local-services.js.map +1 -0
- package/dist/src/lib/local-tools/general/index.js +2 -0
- package/dist/src/lib/local-tools/general/index.js.map +1 -0
- package/dist/src/lib/local-tools/ui/click-element.js +105 -0
- package/dist/src/lib/local-tools/ui/click-element.js.map +1 -0
- package/dist/src/lib/local-tools/ui/dom-rag.js +201 -0
- package/dist/src/lib/local-tools/ui/dom-rag.js.map +1 -0
- package/dist/src/lib/local-tools/ui/find-element.js +31 -0
- package/dist/src/lib/local-tools/ui/find-element.js.map +1 -0
- package/dist/src/lib/local-tools/ui/hover-element.js +94 -0
- package/dist/src/lib/local-tools/ui/hover-element.js.map +1 -0
- package/dist/src/lib/local-tools/ui/index.js +3 -0
- package/dist/src/lib/local-tools/ui/index.js.map +1 -0
- package/dist/src/lib/local-tools/ui/manage-tab.js +65 -0
- package/dist/src/lib/local-tools/ui/manage-tab.js.map +1 -0
- package/dist/src/lib/local-tools/ui/navigate.js +35 -0
- package/dist/src/lib/local-tools/ui/navigate.js.map +1 -0
- package/dist/src/lib/local-tools/ui/page-discovery.js +32 -0
- package/dist/src/lib/local-tools/ui/page-discovery.js.map +1 -0
- package/dist/src/lib/local-tools/ui/playwright-mcp.js +217 -0
- package/dist/src/lib/local-tools/ui/playwright-mcp.js.map +1 -0
- package/dist/src/lib/local-tools/ui/screenshot.js +19 -0
- package/dist/src/lib/local-tools/ui/screenshot.js.map +1 -0
- package/dist/src/lib/local-tools/ui/search-interactive-elements.js +18 -0
- package/dist/src/lib/local-tools/ui/search-interactive-elements.js.map +1 -0
- package/dist/src/lib/local-tools/ui/selector-resolver.js +153 -0
- package/dist/src/lib/local-tools/ui/selector-resolver.js.map +1 -0
- package/dist/src/lib/local-tools/ui/snapshot-query.js +129 -0
- package/dist/src/lib/local-tools/ui/snapshot-query.js.map +1 -0
- package/dist/src/lib/local-tools/ui/type-text.js +40 -0
- package/dist/src/lib/local-tools/ui/type-text.js.map +1 -0
- package/dist/src/lib/local-tools/ui/types.js +2 -0
- package/dist/src/lib/local-tools/ui/types.js.map +1 -0
- package/dist/src/lib/local-tools/utility/finish-overall-test.js +12 -0
- package/dist/src/lib/local-tools/utility/finish-overall-test.js.map +1 -0
- package/dist/src/lib/local-tools/utility/index.js +2 -0
- package/dist/src/lib/local-tools/utility/index.js.map +1 -0
- package/dist/src/lib/prompts/builder.js +38 -0
- package/dist/src/lib/prompts/builder.js.map +1 -0
- package/dist/src/lib/prompts/index.js +7 -0
- package/dist/src/lib/prompts/index.js.map +1 -0
- package/dist/src/lib/prompts/templates.js +166 -0
- package/dist/src/lib/prompts/templates.js.map +1 -0
- package/dist/src/lib/session-manager.js +201 -0
- package/dist/src/lib/session-manager.js.map +1 -0
- package/dist/src/lib/socket.js +70 -9
- package/dist/src/lib/socket.js.map +1 -1
- package/dist/src/lib/testing-mode.js +33 -0
- package/dist/src/lib/testing-mode.js.map +1 -0
- package/dist/src/lib/tool-descriptions.js +59 -0
- package/dist/src/lib/tool-descriptions.js.map +1 -0
- package/dist/src/lib/tool-executor.js +537 -0
- package/dist/src/lib/tool-executor.js.map +1 -0
- package/dist/src/lib/tool-registry.js +803 -0
- package/dist/src/lib/tool-registry.js.map +1 -0
- package/dist/src/lib/tool-result-pruner.js +384 -0
- package/dist/src/lib/tool-result-pruner.js.map +1 -0
- package/dist/src/lib/tui/components/AskIntro.js +6 -0
- package/dist/src/lib/tui/components/AskIntro.js.map +1 -0
- package/dist/src/lib/tui/components/Banner.js +15 -0
- package/dist/src/lib/tui/components/Banner.js.map +1 -0
- package/dist/src/lib/tui/components/Divider.js +17 -0
- package/dist/src/lib/tui/components/Divider.js.map +1 -0
- package/dist/src/lib/tui/components/EventLine.js +110 -0
- package/dist/src/lib/tui/components/EventLine.js.map +1 -0
- package/dist/src/lib/tui/components/Header.js +15 -0
- package/dist/src/lib/tui/components/Header.js.map +1 -0
- package/dist/src/lib/tui/components/InputBox.js +9 -0
- package/dist/src/lib/tui/components/InputBox.js.map +1 -0
- package/dist/src/lib/tui/components/Mapping.js +8 -0
- package/dist/src/lib/tui/components/Mapping.js.map +1 -0
- package/dist/src/lib/tui/components/ProjectList.js +6 -0
- package/dist/src/lib/tui/components/ProjectList.js.map +1 -0
- package/dist/src/lib/tui/components/Spinner.js +20 -0
- package/dist/src/lib/tui/components/Spinner.js.map +1 -0
- package/dist/src/lib/tui/components/StatusBanner.js +12 -0
- package/dist/src/lib/tui/components/StatusBanner.js.map +1 -0
- package/dist/src/lib/tui/components/StatusBar.js +11 -0
- package/dist/src/lib/tui/components/StatusBar.js.map +1 -0
- package/dist/src/lib/tui/components/UserBubble.js +6 -0
- package/dist/src/lib/tui/components/UserBubble.js.map +1 -0
- package/dist/src/lib/tui/components/index.js +16 -0
- package/dist/src/lib/tui/components/index.js.map +1 -0
- package/dist/src/lib/tui/events.js +716 -76
- package/dist/src/lib/tui/events.js.map +1 -1
- package/dist/src/lib/tui/icons.js +14 -0
- package/dist/src/lib/tui/icons.js.map +1 -1
- package/dist/src/lib/tui/ink-print.js +41 -0
- package/dist/src/lib/tui/ink-print.js.map +1 -0
- package/dist/src/lib/tui/interactive-chat.js +345 -0
- package/dist/src/lib/tui/interactive-chat.js.map +1 -0
- package/dist/src/lib/tui/print.js +31 -26
- package/dist/src/lib/tui/print.js.map +1 -1
- package/dist/src/lib/tui/prompt.js +21 -18
- package/dist/src/lib/tui/prompt.js.map +1 -1
- package/dist/src/test-agent-flow.js +148 -0
- package/dist/src/test-agent-flow.js.map +1 -0
- package/dist/src/test-browser-session.js +152 -0
- package/dist/src/test-browser-session.js.map +1 -0
- package/dist/src/test-browser-snapshot.js +187 -0
- package/dist/src/test-browser-snapshot.js.map +1 -0
- package/dist/src/test-snapshot-detailed.js +219 -0
- package/dist/src/test-snapshot-detailed.js.map +1 -0
- package/dist/src/test-snapshot-simple.js +85 -0
- package/dist/src/test-snapshot-simple.js.map +1 -0
- package/dist/src/test-snapshot-tabs.js +110 -0
- package/dist/src/test-snapshot-tabs.js.map +1 -0
- package/package.json +13 -2
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export const TESTING_MODES = ["ui", "api"];
|
|
2
|
+
export function parseTestingMode(value) {
|
|
3
|
+
if (typeof value !== "string") {
|
|
4
|
+
return null;
|
|
5
|
+
}
|
|
6
|
+
const normalized = value.toLowerCase();
|
|
7
|
+
if (normalized === "ui" || normalized === "api") {
|
|
8
|
+
return normalized;
|
|
9
|
+
}
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
export function resolveTestingMode(value, options = {}) {
|
|
13
|
+
const { defaultMode = "ui", strict = false, contextLabel } = options;
|
|
14
|
+
const parsed = parseTestingMode(value);
|
|
15
|
+
if (parsed) {
|
|
16
|
+
return parsed;
|
|
17
|
+
}
|
|
18
|
+
const isEmpty = value === undefined || value === null || value === "";
|
|
19
|
+
if (!strict && isEmpty) {
|
|
20
|
+
return defaultMode;
|
|
21
|
+
}
|
|
22
|
+
const supported = TESTING_MODES.join(", ");
|
|
23
|
+
const labelPrefix = contextLabel ? `${contextLabel} ` : "";
|
|
24
|
+
const received = isEmpty ? "<empty>" : JSON.stringify(value);
|
|
25
|
+
throw new Error(`${labelPrefix}invalid testing mode ${received}. Supported modes: ${supported}.`);
|
|
26
|
+
}
|
|
27
|
+
export function assertTestingMode(value, label) {
|
|
28
|
+
return resolveTestingMode(value, { strict: true, contextLabel: label });
|
|
29
|
+
}
|
|
30
|
+
export function isTestingMode(value) {
|
|
31
|
+
return parseTestingMode(value) !== null;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=testing-mode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing-mode.js","sourceRoot":"","sources":["../../../src/lib/testing-mode.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,KAAK,CAAU,CAAC;AAIpD,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IACvC,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;QAChD,OAAO,UAAyB,CAAC;IACnC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAQD,MAAM,UAAU,kBAAkB,CAChC,KAAc,EACd,UAAqC,EAAE;IAEvC,MAAM,EAAC,WAAW,GAAG,IAAI,EAAE,MAAM,GAAG,KAAK,EAAE,YAAY,EAAC,GAAG,OAAO,CAAC;IACnE,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;IACtE,IAAI,CAAC,MAAM,IAAI,OAAO,EAAE,CAAC;QACvB,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC7D,MAAM,IAAI,KAAK,CACb,GAAG,WAAW,wBAAwB,QAAQ,sBAAsB,SAAS,GAAG,CACjF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAc,EAAE,KAAc;IAC9D,OAAO,kBAAkB,CAAC,KAAK,EAAE,EAAC,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAC,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,gBAAgB,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool description utility - shared across CLI components
|
|
3
|
+
*/
|
|
4
|
+
export function getToolDescription(toolName) {
|
|
5
|
+
const descriptions = {
|
|
6
|
+
// UI tools
|
|
7
|
+
browser_navigate: "Navigated to a page or URL",
|
|
8
|
+
browser_snapshot_query: "Searched the cached snapshot for matching elements",
|
|
9
|
+
browser_click: "Clicked an element using its MCP ref",
|
|
10
|
+
browser_hover: "Hovered over an element using its MCP ref",
|
|
11
|
+
browser_type: "Typed text into an element",
|
|
12
|
+
browser_press_key: "Pressed a keyboard key",
|
|
13
|
+
browser_wait_for: "Waited for text or time-based conditions",
|
|
14
|
+
browser_take_screenshot: "Captured a screenshot of the current page or element",
|
|
15
|
+
browser_select_option: "Selected option(s) from a dropdown",
|
|
16
|
+
browser_fill_form: "Filled multiple form fields",
|
|
17
|
+
browser_tabs: "Managed browser tabs",
|
|
18
|
+
browser_handle_dialog: "Handled (accepted/dismissed) a dialog",
|
|
19
|
+
browser_network_requests: "Retrieved recent network requests",
|
|
20
|
+
browser_console_messages: "Retrieved console output",
|
|
21
|
+
browser_resize: "Resized the browser viewport",
|
|
22
|
+
browser_drag: "Dragged from one element to another",
|
|
23
|
+
generate_test_cases: "Generated test cases from screenshot/context",
|
|
24
|
+
set_testing_mode: "Configured testing mode and browser settings",
|
|
25
|
+
// API tools
|
|
26
|
+
api_discovery: "Discovered API endpoints and documentation",
|
|
27
|
+
build_api_request: "Built an API request with parameters and body",
|
|
28
|
+
generate_curl: "Generated a cURL command for an API request",
|
|
29
|
+
generate_api_test: "Generated API test cases",
|
|
30
|
+
search_discovered_endpoints: "Searched discovered API endpoints",
|
|
31
|
+
get_api_parameters: "Loaded API parameters and schema",
|
|
32
|
+
get_api: "Executed a GET request",
|
|
33
|
+
post_api: "Executed a POST request",
|
|
34
|
+
put_api: "Executed a PUT request",
|
|
35
|
+
patch_api: "Executed a PATCH request",
|
|
36
|
+
delete_api: "Executed a DELETE request",
|
|
37
|
+
validate_api_response: "Validated API response values",
|
|
38
|
+
assert_response_schema: "Asserted response matches schema",
|
|
39
|
+
extract_response_fields: "Extracted fields from API response",
|
|
40
|
+
set_auth_header: "Configured authorization header for requests",
|
|
41
|
+
// Memory tools
|
|
42
|
+
memory_search: "Searched agent memory for prior context",
|
|
43
|
+
memory_store: "Stored information in agent memory",
|
|
44
|
+
memory_update: "Updated existing agent memory records",
|
|
45
|
+
memory_delete: "Deleted items from agent memory",
|
|
46
|
+
// Browser management
|
|
47
|
+
browser_session: "Started or stopped browser session for UI testing",
|
|
48
|
+
clear_browser_state: "Cleared browser/session state",
|
|
49
|
+
reset_browser: "Reset browser context",
|
|
50
|
+
reset_for_next_test_case: "Reset state before next test case",
|
|
51
|
+
// Utility
|
|
52
|
+
finish: "Finished task and stopped agent loop",
|
|
53
|
+
finish_overall_test: "Finished test and generated report",
|
|
54
|
+
todo: "Managed todo items for execution",
|
|
55
|
+
reporting: "Generated or updated reporting data",
|
|
56
|
+
};
|
|
57
|
+
return descriptions[toolName] || "Executed tool to gather information";
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=tool-descriptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-descriptions.js","sourceRoot":"","sources":["../../../src/lib/tool-descriptions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,MAAM,YAAY,GAA2B;QAC3C,WAAW;QACX,gBAAgB,EAAE,4BAA4B;QAC9C,sBAAsB,EAAE,oDAAoD;QAC5E,aAAa,EAAE,sCAAsC;QACrD,aAAa,EAAE,2CAA2C;QAC1D,YAAY,EAAE,4BAA4B;QAC1C,iBAAiB,EAAE,wBAAwB;QAC3C,gBAAgB,EAAE,0CAA0C;QAC5D,uBAAuB,EAAE,sDAAsD;QAC/E,qBAAqB,EAAE,oCAAoC;QAC3D,iBAAiB,EAAE,6BAA6B;QAChD,YAAY,EAAE,sBAAsB;QACpC,qBAAqB,EAAE,uCAAuC;QAC9D,wBAAwB,EAAE,mCAAmC;QAC7D,wBAAwB,EAAE,0BAA0B;QACpD,cAAc,EAAE,8BAA8B;QAC9C,YAAY,EAAE,qCAAqC;QACnD,mBAAmB,EAAE,8CAA8C;QACnE,gBAAgB,EAAE,8CAA8C;QAChE,YAAY;QACZ,aAAa,EAAE,4CAA4C;QAC3D,iBAAiB,EAAE,+CAA+C;QAClE,aAAa,EAAE,6CAA6C;QAC5D,iBAAiB,EAAE,0BAA0B;QAC7C,2BAA2B,EAAE,mCAAmC;QAChE,kBAAkB,EAAE,kCAAkC;QACtD,OAAO,EAAE,wBAAwB;QACjC,QAAQ,EAAE,yBAAyB;QACnC,OAAO,EAAE,wBAAwB;QACjC,SAAS,EAAE,0BAA0B;QACrC,UAAU,EAAE,2BAA2B;QACvC,qBAAqB,EAAE,+BAA+B;QACtD,sBAAsB,EAAE,kCAAkC;QAC1D,uBAAuB,EAAE,oCAAoC;QAC7D,eAAe,EAAE,8CAA8C;QAC/D,eAAe;QACf,aAAa,EAAE,yCAAyC;QACxD,YAAY,EAAE,oCAAoC;QAClD,aAAa,EAAE,uCAAuC;QACtD,aAAa,EAAE,iCAAiC;QAChD,qBAAqB;QACrB,eAAe,EAAE,mDAAmD;QACpE,mBAAmB,EAAE,+BAA+B;QACpD,aAAa,EAAE,uBAAuB;QACtC,wBAAwB,EAAE,mCAAmC;QAC7D,UAAU;QACV,MAAM,EAAE,sCAAsC;QAC9C,mBAAmB,EAAE,oCAAoC;QACzD,IAAI,EAAE,kCAAkC;QACxC,SAAS,EAAE,qCAAqC;KACjD,CAAC;IAEF,OAAO,YAAY,CAAC,QAAQ,CAAC,IAAI,qCAAqC,CAAC;AACzE,CAAC"}
|
|
@@ -0,0 +1,537 @@
|
|
|
1
|
+
import * as UiTools from "./local-tools/ui/index.js";
|
|
2
|
+
import * as ApiTools from "./local-tools/api/index.js";
|
|
3
|
+
import { finishOverallTest } from "./local-tools/utility/index.js";
|
|
4
|
+
import { parseTestingMode, TESTING_MODES, } from "./testing-mode.js";
|
|
5
|
+
import { cloudinaryService } from "./cloudinary-service.js";
|
|
6
|
+
import { Buffer } from "node:buffer";
|
|
7
|
+
const LEGACY_TOOL_HINTS = {
|
|
8
|
+
navigate: 'Tool "navigate" has been replaced by "browser_navigate". Snapshots refresh automatically; inspect them with browser_snapshot_query.',
|
|
9
|
+
click_element: 'Tool "click_element" has been removed. Use browser_snapshot_query to find refs, then call "browser_click".',
|
|
10
|
+
hover_element: 'Tool "hover_element" is deprecated. Use "browser_hover" with refs from browser_snapshot_query.',
|
|
11
|
+
type_text: 'Tool "type_text" has been replaced by "browser_type" or "browser_fill_form".',
|
|
12
|
+
screenshot: 'Tool "screenshot" is no longer available. Use "browser_take_screenshot".',
|
|
13
|
+
search_interactive_elements: "DOM RAG search is retired. Use browser_snapshot_query to reason over the cached structure.",
|
|
14
|
+
manage_tab: 'Tab management now lives under "browser_tabs".',
|
|
15
|
+
browser_snapshot: "Snapshots are managed automatically. Use browser_snapshot_query to inspect the cached snapshot.",
|
|
16
|
+
page_discovery: 'Automatic page discovery is not supported locally. Use "browser_navigate" to explore pages manually.',
|
|
17
|
+
};
|
|
18
|
+
export class ToolExecutor {
|
|
19
|
+
context;
|
|
20
|
+
lastScreenshotTime = 0;
|
|
21
|
+
screenshotThrottleMs = 300; // Same as backend
|
|
22
|
+
screenshotQuality = 50; // Same as backend
|
|
23
|
+
pendingScreenshot = null;
|
|
24
|
+
// Extract only the YAML accessibility tree from a "Page state" section.
|
|
25
|
+
// Supports fenced blocks ```yaml ... ``` or ``` ... ```. Falls back to raw text.
|
|
26
|
+
extractAriaYaml(pageStateSection) {
|
|
27
|
+
if (!pageStateSection)
|
|
28
|
+
return undefined;
|
|
29
|
+
const fenceYaml = /```yaml\n([\s\S]*?)```/m.exec(pageStateSection);
|
|
30
|
+
if (fenceYaml?.[1])
|
|
31
|
+
return fenceYaml[1].trim();
|
|
32
|
+
const fenceAny = /```\n([\s\S]*?)```/m.exec(pageStateSection);
|
|
33
|
+
if (fenceAny?.[1])
|
|
34
|
+
return fenceAny[1].trim();
|
|
35
|
+
// If there are known preamble lines (Page URL/Title/Page Snapshot:), try to remove them.
|
|
36
|
+
const lines = pageStateSection
|
|
37
|
+
.split("\n")
|
|
38
|
+
.filter((l) => !/^\s*-\s*Page URL:/i.test(l) &&
|
|
39
|
+
!/^\s*-\s*Page Title:/i.test(l) &&
|
|
40
|
+
!/^\s*-\s*Page Snapshot:/i.test(l));
|
|
41
|
+
const cleaned = lines.join("\n").trim();
|
|
42
|
+
return cleaned.length ? cleaned : undefined;
|
|
43
|
+
}
|
|
44
|
+
constructor(context) {
|
|
45
|
+
this.context = context;
|
|
46
|
+
}
|
|
47
|
+
async execute(toolCall) {
|
|
48
|
+
const { name, arguments: args } = toolCall;
|
|
49
|
+
if (LEGACY_TOOL_HINTS[name]) {
|
|
50
|
+
return { success: false, error: LEGACY_TOOL_HINTS[name] };
|
|
51
|
+
}
|
|
52
|
+
// Route to appropriate tool implementation
|
|
53
|
+
switch (name) {
|
|
54
|
+
// API Tools
|
|
55
|
+
case "api_request":
|
|
56
|
+
return this.executeApiRequest(args);
|
|
57
|
+
case "build_api_request":
|
|
58
|
+
return this.executeBuildApiRequest(args);
|
|
59
|
+
case "generate_curl":
|
|
60
|
+
return this.executeGenerateCurl(args);
|
|
61
|
+
case "validate_api_response":
|
|
62
|
+
return this.executeValidateApiResponse(args);
|
|
63
|
+
case "extract_response_fields":
|
|
64
|
+
return this.executeExtractResponseFields(args);
|
|
65
|
+
case "set_auth_header":
|
|
66
|
+
return this.executeSetAuthHeader(args);
|
|
67
|
+
case "generate_api_test":
|
|
68
|
+
return this.executeGenerateApiTest(args);
|
|
69
|
+
case "get_api_parameters":
|
|
70
|
+
return this.executeGetApiParameters(args);
|
|
71
|
+
case "api_discovery":
|
|
72
|
+
return this.executeApiDiscovery(args);
|
|
73
|
+
// General Tools
|
|
74
|
+
case "set_testing_mode":
|
|
75
|
+
return this.executeSetTestingMode(args);
|
|
76
|
+
case "browser_session":
|
|
77
|
+
return this.executeBrowserSession(args);
|
|
78
|
+
case "finish":
|
|
79
|
+
return this.executeFinish(args);
|
|
80
|
+
case "finish_overall_test":
|
|
81
|
+
return this.executeFinishOverallTest(args);
|
|
82
|
+
case "browser_snapshot_query":
|
|
83
|
+
return this.executeSnapshotQuery(args);
|
|
84
|
+
default:
|
|
85
|
+
// Handle browser_* tools via MCP
|
|
86
|
+
if (name.startsWith("browser_")) {
|
|
87
|
+
return this.executeBrowserTool(name, args);
|
|
88
|
+
}
|
|
89
|
+
if (LEGACY_TOOL_HINTS[name]) {
|
|
90
|
+
return { success: false, error: LEGACY_TOOL_HINTS[name] };
|
|
91
|
+
}
|
|
92
|
+
return { success: false, error: `Unknown tool: ${name}` };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async executeSnapshotQuery(args) {
|
|
96
|
+
const modeError = this.ensureMode("ui");
|
|
97
|
+
if (modeError)
|
|
98
|
+
return modeError;
|
|
99
|
+
if (!this.context.browserContext) {
|
|
100
|
+
this.context.browserContext = {};
|
|
101
|
+
}
|
|
102
|
+
const { text, limit } = args;
|
|
103
|
+
return UiTools.snapshotQuery(this.context.browserContext, {
|
|
104
|
+
text,
|
|
105
|
+
limit,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
snapshotRefreshTools = new Set([
|
|
109
|
+
"browser_navigate",
|
|
110
|
+
"browser_click",
|
|
111
|
+
"browser_hover",
|
|
112
|
+
"browser_type",
|
|
113
|
+
"browser_fill_form",
|
|
114
|
+
"browser_select_option",
|
|
115
|
+
"browser_press_key",
|
|
116
|
+
"browser_wait_for",
|
|
117
|
+
"browser_wait_for",
|
|
118
|
+
"browser_handle_dialog",
|
|
119
|
+
"browser_drag",
|
|
120
|
+
"browser_resize",
|
|
121
|
+
]);
|
|
122
|
+
lastSnapshotRefresh = 0;
|
|
123
|
+
snapshotRefreshThrottleMs = 500;
|
|
124
|
+
screenshotActions = new Set([
|
|
125
|
+
"browser_navigate",
|
|
126
|
+
"browser_click",
|
|
127
|
+
"browser_hover",
|
|
128
|
+
"browser_type",
|
|
129
|
+
"browser_fill_form",
|
|
130
|
+
"browser_select_option",
|
|
131
|
+
"browser_press_key",
|
|
132
|
+
"browser_wait_for",
|
|
133
|
+
"browser_wait_for",
|
|
134
|
+
"browser_handle_dialog",
|
|
135
|
+
"browser_drag",
|
|
136
|
+
"browser_resize",
|
|
137
|
+
]);
|
|
138
|
+
async refreshSnapshotCache() {
|
|
139
|
+
if (!this.context.browserContext) {
|
|
140
|
+
this.context.browserContext = {};
|
|
141
|
+
}
|
|
142
|
+
const now = Date.now();
|
|
143
|
+
if (now - this.lastSnapshotRefresh < this.snapshotRefreshThrottleMs) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
this.lastSnapshotRefresh = now;
|
|
147
|
+
try {
|
|
148
|
+
const snapshotResult = await UiTools.callMcpTool(this.context.browserContext, "browser_snapshot", {});
|
|
149
|
+
if (!snapshotResult.success) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const pageState = snapshotResult.sections.get("Page state");
|
|
153
|
+
const ariaYaml = this.extractAriaYaml(pageState);
|
|
154
|
+
if (ariaYaml) {
|
|
155
|
+
this.context.browserContext.snapshotCache = {
|
|
156
|
+
timestamp: Date.now(),
|
|
157
|
+
mode: "full",
|
|
158
|
+
ariaSnapshot: ariaYaml,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
// best effort
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async executeBrowserTool(name, args) {
|
|
167
|
+
const modeError = this.ensureMode("ui");
|
|
168
|
+
if (modeError)
|
|
169
|
+
return modeError;
|
|
170
|
+
if (!this.context.browserContext) {
|
|
171
|
+
this.context.browserContext = {};
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
await UiTools.ensureMcpConnection(this.context.browserContext);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
return {
|
|
178
|
+
success: false,
|
|
179
|
+
error: `Failed to ensure Playwright MCP connection: ${error?.message ?? String(error)}`,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
try {
|
|
183
|
+
const callResult = await UiTools.callMcpTool(this.context.browserContext, name, args ?? {});
|
|
184
|
+
const snapshotSection = callResult.sections.get("Page state");
|
|
185
|
+
if (snapshotSection) {
|
|
186
|
+
if (!this.context.browserContext) {
|
|
187
|
+
this.context.browserContext = {};
|
|
188
|
+
}
|
|
189
|
+
const ariaYaml = this.extractAriaYaml(snapshotSection);
|
|
190
|
+
if (ariaYaml) {
|
|
191
|
+
this.context.browserContext.snapshotCache = {
|
|
192
|
+
timestamp: Date.now(),
|
|
193
|
+
mode: "full",
|
|
194
|
+
ariaSnapshot: ariaYaml,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
callResult.sections.delete("Page state");
|
|
198
|
+
if (Array.isArray(callResult.raw.content)) {
|
|
199
|
+
callResult.raw.content = callResult.raw.content.filter((entry) => {
|
|
200
|
+
return !(entry?.type === "text" &&
|
|
201
|
+
typeof entry.text === "string" &&
|
|
202
|
+
entry.text.includes("### Page state"));
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const response = this.normalizeMcpResult(callResult);
|
|
207
|
+
// For MCP browser tools, aggressively prune heavy sections and text content
|
|
208
|
+
if (name.startsWith("browser_") && name !== "browser_snapshot_query") {
|
|
209
|
+
if (response.sections)
|
|
210
|
+
delete response.sections;
|
|
211
|
+
// Remove verbose text entries; keep only images (if any) since we attach a dedicated screenshot field anyway
|
|
212
|
+
if (Array.isArray(response.content)) {
|
|
213
|
+
response.content = response.content.filter((entry) => entry && entry.type === "image");
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
response.content = [];
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
const needsScreenshot = this.screenshotActions.has(name) || name === "browser_take_screenshot";
|
|
220
|
+
if (needsScreenshot) {
|
|
221
|
+
await this.captureScreenshotAfterAction(name, name === "browser_take_screenshot" ? callResult : undefined);
|
|
222
|
+
// Screenshot data is recorded separately and exposed via consumePendingScreenshot().
|
|
223
|
+
}
|
|
224
|
+
if (callResult.success &&
|
|
225
|
+
!snapshotSection &&
|
|
226
|
+
this.snapshotRefreshTools.has(name) &&
|
|
227
|
+
name !== "browser_snapshot_query") {
|
|
228
|
+
await this.refreshSnapshotCache();
|
|
229
|
+
}
|
|
230
|
+
return response;
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
const failure = {
|
|
234
|
+
success: false,
|
|
235
|
+
error: error?.message ?? String(error),
|
|
236
|
+
};
|
|
237
|
+
if (this.screenshotActions.has(name)) {
|
|
238
|
+
await this.captureScreenshotAfterAction(`${name}_failure`);
|
|
239
|
+
// Screenshot data is recorded separately and exposed via consumePendingScreenshot().
|
|
240
|
+
}
|
|
241
|
+
return failure;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
normalizeMcpResult(result) {
|
|
245
|
+
const sectionsObject = result.sections.size > 0
|
|
246
|
+
? Object.fromEntries(result.sections)
|
|
247
|
+
: undefined;
|
|
248
|
+
const normalized = {
|
|
249
|
+
success: result.success,
|
|
250
|
+
summary: result.summary,
|
|
251
|
+
content: result.raw.content,
|
|
252
|
+
};
|
|
253
|
+
if (result.raw.structuredContent) {
|
|
254
|
+
normalized.structured_content = result.raw.structuredContent;
|
|
255
|
+
}
|
|
256
|
+
if (sectionsObject) {
|
|
257
|
+
normalized.sections = sectionsObject;
|
|
258
|
+
}
|
|
259
|
+
if (result.images.length) {
|
|
260
|
+
normalized.images = result.images;
|
|
261
|
+
}
|
|
262
|
+
return normalized;
|
|
263
|
+
}
|
|
264
|
+
extractPageMetadata(sections) {
|
|
265
|
+
const pageState = sections.get("Page state");
|
|
266
|
+
if (!pageState)
|
|
267
|
+
return {};
|
|
268
|
+
const metadata = {};
|
|
269
|
+
for (const line of pageState.split("\n")) {
|
|
270
|
+
const trimmed = line.trim();
|
|
271
|
+
if (trimmed.startsWith("- Page URL:")) {
|
|
272
|
+
metadata.url = trimmed.slice("- Page URL:".length).trim();
|
|
273
|
+
}
|
|
274
|
+
else if (trimmed.startsWith("- Page Title:")) {
|
|
275
|
+
metadata.title = trimmed.slice("- Page Title:".length).trim();
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return metadata;
|
|
279
|
+
}
|
|
280
|
+
async executeApiRequest(args) {
|
|
281
|
+
const modeError = this.ensureMode("api");
|
|
282
|
+
if (modeError)
|
|
283
|
+
return modeError;
|
|
284
|
+
if (!this.context.apiContext) {
|
|
285
|
+
this.context.apiContext = {};
|
|
286
|
+
}
|
|
287
|
+
return ApiTools.apiRequest(this.context.apiContext, {
|
|
288
|
+
method: args.method,
|
|
289
|
+
url: args.url,
|
|
290
|
+
headers: args.headers,
|
|
291
|
+
payload: args.payload,
|
|
292
|
+
queryParams: args.query_params,
|
|
293
|
+
timeout: args.timeout,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
async executeBuildApiRequest(args) {
|
|
297
|
+
const modeError = this.ensureMode("api");
|
|
298
|
+
if (modeError)
|
|
299
|
+
return modeError;
|
|
300
|
+
return ApiTools.buildApiRequest(args.method, args.url, args.headers, args.payload, args.parameters);
|
|
301
|
+
}
|
|
302
|
+
async executeGenerateCurl(args) {
|
|
303
|
+
const modeError = this.ensureMode("api");
|
|
304
|
+
if (modeError)
|
|
305
|
+
return modeError;
|
|
306
|
+
return ApiTools.generateCurl(args.method, args.url, args.headers, args.payload);
|
|
307
|
+
}
|
|
308
|
+
async executeValidateApiResponse(args) {
|
|
309
|
+
const modeError = this.ensureMode("api");
|
|
310
|
+
if (modeError)
|
|
311
|
+
return modeError;
|
|
312
|
+
return ApiTools.validateApiResponse(args.response, args.expected_status, args.expected_content_type, args.max_response_time);
|
|
313
|
+
}
|
|
314
|
+
async executeExtractResponseFields(args) {
|
|
315
|
+
const modeError = this.ensureMode("api");
|
|
316
|
+
if (modeError)
|
|
317
|
+
return modeError;
|
|
318
|
+
return ApiTools.extractResponseFields(args.response, args.paths ?? []);
|
|
319
|
+
}
|
|
320
|
+
async executeSetAuthHeader(args) {
|
|
321
|
+
const modeError = this.ensureMode("api");
|
|
322
|
+
if (modeError)
|
|
323
|
+
return modeError;
|
|
324
|
+
if (!this.context.apiContext) {
|
|
325
|
+
this.context.apiContext = {};
|
|
326
|
+
}
|
|
327
|
+
return ApiTools.setAuthHeader(args.token, this.context.apiContext);
|
|
328
|
+
}
|
|
329
|
+
async executeGenerateApiTest(args) {
|
|
330
|
+
const modeError = this.ensureMode("api");
|
|
331
|
+
if (modeError)
|
|
332
|
+
return modeError;
|
|
333
|
+
return ApiTools.generateApiTest(args.base_url, args.endpoints, args.test_type || "basic");
|
|
334
|
+
}
|
|
335
|
+
async executeGetApiParameters(args) {
|
|
336
|
+
const modeError = this.ensureMode("api");
|
|
337
|
+
if (modeError)
|
|
338
|
+
return modeError;
|
|
339
|
+
return ApiTools.getApiParameters(args);
|
|
340
|
+
}
|
|
341
|
+
async executeApiDiscovery(args) {
|
|
342
|
+
const modeError = this.ensureMode("api");
|
|
343
|
+
if (modeError)
|
|
344
|
+
return modeError;
|
|
345
|
+
return ApiTools.apiDiscovery(args.action, args);
|
|
346
|
+
}
|
|
347
|
+
async executeSetTestingMode(args) {
|
|
348
|
+
const mode = parseTestingMode(args.mode);
|
|
349
|
+
if (!mode) {
|
|
350
|
+
return {
|
|
351
|
+
success: false,
|
|
352
|
+
error: `Invalid testing mode ${JSON.stringify(args.mode)}. Supported modes: ${TESTING_MODES.join(", ")}.`,
|
|
353
|
+
supported_modes: TESTING_MODES,
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
this.context.testingMode = mode;
|
|
357
|
+
if (this.context.sessionManager) {
|
|
358
|
+
this.context.sessionManager.updateConfig({
|
|
359
|
+
testingMode: mode,
|
|
360
|
+
baseUrl: args.base_url,
|
|
361
|
+
apiBaseUrl: args.api_base_url,
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
return {
|
|
365
|
+
success: true,
|
|
366
|
+
mode,
|
|
367
|
+
message: `Switched to ${mode} testing mode`,
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
async executeBrowserSession(args) {
|
|
371
|
+
const action = args.action;
|
|
372
|
+
if (!action || !["start", "stop"].includes(action)) {
|
|
373
|
+
return {
|
|
374
|
+
success: false,
|
|
375
|
+
error: "Action must be 'start' or 'stop'",
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
if (action === "start") {
|
|
379
|
+
if (this.context.browserContext?.mcp) {
|
|
380
|
+
return {
|
|
381
|
+
success: false,
|
|
382
|
+
error: "Browser session already started",
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
try {
|
|
386
|
+
if (!this.context.browserContext) {
|
|
387
|
+
this.context.browserContext = {};
|
|
388
|
+
}
|
|
389
|
+
const viewport = args.viewport && typeof args.viewport === "object"
|
|
390
|
+
? args.viewport
|
|
391
|
+
: undefined;
|
|
392
|
+
await UiTools.ensureMcpConnection(this.context.browserContext, {
|
|
393
|
+
viewport,
|
|
394
|
+
});
|
|
395
|
+
// best-effort warm-up navigation, mirroring previous behaviour
|
|
396
|
+
try {
|
|
397
|
+
await UiTools.callMcpTool(this.context.browserContext, "browser_navigate", {
|
|
398
|
+
url: args.start_url || "https://www.google.com",
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
catch {
|
|
402
|
+
// ignore warm-up failures; agent can recover
|
|
403
|
+
}
|
|
404
|
+
return {
|
|
405
|
+
success: true,
|
|
406
|
+
message: "Browser session started via Playwright MCP",
|
|
407
|
+
viewport: viewport ?? { width: 1280, height: 800 },
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
catch (error) {
|
|
411
|
+
await UiTools.closeMcpConnection(this.context.browserContext ?? {});
|
|
412
|
+
return {
|
|
413
|
+
success: false,
|
|
414
|
+
error: `Failed to start browser session: ${error?.message ?? String(error)}`,
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
if (!this.context.browserContext?.mcp) {
|
|
420
|
+
return {
|
|
421
|
+
success: false,
|
|
422
|
+
error: "No browser session to stop",
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
try {
|
|
426
|
+
await UiTools.closeMcpConnection(this.context.browserContext);
|
|
427
|
+
this.context.browserContext = {};
|
|
428
|
+
return {
|
|
429
|
+
success: true,
|
|
430
|
+
message: "Browser session stopped successfully",
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
catch (error) {
|
|
434
|
+
return {
|
|
435
|
+
success: false,
|
|
436
|
+
error: `Failed to stop browser session: ${error?.message ?? String(error)}`,
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
async executeFinish(args) {
|
|
442
|
+
return {
|
|
443
|
+
success: true,
|
|
444
|
+
finished: true,
|
|
445
|
+
summary: args.summary || "Task completed",
|
|
446
|
+
reason: args.reason || "Agent finished task",
|
|
447
|
+
message: "Agent finished task and stopped",
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
async executeFinishOverallTest(args) {
|
|
451
|
+
return finishOverallTest(args.summary);
|
|
452
|
+
}
|
|
453
|
+
async captureScreenshotAfterAction(actionName, existingResult) {
|
|
454
|
+
this.pendingScreenshot = null;
|
|
455
|
+
if (!this.context.browserContext?.mcp) {
|
|
456
|
+
return null;
|
|
457
|
+
}
|
|
458
|
+
const now = Date.now();
|
|
459
|
+
if (!existingResult &&
|
|
460
|
+
now - this.lastScreenshotTime < this.screenshotThrottleMs) {
|
|
461
|
+
return null;
|
|
462
|
+
}
|
|
463
|
+
let callResult = existingResult;
|
|
464
|
+
if (!callResult) {
|
|
465
|
+
try {
|
|
466
|
+
callResult = await UiTools.callMcpTool(this.context.browserContext, "browser_take_screenshot", { type: "jpeg" });
|
|
467
|
+
}
|
|
468
|
+
catch {
|
|
469
|
+
return null;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
if (!callResult.success || callResult.images.length === 0) {
|
|
473
|
+
return null;
|
|
474
|
+
}
|
|
475
|
+
const captureTime = existingResult ? Date.now() : now;
|
|
476
|
+
this.lastScreenshotTime = captureTime;
|
|
477
|
+
const image = callResult.images[0];
|
|
478
|
+
const base64Data = image.data;
|
|
479
|
+
const mimeType = image.mimeType ?? "image/jpeg";
|
|
480
|
+
const buffer = Buffer.from(base64Data, "base64");
|
|
481
|
+
const metadata = this.extractPageMetadata(callResult.sections);
|
|
482
|
+
let uploadResult;
|
|
483
|
+
try {
|
|
484
|
+
uploadResult = await cloudinaryService.uploadScreenshot(base64Data, {
|
|
485
|
+
folder: "cli-screenshots",
|
|
486
|
+
publicId: `screenshot_${actionName}_${captureTime}`,
|
|
487
|
+
quality: this.screenshotQuality,
|
|
488
|
+
mimeType,
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
catch {
|
|
492
|
+
uploadResult = {
|
|
493
|
+
url: `data:${mimeType};base64,${base64Data}`,
|
|
494
|
+
uploaded: false,
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
const imageUrl = uploadResult.url;
|
|
498
|
+
if (this.context.sessionManager) {
|
|
499
|
+
const extension = mimeType.includes("png") ? "png" : "jpg";
|
|
500
|
+
const filename = `screenshot_${actionName}_${captureTime}.${extension}`;
|
|
501
|
+
this.context.sessionManager.saveScreenshot(filename, buffer);
|
|
502
|
+
}
|
|
503
|
+
const screenshotData = {
|
|
504
|
+
base64_data: base64Data,
|
|
505
|
+
image_url: imageUrl,
|
|
506
|
+
mime_type: mimeType,
|
|
507
|
+
page_url: metadata.url,
|
|
508
|
+
page_title: metadata.title,
|
|
509
|
+
action_name: actionName,
|
|
510
|
+
timestamp: captureTime,
|
|
511
|
+
quality: this.screenshotQuality,
|
|
512
|
+
full_page: false,
|
|
513
|
+
cloudinary_uploaded: uploadResult.uploaded,
|
|
514
|
+
};
|
|
515
|
+
this.pendingScreenshot = {
|
|
516
|
+
data: screenshotData,
|
|
517
|
+
action: actionName,
|
|
518
|
+
};
|
|
519
|
+
return screenshotData;
|
|
520
|
+
}
|
|
521
|
+
consumePendingScreenshot() {
|
|
522
|
+
const pending = this.pendingScreenshot;
|
|
523
|
+
this.pendingScreenshot = null;
|
|
524
|
+
return pending;
|
|
525
|
+
}
|
|
526
|
+
ensureMode(required) {
|
|
527
|
+
if (this.context.testingMode !== required) {
|
|
528
|
+
return {
|
|
529
|
+
error: `Tool available only in ${required} mode. Call set_testing_mode first.`,
|
|
530
|
+
current_mode: this.context.testingMode,
|
|
531
|
+
supported_modes: TESTING_MODES,
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
return null;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
//# sourceMappingURL=tool-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-executor.js","sourceRoot":"","sources":["../../../src/lib/tool-executor.ts"],"names":[],"mappings":"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"}
|