@empiricalrun/test-gen 0.58.0 → 0.59.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 (53) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/agent/browsing/run.d.ts +3 -1
  3. package/dist/agent/browsing/run.d.ts.map +1 -1
  4. package/dist/agent/browsing/run.js +23 -25
  5. package/dist/agent/browsing/utils.d.ts +1 -14
  6. package/dist/agent/browsing/utils.d.ts.map +1 -1
  7. package/dist/agent/browsing/utils.js +1 -58
  8. package/dist/agent/chat/agent-loop.d.ts +2 -1
  9. package/dist/agent/chat/agent-loop.d.ts.map +1 -1
  10. package/dist/agent/chat/agent-loop.js +41 -24
  11. package/dist/agent/chat/exports.d.ts +4 -5
  12. package/dist/agent/chat/exports.d.ts.map +1 -1
  13. package/dist/agent/chat/exports.js +12 -42
  14. package/dist/agent/chat/index.d.ts.map +1 -1
  15. package/dist/agent/chat/index.js +10 -4
  16. package/dist/agent/chat/models.d.ts +6 -0
  17. package/dist/agent/chat/models.d.ts.map +1 -0
  18. package/dist/agent/chat/models.js +37 -0
  19. package/dist/agent/chat/prompt.d.ts.map +1 -1
  20. package/dist/agent/chat/prompt.js +37 -8
  21. package/dist/agent/chat/state.d.ts +14 -5
  22. package/dist/agent/chat/state.d.ts.map +1 -1
  23. package/dist/agent/chat/state.js +88 -25
  24. package/dist/agent/chat/types.d.ts +0 -1
  25. package/dist/agent/chat/types.d.ts.map +1 -1
  26. package/dist/agent/master/browser-tests/index.spec.js +6 -6
  27. package/dist/bin/index.js +4 -0
  28. package/dist/bin/utils/index.d.ts +1 -0
  29. package/dist/bin/utils/index.d.ts.map +1 -1
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +3 -0
  33. package/dist/test-build/index.js +1 -1
  34. package/dist/tool-call-service/index.d.ts +2 -1
  35. package/dist/tool-call-service/index.d.ts.map +1 -1
  36. package/dist/tool-call-service/index.js +51 -71
  37. package/dist/tool-call-service/utils.d.ts +10 -0
  38. package/dist/tool-call-service/utils.d.ts.map +1 -0
  39. package/dist/tool-call-service/utils.js +23 -0
  40. package/dist/tools/download-build.d.ts +9 -0
  41. package/dist/tools/download-build.d.ts.map +1 -1
  42. package/dist/tools/download-build.js +5 -4
  43. package/dist/tools/test-gen-browser.d.ts.map +1 -1
  44. package/dist/tools/test-gen-browser.js +8 -13
  45. package/dist/tools/test-run.d.ts.map +1 -1
  46. package/dist/tools/test-run.js +8 -13
  47. package/dist/utils/checkpoint.d.ts.map +1 -1
  48. package/dist/utils/checkpoint.js +3 -1
  49. package/dist/utils/exec.d.ts +2 -2
  50. package/dist/utils/exec.d.ts.map +1 -1
  51. package/dist/utils/exec.js +5 -4
  52. package/package.json +4 -4
  53. package/tsconfig.tsbuildinfo +1 -1
@@ -52,20 +52,49 @@ The position of the comment is important: the browser agent will look for this c
52
52
  the actual code to click on the login button. If you are fixing a failing test, your comment should be
53
53
  around the failing line of code, so that it can be replaced/modified.
54
54
 
55
- # Rules for fixing Playwright tests
55
+ # Proactiveness
56
+
57
+ 1. You are allowed to be proactive, but ONLY for read-only tool calls: like searching for content, reading files, fetching data from tools, and
58
+ running Playwright tests.
59
+ 2. For any read-write tool calls (e.g. modifying any file), you should share your plan and get the user's approval before proceeding.
60
+
61
+ # Rules to follow
56
62
 
57
63
  You must follow these rules while adding new tests or modifying existing tests. There can be exceptions to these rules, but
58
64
  ONLY when explicitly asked for by the user.
59
65
 
60
- 1. Do not add any conditional logic or try catch blocks in a test. A good test deterministically tests a user scenario
61
- 2. Trust Playwright's ability to auto-wait while taking actions on elements. For example, do not add checks on locator.isVisible() before clicking on it: Playwright already does this
62
- 3. Do not add waitForTimeout or waitForLoadState in a test. Playwright will automatically wait for the page to load.
63
- 4. You can't delete some steps from the test to make it pass. The test needs to accomplish its objective (which is to validate a particular user scenario)
66
+ 1. You can't delete some steps from the test to make it pass. The test needs to accomplish its objective (which is to validate a particular user scenario)
67
+ 2. Do not add any conditional logic or try catch blocks in a test. A good test deterministically tests a user scenario
68
+ 3. Trust Playwright's ability to auto-wait while taking actions on elements. For example, do not add checks on locator.isVisible() before clicking on it: Playwright already does this
69
+ 4. Do not add waitForTimeout or waitForLoadState in a test. Playwright will automatically wait for the page to load.
70
+ 5. Try/catch blocks are a code smell for tests: you should not use them.
71
+ 6. Do not use then() or catch() syntax in a test. Use async/await only
64
72
 
65
- # Proactiveness
73
+ There are few exceptions to these rules. BEFORE applying any of the following exceptions, you MUST share your plan with the user and get their approval.
74
+
75
+ ## Exceptions for conditional logic
76
+
77
+ There are few exceptions where you can add conditional logic to a test. If the application UI reveals some UI elements on certain conditions, we can add conditional logic.
66
78
 
67
- You are allowed to be proactive, but ONLY for read-only actions, like searching for content, reading files, fetching data from tools, and
68
- running Playwright tests. For any read-write actions (e.g. modifying any file), you should share your plan and get the user's approval before proceeding.
79
+ For example, a form view shows a "Save" button only when the form is dirty. In this case, we will have to check if the "Save" button is visible before clicking on it. To do this,
80
+ follow this pattern:
81
+
82
+ \`\`\`
83
+ const saveButton = page.getByRole('button', { name: 'Save' });
84
+ if (await saveButton.isVisible()) {
85
+ await saveButton.click();
86
+ }
87
+ \`\`\`
88
+
89
+ Note that locator.isVisible() DOES NOT wait for the element to be visible. If the element in question shows up after a delay, we have no option but to add a waitForTimeout.
90
+
91
+ \`\`\`
92
+ const saveButton = page.getByRole('button', { name: 'Save' });
93
+ await page.waitForTimeout(100); // Wait for the element to be visible -- only if necessary.
94
+ if (await saveButton.isVisible()) {
95
+ await saveButton.click();
96
+ }
97
+ \`\`\`
69
98
 
70
99
  # Repo context
71
100
  ${repoContext}
@@ -1,14 +1,23 @@
1
1
  import { IChatModel, SupportedChatModels } from "@empiricalrun/llm/chat";
2
- export declare const CURRENT_CHAT_STATE_VERSION = "20250327.1";
2
+ import { CanonicalMessage, ChatState } from "@empiricalrun/shared-types";
3
+ export declare const CHAT_STATE_VERSIONS_MIGRATIONS_MAP: Record<string, (state: any) => any>;
4
+ export declare const LATEST_CHAT_STATE_VERSION = "0.1";
3
5
  export declare const CHAT_STATE_PATH: string;
4
6
  export type ChatStateOnDisk<T> = {
5
7
  version: string;
6
8
  model: SupportedChatModels;
7
9
  messages: T[];
10
+ askUserForInput: boolean;
8
11
  };
9
- export declare function createChatState(userPrompt: string, existingState: ChatStateOnDisk<any> | undefined, selectedModel: SupportedChatModels): ChatStateOnDisk<unknown>;
10
- export declare function createChatStateForMessages<T>(messages: any, selectedModel: SupportedChatModels): ChatStateOnDisk<T>;
12
+ export declare function createChatState(userPrompt: string | undefined, existingState: ChatStateOnDisk<any> | undefined, selectedModel: SupportedChatModels): ChatStateOnDisk<unknown>;
13
+ export declare function createChatStateForMessages<T>(messages: any, selectedModel: SupportedChatModels, askUserForInput: boolean): ChatStateOnDisk<T>;
11
14
  export declare function chatStateFromModel<T>(chatModel: IChatModel<T>, selectedModel: SupportedChatModels): ChatStateOnDisk<unknown>;
12
- export declare function loadChatState<T>(): ChatStateOnDisk<T> | undefined;
13
- export declare function saveToDisk<T>(messages: Array<T>, selectedModel: SupportedChatModels): void;
15
+ export declare function loadChatState(): ChatState | undefined;
16
+ /**
17
+ * Migrates a chat state object from an old version to the latest version.
18
+ * Add migration logic for each version as needed.
19
+ */
20
+ export declare function migrateChatState<T = any>(oldState: any): ChatStateOnDisk<T>;
21
+ export declare function saveToDisk<T>(messages: Array<T>, selectedModel: SupportedChatModels, askUserForInput: boolean): void;
22
+ export declare function getLatestDownloadBuildUrl(messages: CanonicalMessage[]): string | null;
14
23
  //# sourceMappingURL=state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,UAAU,EACV,mBAAmB,EACpB,MAAM,wBAAwB,CAAC;AAIhC,eAAO,MAAM,0BAA0B,eAAe,CAAC;AAEvD,eAAO,MAAM,eAAe,QAI3B,CAAC;AAEF,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,mBAAmB,CAAC;IAC3B,QAAQ,EAAE,CAAC,EAAE,CAAC;CACf,CAAC;AAEF,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,eAAe,CAAC,GAAG,CAAC,GAAG,SAAS,EAC/C,aAAa,EAAE,mBAAmB,4BAMnC;AAED,wBAAgB,0BAA0B,CAAC,CAAC,EAC1C,QAAQ,EAAE,GAAG,EACb,aAAa,EAAE,mBAAmB,GACjC,eAAe,CAAC,CAAC,CAAC,CAOpB;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,EACxB,aAAa,EAAE,mBAAmB,4BAGnC;AAED,wBAAgB,aAAa,CAAC,CAAC,KAAK,eAAe,CAAC,CAAC,CAAC,GAAG,SAAS,CAajE;AAED,wBAAgB,UAAU,CAAC,CAAC,EAC1B,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,EAClB,aAAa,EAAE,mBAAmB,QAsBnC"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,UAAU,EACV,mBAAmB,EACpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AA+BzE,eAAO,MAAM,kCAAkC,EAAE,MAAM,CACrD,MAAM,EACN,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAIpB,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAAQ,CAAC;AAE/C,eAAO,MAAM,eAAe,QAI3B,CAAC;AAEF,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,mBAAmB,CAAC;IAC3B,QAAQ,EAAE,CAAC,EAAE,CAAC;IACd,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,aAAa,EAAE,eAAe,CAAC,GAAG,CAAC,GAAG,SAAS,EAC/C,aAAa,EAAE,mBAAmB,4BAYnC;AAED,wBAAgB,0BAA0B,CAAC,CAAC,EAC1C,QAAQ,EAAE,GAAG,EACb,aAAa,EAAE,mBAAmB,EAClC,eAAe,EAAE,OAAO,GACvB,eAAe,CAAC,CAAC,CAAC,CAQpB;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,EACxB,aAAa,EAAE,mBAAmB,4BAOnC;AAED,wBAAgB,aAAa,IAAI,SAAS,GAAG,SAAS,CAarD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,GAAG,GAAG,EAAE,QAAQ,EAAE,GAAG,GAAG,eAAe,CAAC,CAAC,CAAC,CAqB3E;AAED,wBAAgB,UAAU,CAAC,CAAC,EAC1B,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,EAClB,aAAa,EAAE,mBAAmB,EAClC,eAAe,EAAE,OAAO,QAezB;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,gBAAgB,EAAE,GAC3B,MAAM,GAAG,IAAI,CAqBf"}
@@ -3,64 +3,127 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.CHAT_STATE_PATH = exports.CURRENT_CHAT_STATE_VERSION = void 0;
6
+ exports.CHAT_STATE_PATH = exports.LATEST_CHAT_STATE_VERSION = exports.CHAT_STATE_VERSIONS_MIGRATIONS_MAP = void 0;
7
7
  exports.createChatState = createChatState;
8
8
  exports.createChatStateForMessages = createChatStateForMessages;
9
9
  exports.chatStateFromModel = chatStateFromModel;
10
10
  exports.loadChatState = loadChatState;
11
+ exports.migrateChatState = migrateChatState;
11
12
  exports.saveToDisk = saveToDisk;
13
+ exports.getLatestDownloadBuildUrl = getLatestDownloadBuildUrl;
12
14
  const chat_1 = require("@empiricalrun/llm/chat");
13
15
  const fs_1 = __importDefault(require("fs"));
14
16
  const path_1 = __importDefault(require("path"));
15
- exports.CURRENT_CHAT_STATE_VERSION = "20250327.1";
17
+ // Migration wrapper for v20250327.1 -> v0.1 chat state versions
18
+ // v20250327.1 was model-specific, but v0.1 is canonical
19
+ function migrateToV01(oldState) {
20
+ if (oldState.model &&
21
+ typeof oldState.model === "string" &&
22
+ Array.isArray(oldState.messages)) {
23
+ const provider = (0, chat_1.getProviderForModel)(oldState.model);
24
+ if (provider === "google") {
25
+ return {
26
+ ...oldState,
27
+ version: "0.1",
28
+ messages: oldState.messages.map(chat_1.geminiToCanonical),
29
+ };
30
+ }
31
+ else {
32
+ throw new Error(`Unsupported state for migration with model: ${oldState.model} and version: ${oldState.version}`);
33
+ }
34
+ }
35
+ // If not Gemini or not matching, return the old state
36
+ return oldState;
37
+ }
38
+ exports.CHAT_STATE_VERSIONS_MIGRATIONS_MAP = {
39
+ "20250327.1": migrateToV01,
40
+ "0.1": (state) => state,
41
+ };
42
+ exports.LATEST_CHAT_STATE_VERSION = "0.1";
16
43
  exports.CHAT_STATE_PATH = path_1.default.join(process.cwd(), ".empiricalrun", "last-chat.json");
17
44
  function createChatState(userPrompt, existingState, selectedModel) {
18
45
  const messages = existingState?.messages || [];
19
46
  const chatModel = (0, chat_1.createChatModel)(messages, selectedModel);
20
- chatModel.pushUserMessage(userPrompt);
21
- return createChatStateForMessages(chatModel.messages, selectedModel);
47
+ if (userPrompt) {
48
+ chatModel.pushUserMessage(userPrompt);
49
+ }
50
+ return createChatStateForMessages(chatModel.messages, selectedModel, chatModel.askUserForInput);
22
51
  }
23
- function createChatStateForMessages(messages, selectedModel) {
52
+ function createChatStateForMessages(messages, selectedModel, askUserForInput) {
24
53
  // TODO: Add better types for messages
25
54
  return {
26
- version: exports.CURRENT_CHAT_STATE_VERSION,
55
+ version: exports.LATEST_CHAT_STATE_VERSION,
27
56
  model: selectedModel,
28
57
  messages: messages,
58
+ askUserForInput: askUserForInput,
29
59
  };
30
60
  }
31
61
  function chatStateFromModel(chatModel, selectedModel) {
32
- return createChatStateForMessages(chatModel.messages, selectedModel);
62
+ return createChatStateForMessages(chatModel.messages, selectedModel, chatModel.askUserForInput);
33
63
  }
34
64
  function loadChatState() {
35
65
  if (!fs_1.default.existsSync(exports.CHAT_STATE_PATH)) {
36
66
  return undefined;
37
67
  }
38
68
  const raw = fs_1.default.readFileSync(exports.CHAT_STATE_PATH, "utf8");
39
- const state = JSON.parse(raw);
40
- if (state.version !== exports.CURRENT_CHAT_STATE_VERSION) {
41
- throw new Error(`Unsupported chat state v${state.version}. Expected v${exports.CURRENT_CHAT_STATE_VERSION}.`);
69
+ let state = JSON.parse(raw);
70
+ // Always migrate to the latest version after loading
71
+ const migratedState = migrateChatState(state);
72
+ // Only save if migration actually changed the state
73
+ if (JSON.stringify(state) !== JSON.stringify(migratedState)) {
74
+ fs_1.default.writeFileSync(exports.CHAT_STATE_PATH, JSON.stringify(migratedState, null, 2));
42
75
  }
43
- return state;
76
+ return migratedState;
44
77
  }
45
- function saveToDisk(messages, selectedModel) {
46
- const statePath = exports.CHAT_STATE_PATH;
47
- let existingState = {
48
- version: exports.CURRENT_CHAT_STATE_VERSION,
49
- model: selectedModel,
50
- messages: [],
78
+ /**
79
+ * Migrates a chat state object from an old version to the latest version.
80
+ * Add migration logic for each version as needed.
81
+ */
82
+ function migrateChatState(oldState) {
83
+ if (!oldState || Object.keys(oldState).length === 0) {
84
+ return oldState;
85
+ }
86
+ if (!oldState.version) {
87
+ throw new Error("No version found in chat state");
88
+ }
89
+ if (!exports.CHAT_STATE_VERSIONS_MIGRATIONS_MAP[oldState.version]) {
90
+ throw new Error(`No migration function found for version: ${oldState.version}`);
91
+ }
92
+ if (oldState.version === exports.LATEST_CHAT_STATE_VERSION) {
93
+ return oldState;
94
+ }
95
+ const migrateFn = exports.CHAT_STATE_VERSIONS_MIGRATIONS_MAP[oldState.version];
96
+ const migrated = migrateFn(oldState);
97
+ return {
98
+ version: exports.LATEST_CHAT_STATE_VERSION,
99
+ ...migrated,
51
100
  };
101
+ }
102
+ function saveToDisk(messages, selectedModel, askUserForInput) {
103
+ const statePath = exports.CHAT_STATE_PATH;
52
104
  // Ensure directory exists before trying to read/write
53
105
  const dirname = path_1.default.dirname(statePath);
54
106
  if (!fs_1.default.existsSync(dirname)) {
55
107
  fs_1.default.mkdirSync(dirname, { recursive: true });
56
108
  }
57
- if (fs_1.default.existsSync(statePath)) {
58
- existingState = JSON.parse(fs_1.default.readFileSync(statePath, "utf8"));
59
- }
60
- const newState = {
61
- ...existingState,
62
- messages: messages,
63
- model: selectedModel,
64
- };
109
+ // Use the helper to build the new state
110
+ const newState = createChatStateForMessages(messages, selectedModel, askUserForInput);
65
111
  fs_1.default.writeFileSync(statePath, JSON.stringify(newState, null, 2));
66
112
  }
113
+ function getLatestDownloadBuildUrl(messages) {
114
+ const toolCallMessage = messages
115
+ .sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())
116
+ .find((p) => p.parts.find((p) => {
117
+ if ("toolCall" in p) {
118
+ return p.toolCall?.name === "downloadBuild";
119
+ }
120
+ return false;
121
+ }));
122
+ if (!toolCallMessage)
123
+ return null;
124
+ const toolCallPart = toolCallMessage.parts.find((p) => "toolCall" in p && p.toolCall?.name === "downloadBuild");
125
+ if (!toolCallPart || !("toolCall" in toolCallPart))
126
+ return null;
127
+ const input = toolCallPart.toolCall.input;
128
+ return input.buildUrl;
129
+ }
@@ -1,5 +1,4 @@
1
1
  import { ChatStateOnDisk } from "./state";
2
- export type SupportedChatModels = "claude-3-7-sonnet-20250219" | "claude-3-5-sonnet-20241022" | "gemini-2.5-pro-preview-03-25" | "o4-mini-2025-04-16";
3
2
  type LatestMessage = {
4
3
  role: string;
5
4
  textMessage: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,MAAM,MAAM,mBAAmB,GAC3B,4BAA4B,GAC5B,4BAA4B,GAC5B,8BAA8B,GAC9B,oBAAoB,CAAC;AAEzB,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAC7B,KAAK,EAAE,eAAe,CAAC,GAAG,CAAC,EAC3B,0BAA0B,EAAE,aAAa,GAAG,SAAS,KAClD,OAAO,CAAC,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAC7B,KAAK,EAAE,eAAe,CAAC,GAAG,CAAC,EAC3B,0BAA0B,EAAE,aAAa,GAAG,SAAS,KAClD,OAAO,CAAC,IAAI,CAAC,CAAC"}
@@ -9,7 +9,7 @@ const utils_1 = require("../../browsing/utils");
9
9
  const element_annotation_1 = require("../element-annotation");
10
10
  const run_1 = require("../run");
11
11
  const fixtures_1 = require("./fixtures");
12
- (0, fixtures_1.test)("able to scroll and interact with elements", async ({ page, server }) => {
12
+ fixtures_1.test.skip("able to scroll and interact with elements", async ({ page, server, }) => {
13
13
  await page.goto(`${server.baseURL}/blog-page.html`);
14
14
  const response = await (0, run_1.createTestUsingMasterAgent)({
15
15
  task: `fill test@test.com into the email field and click the submit`,
@@ -21,7 +21,7 @@ const fixtures_1 = require("./fixtures");
21
21
  (0, fixtures_1.expect)(response.code).toContain("await page.getByPlaceholder('Enter your email').fill(\"test@test.com\")");
22
22
  (0, fixtures_1.expect)(response.code).toContain("await page.getByRole('button', { name: 'Subscribe' }).click()");
23
23
  });
24
- (0, fixtures_1.test)("scroll when element does not exist", async ({ page, server }) => {
24
+ fixtures_1.test.skip("scroll when element does not exist", async ({ page, server }) => {
25
25
  await page.goto(`${server.baseURL}/blog-page.html`);
26
26
  const response = await (0, run_1.createTestUsingMasterAgent)({
27
27
  task: `click search button`,
@@ -32,7 +32,7 @@ const fixtures_1 = require("./fixtures");
32
32
  (0, fixtures_1.expect)(response.importPaths.length).toBe(0);
33
33
  (0, fixtures_1.expect)(response.code.length).toBe(0);
34
34
  });
35
- (0, fixtures_1.test)("scroll and click inside div elements", async ({ page, server }) => {
35
+ fixtures_1.test.skip("scroll and click inside div elements", async ({ page, server }) => {
36
36
  await page.goto(`${server.baseURL}/dropdown-scrolls.html`);
37
37
  const response = await (0, run_1.createTestUsingMasterAgent)({
38
38
  task: `click on x-3 inside bmw dropdown, and then,
@@ -49,7 +49,7 @@ click on maverick inside ford dropdown`,
49
49
  (0, fixtures_1.expect)(lines.find((l) => l.match(/^await page.+Ford.+.click/))).toBeTruthy();
50
50
  (0, fixtures_1.expect)(lines.find((l) => l.match(/^await page.+Maverick.+.click/))).toBeTruthy();
51
51
  });
52
- (0, fixtures_1.test)("master agent can click icons accurately", async ({ page, server }) => {
52
+ fixtures_1.test.skip("master agent can click icons accurately", async ({ page, server, }) => {
53
53
  await page.goto(`${server.baseURL}/icons-navbar.html`);
54
54
  await (0, fixtures_1.expect)(page.getByText("select an icon")).toBeVisible();
55
55
  const response = await (0, run_1.createTestUsingMasterAgent)({
@@ -86,7 +86,7 @@ click on maverick inside ford dropdown`,
86
86
  (0, fixtures_1.expect)(response.code).toContain("page.locator");
87
87
  (0, fixtures_1.expect)(response.code).toContain("click()");
88
88
  });
89
- (0, fixtures_1.test)("annotate and enrich annotations correctly", async ({ page, server }) => {
89
+ fixtures_1.test.skip("annotate and enrich annotations correctly", async ({ page, server, }) => {
90
90
  await (0, utils_1.injectPwLocatorGenerator)(page);
91
91
  await page.goto(`${server.baseURL}/iframe-elements.html`);
92
92
  const { annotationKeys: keys } = await (0, element_annotation_1.getAnnotationKeys)({
@@ -105,7 +105,7 @@ click on maverick inside ford dropdown`,
105
105
  // 2 clickable divs: 1 in main frame, 1 in iframe
106
106
  (0, fixtures_1.expect)(keys.filter((k) => k.text.includes("Lorem Ipsum")).length).toBe(2);
107
107
  });
108
- (0, fixtures_1.test)("fill action with multiple pages", async ({ context }) => {
108
+ fixtures_1.test.skip("fill action with multiple pages", async ({ context }) => {
109
109
  const page1 = await context.newPage();
110
110
  const page2 = await context.newPage();
111
111
  const response = await (0, run_1.createTestUsingMasterAgent)({
package/dist/bin/index.js CHANGED
@@ -185,6 +185,8 @@ async function runAgentsWorkflow(testGenConfig, testGenToken) {
185
185
  status: "agent_live_session_started",
186
186
  });
187
187
  const { isError, error } = await (0, run_1.generateTestsUsingMasterAgent)({
188
+ testCaseName: testCase.name,
189
+ testCaseSuites: testCase.suites,
188
190
  testFilePath: specPath,
189
191
  filePathToUpdate,
190
192
  pwProjectsFilter: testGenConfig.environment?.playwrightProjects,
@@ -213,6 +215,7 @@ async function main() {
213
215
  .option("--use-disk-for-chat-state", "Save and load chat state from disk")
214
216
  .option("--chat-model <model>", "Chat model to use (claude-3-7-sonnet-20250219 or claude-3-5-sonnet-20241022 or gemini-2.5-pro-preview-03-25)")
215
217
  .option("--initial-prompt <path>", "Path to an initial prompt file (e.g. prompt.md)")
218
+ .option("--use-transform", "Use the new message transform strategy")
216
219
  .parse(process.argv);
217
220
  const options = program.opts();
218
221
  const completedOptions = await (0, utils_2.validateAndCompleteCliOptions)(options);
@@ -243,6 +246,7 @@ async function main() {
243
246
  modelInput: completedOptions.chatModel,
244
247
  useDiskForChatState: completedOptions.useDiskForChatState,
245
248
  initialPromptPath: completedOptions.initialPrompt,
249
+ useTransform: completedOptions.useTransform,
246
250
  });
247
251
  return;
248
252
  }
@@ -9,6 +9,7 @@ export interface CliOptions {
9
9
  initialPrompt?: string;
10
10
  chatSessionId?: string;
11
11
  chatModel?: "claude-3-7" | "claude-3-5" | "claude-3-7-sonnet-20250219" | "claude-3-5-sonnet-20241022" | "gemini-2.5-pro" | "gemini-2.5-pro-preview-03-25" | "o4-mini" | "o4-mini-2025-04-16";
12
+ useTransform?: boolean;
12
13
  }
13
14
  export declare function validateAndCompleteCliOptions(options: CliOptions): Promise<CliOptions>;
14
15
  export declare function printBanner(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bin/utils/index.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EACN,YAAY,GACZ,YAAY,GACZ,4BAA4B,GAC5B,4BAA4B,GAC5B,gBAAgB,GAChB,8BAA8B,GAC9B,SAAS,GACT,oBAAoB,CAAC;CAC1B;AAQD,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,UAAU,CAAC,CAyDrB;AAED,wBAAgB,WAAW,SAgC1B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bin/utils/index.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EACN,YAAY,GACZ,YAAY,GACZ,4BAA4B,GAC5B,4BAA4B,GAC5B,gBAAgB,GAChB,8BAA8B,GAC9B,SAAS,GACT,oBAAoB,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAQD,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,UAAU,CAAC,CAyDrB;AAED,wBAAgB,WAAW,SAgC1B"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { FrameLocator, Page } from "playwright";
2
2
  import { ScopeVars } from "./types";
3
+ export { downloadBuild } from "./test-build";
3
4
  export declare function createTest(task: string, pageRef: Page | FrameLocator, scope?: ScopeVars): Promise<void>;
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAQhD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAoBpC,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,IAAI,GAAG,YAAY,EAC5B,KAAK,CAAC,EAAE,SAAS,iBA0ElB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAQhD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAoB7C,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,IAAI,GAAG,YAAY,EAC5B,KAAK,CAAC,EAAE,SAAS,iBA0ElB"}
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.downloadBuild = void 0;
6
7
  exports.createTest = createTest;
7
8
  const llm_1 = require("@empiricalrun/llm");
8
9
  const cua_1 = require("./agent/cua");
@@ -11,6 +12,8 @@ const scenarios_1 = require("./bin/utils/scenarios");
11
12
  const client_1 = __importDefault(require("./file/client"));
12
13
  const reporter_1 = require("./reporter");
13
14
  const session_1 = require("./session");
15
+ var test_build_1 = require("./test-build");
16
+ Object.defineProperty(exports, "downloadBuild", { enumerable: true, get: function () { return test_build_1.downloadBuild; } });
14
17
  const flushEvents = async () => {
15
18
  await (0, llm_1.flushAllTraces)();
16
19
  };
@@ -23,7 +23,7 @@ async function downloadBuild(buildUrl) {
23
23
  const buildDownloadScript = packageJSON.scripts["download"];
24
24
  if (buildDownloadScript && buildUrl) {
25
25
  logger.log(`Downloading build from ${buildUrl}`);
26
- await (0, exec_1.cmd)(`npm run download ${buildUrl}`.split(" "), {
26
+ await (0, exec_1.cmd)(`npm`, ["run", "download", buildUrl], {
27
27
  env: { ...Object(process.env) },
28
28
  });
29
29
  }
@@ -14,6 +14,7 @@ export declare class ToolCallService {
14
14
  getTools(): Promise<{
15
15
  tools: Tool[];
16
16
  }>;
17
- execute(toolCalls: PendingToolCall[], isRemote: boolean, trace?: TraceClient): Promise<ToolResult[]>;
17
+ sendToQueue(toolCalls: PendingToolCall[]): Promise<void>;
18
+ execute(toolCalls: PendingToolCall[], trace?: TraceClient): Promise<ToolResult[]>;
18
19
  }
19
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tool-call-service/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,IAAI,EACJ,UAAU,EACX,MAAM,wBAAwB,CAAC;AAgBhC,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC,KAAK,aAAa,GAAG;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;CACzE,CAAC;AA6BF,qBAAa,eAAe;IAC1B,KAAK,EAAE,IAAI,EAAE,CAAM;IACnB,aAAa,EAAE,aAAa,CAAM;IAClC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,mBAAmB,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;gBAEjB,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,aAAa,EAAE,mBAAmB,EAClC,UAAU,EAAE,MAAM;IAiBd,QAAQ;;;IAaR,OAAO,CACX,SAAS,EAAE,eAAe,EAAE,EAC5B,QAAQ,EAAE,OAAO,EACjB,KAAK,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,UAAU,EAAE,CAAC;CAyDzB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tool-call-service/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAEL,eAAe,EACf,mBAAmB,EACnB,IAAI,EACJ,UAAU,EACX,MAAM,wBAAwB,CAAC;AAiBhC,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC,KAAK,aAAa,GAAG;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;CACzE,CAAC;AAEF,qBAAa,eAAe;IAC1B,KAAK,EAAE,IAAI,EAAE,CAAM;IACnB,aAAa,EAAE,aAAa,CAAM;IAClC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,mBAAmB,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;gBAEjB,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,aAAa,EAAE,mBAAmB,EAClC,UAAU,EAAE,MAAM;IAiBd,QAAQ;;;IAaR,WAAW,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAcxD,OAAO,CACX,SAAS,EAAE,eAAe,EAAE,EAC5B,KAAK,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,UAAU,EAAE,CAAC;CA2CzB"}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ToolCallService = void 0;
4
- const client_sqs_1 = require("@aws-sdk/client-sqs");
4
+ const chat_1 = require("@empiricalrun/llm/chat");
5
5
  const commit_and_create_pr_1 = require("../tools/commit-and-create-pr");
6
6
  const diagnosis_fetcher_1 = require("../tools/diagnosis-fetcher");
7
7
  const download_build_1 = require("../tools/download-build");
@@ -12,25 +12,7 @@ const test_gen_browser_1 = require("../tools/test-gen-browser");
12
12
  const test_run_1 = require("../tools/test-run");
13
13
  const test_run_fetcher_1 = require("../tools/test-run-fetcher");
14
14
  const checkpoint_1 = require("../utils/checkpoint");
15
- async function sendToolRequestToRemoteQueue(payload) {
16
- const sqs = new client_sqs_1.SQSClient({
17
- region: process.env.AWS_REGION,
18
- credentials: {
19
- accessKeyId: process.env.AWS_ACCESS_KEY_ID,
20
- secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
21
- },
22
- });
23
- const queueUrl = process.env.TOOL_EXECUTION_SQS_URL;
24
- if (!queueUrl) {
25
- throw new Error("TOOL_EXECUTION_SQS_URL is required for remote execution.");
26
- }
27
- await sqs.send(new client_sqs_1.SendMessageCommand({
28
- QueueUrl: queueUrl,
29
- MessageBody: JSON.stringify(payload),
30
- MessageGroupId: payload.requestId,
31
- MessageDeduplicationId: payload.requestId, // unique id for the tool request
32
- }));
33
- }
15
+ const utils_1 = require("./utils");
34
16
  class ToolCallService {
35
17
  tools = [];
36
18
  toolExecutors = {};
@@ -53,70 +35,68 @@ class ToolCallService {
53
35
  ];
54
36
  }
55
37
  async getTools() {
56
- if (!this.selectedModel.startsWith("claude")) {
38
+ if ((0, chat_1.getProviderForModel)(this.selectedModel) !== "claude") {
57
39
  this.tools.push(...str_replace_editor_1.textEditorTools);
58
40
  }
59
41
  this.tools.forEach((tool) => {
60
42
  this.toolExecutors[tool.schema.name] = tool.execute;
61
43
  });
62
- if (this.selectedModel.startsWith("claude")) {
44
+ if ((0, chat_1.getProviderForModel)(this.selectedModel) === "claude") {
63
45
  this.toolExecutors["str_replace_editor"] = str_replace_editor_1.strReplaceEditorExecutor;
64
46
  }
65
47
  return { tools: this.tools };
66
48
  }
67
- async execute(toolCalls, isRemote, trace) {
68
- if (isRemote && this.chatSessionId) {
69
- await sendToolRequestToRemoteQueue({
70
- toolCalls,
71
- requestId: crypto.randomUUID(),
72
- chatSessionId: this.chatSessionId,
73
- selectedModel: this.selectedModel,
74
- branchName: this.branchName,
75
- });
76
- return toolCalls.map(() => ({
77
- isError: false,
78
- result: `Tool request sent to remote queue to execute.`,
79
- }));
49
+ async sendToQueue(toolCalls) {
50
+ const requestId = toolCalls[0]?.id;
51
+ if (!requestId) {
52
+ throw new Error("Could not find an id for the tool call.");
80
53
  }
81
- else {
82
- const executeSpan = trace?.span({
83
- name: "execute_tools",
84
- input: { toolCalls: toolCalls.map((tc) => ({ name: tc.name })) },
54
+ await (0, utils_1.sendToolRequestToRemoteQueue)({
55
+ toolCalls,
56
+ requestId,
57
+ chatSessionId: this.chatSessionId,
58
+ selectedModel: this.selectedModel,
59
+ branchName: this.branchName,
60
+ });
61
+ }
62
+ async execute(toolCalls, trace) {
63
+ const executeSpan = trace?.span({
64
+ name: "execute_tools",
65
+ input: { toolCalls: toolCalls.map((tc) => ({ name: tc.name })) },
66
+ });
67
+ const toolResults = [];
68
+ for (const toolCall of toolCalls) {
69
+ const span = executeSpan?.span({
70
+ name: `tool: ${toolCall.name}`,
71
+ input: toolCall.input,
85
72
  });
86
- const toolResults = [];
87
- for (const toolCall of toolCalls) {
88
- const span = executeSpan?.span({
89
- name: `tool: ${toolCall.name}`,
90
- input: toolCall.input,
91
- });
92
- const toolExecutor = this.toolExecutors[toolCall.name];
93
- if (!toolExecutor) {
94
- const errorResult = {
95
- isError: true,
96
- result: `Invalid function/tool call: invalid_tool_call not found`,
97
- };
98
- toolResults.push(errorResult);
99
- span?.end({ output: errorResult });
100
- continue;
101
- }
102
- try {
103
- const result = await toolExecutor(toolCall.input, trace);
104
- toolResults.push(result);
105
- span?.end({ output: result });
106
- }
107
- catch (error) {
108
- const errorResult = {
109
- isError: true,
110
- result: error instanceof Error ? error.message : String(error),
111
- };
112
- toolResults.push(errorResult);
113
- span?.end({ output: errorResult });
114
- }
73
+ const toolExecutor = this.toolExecutors[toolCall.name];
74
+ if (!toolExecutor) {
75
+ const errorResult = {
76
+ isError: true,
77
+ result: `Invalid function/tool call: ${toolCall.name} not found`,
78
+ };
79
+ toolResults.push(errorResult);
80
+ span?.end({ output: errorResult });
81
+ continue;
82
+ }
83
+ try {
84
+ const result = await toolExecutor(toolCall.input, trace);
85
+ toolResults.push(result);
86
+ span?.end({ output: result });
87
+ }
88
+ catch (error) {
89
+ const errorResult = {
90
+ isError: true,
91
+ result: error instanceof Error ? error.message : String(error),
92
+ };
93
+ toolResults.push(errorResult);
94
+ span?.end({ output: errorResult });
115
95
  }
116
- await (0, checkpoint_1.createCheckpoint)(toolCalls, this.branchName);
117
- executeSpan?.end({ output: { toolResults } });
118
- return toolResults;
119
96
  }
97
+ await (0, checkpoint_1.createCheckpoint)(toolCalls, this.branchName);
98
+ executeSpan?.end({ output: { toolResults } });
99
+ return toolResults;
120
100
  }
121
101
  }
122
102
  exports.ToolCallService = ToolCallService;
@@ -0,0 +1,10 @@
1
+ import { SupportedChatModels } from "@empiricalrun/llm/chat";
2
+ import { PendingToolCall } from "@empiricalrun/shared-types";
3
+ export declare function sendToolRequestToRemoteQueue(payload: {
4
+ toolCalls: PendingToolCall[];
5
+ requestId: string;
6
+ chatSessionId: number;
7
+ selectedModel: SupportedChatModels;
8
+ branchName: string;
9
+ }): Promise<void>;
10
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/tool-call-service/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,wBAAsB,4BAA4B,CAAC,OAAO,EAAE;IAC1D,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,mBAAmB,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;CACpB,iBAoBA"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sendToolRequestToRemoteQueue = sendToolRequestToRemoteQueue;
4
+ const client_sqs_1 = require("@aws-sdk/client-sqs");
5
+ async function sendToolRequestToRemoteQueue(payload) {
6
+ const sqs = new client_sqs_1.SQSClient({
7
+ region: process.env.AWS_REGION,
8
+ credentials: {
9
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID,
10
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
11
+ },
12
+ });
13
+ const queueUrl = process.env.TOOL_EXECUTION_SQS_URL;
14
+ if (!queueUrl) {
15
+ throw new Error("TOOL_EXECUTION_SQS_URL is required for remote execution.");
16
+ }
17
+ await sqs.send(new client_sqs_1.SendMessageCommand({
18
+ QueueUrl: queueUrl,
19
+ MessageBody: JSON.stringify(payload),
20
+ MessageGroupId: payload.requestId,
21
+ MessageDeduplicationId: payload.requestId, // unique id for the tool request
22
+ }));
23
+ }
@@ -1,3 +1,12 @@
1
1
  import type { Tool } from "@empiricalrun/llm/chat";
2
+ import { z } from "zod";
3
+ export declare const downloadBuildToolSchema: z.ZodObject<{
4
+ buildUrl: z.ZodString;
5
+ }, "strip", z.ZodTypeAny, {
6
+ buildUrl: string;
7
+ }, {
8
+ buildUrl: string;
9
+ }>;
10
+ export type DownloadBuildToolInput = z.infer<typeof downloadBuildToolSchema>;
2
11
  export declare const downloadBuildTool: Tool;
3
12
  //# sourceMappingURL=download-build.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"download-build.d.ts","sourceRoot":"","sources":["../../src/tools/download-build.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAKnD,eAAO,MAAM,iBAAiB,EAAE,IAkC/B,CAAC"}
1
+ {"version":3,"file":"download-build.d.ts","sourceRoot":"","sources":["../../src/tools/download-build.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,uBAAuB;;;;;;EAElC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAE7E,eAAO,MAAM,iBAAiB,EAAE,IA8B/B,CAAC"}