@empiricalrun/test-gen 0.63.0 → 0.64.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 (71) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist/agent/browsing/run.d.ts +2 -1
  3. package/dist/agent/browsing/run.d.ts.map +1 -1
  4. package/dist/agent/browsing/run.js +25 -12
  5. package/dist/agent/browsing/utils.d.ts +1 -1
  6. package/dist/agent/browsing/utils.d.ts.map +1 -1
  7. package/dist/agent/browsing/utils.js +5 -4
  8. package/dist/agent/chat/index.d.ts.map +1 -1
  9. package/dist/agent/chat/index.js +2 -0
  10. package/dist/agent/chat/models.js +1 -1
  11. package/dist/agent/cua/computer.d.ts.map +1 -1
  12. package/dist/agent/cua/computer.js +45 -24
  13. package/dist/agent/cua/pw-codegen/element-from-point.d.ts +3 -1
  14. package/dist/agent/cua/pw-codegen/element-from-point.d.ts.map +1 -1
  15. package/dist/agent/cua/pw-codegen/element-from-point.js +73 -56
  16. package/dist/agent/cua/pw-codegen/types.d.ts +2 -1
  17. package/dist/agent/cua/pw-codegen/types.d.ts.map +1 -1
  18. package/dist/artifacts/utils.d.ts +21 -0
  19. package/dist/artifacts/utils.d.ts.map +1 -0
  20. package/dist/artifacts/utils.js +102 -0
  21. package/dist/bin/index.js +2 -1
  22. package/dist/bin/utils/platform/web/index.d.ts.map +1 -1
  23. package/dist/bin/utils/platform/web/index.js +2 -0
  24. package/dist/file/server.js +1 -1
  25. package/dist/test-build/index.js +1 -1
  26. package/dist/tool-call-service/index.d.ts +5 -2
  27. package/dist/tool-call-service/index.d.ts.map +1 -1
  28. package/dist/tool-call-service/index.js +11 -2
  29. package/dist/tool-call-service/utils.d.ts +1 -0
  30. package/dist/tool-call-service/utils.d.ts.map +1 -1
  31. package/dist/tool-call-service/utils.js +6 -2
  32. package/dist/tools/commit-and-create-pr.d.ts +1 -1
  33. package/dist/tools/commit-and-create-pr.d.ts.map +1 -1
  34. package/dist/tools/commit-and-create-pr.js +1 -1
  35. package/dist/tools/diagnosis-fetcher.d.ts +1 -1
  36. package/dist/tools/diagnosis-fetcher.d.ts.map +1 -1
  37. package/dist/tools/diagnosis-fetcher.js +1 -1
  38. package/dist/tools/download-build.d.ts +1 -1
  39. package/dist/tools/download-build.d.ts.map +1 -1
  40. package/dist/tools/download-build.js +1 -1
  41. package/dist/tools/environment-crud.d.ts +1 -1
  42. package/dist/tools/environment-crud.d.ts.map +1 -1
  43. package/dist/tools/environment-crud.js +1 -1
  44. package/dist/tools/grep/index.d.ts +1 -1
  45. package/dist/tools/grep/index.d.ts.map +1 -1
  46. package/dist/tools/grep/index.js +4 -3
  47. package/dist/tools/str_replace_editor.d.ts +5 -7
  48. package/dist/tools/str_replace_editor.d.ts.map +1 -1
  49. package/dist/tools/str_replace_editor.js +259 -247
  50. package/dist/tools/test-gen-browser.d.ts +1 -1
  51. package/dist/tools/test-gen-browser.d.ts.map +1 -1
  52. package/dist/tools/test-gen-browser.js +45 -20
  53. package/dist/tools/test-run-fetcher/index.d.ts +1 -1
  54. package/dist/tools/test-run-fetcher/index.d.ts.map +1 -1
  55. package/dist/tools/test-run-fetcher/index.js +1 -1
  56. package/dist/tools/test-run.d.ts +1 -1
  57. package/dist/tools/test-run.d.ts.map +1 -1
  58. package/dist/tools/test-run.js +35 -12
  59. package/dist/tools/utils/index.d.ts +0 -13
  60. package/dist/tools/utils/index.d.ts.map +1 -1
  61. package/dist/tools/utils/index.js +0 -47
  62. package/dist/utils/exec.d.ts +4 -4
  63. package/dist/utils/exec.d.ts.map +1 -1
  64. package/dist/utils/exec.js +2 -4
  65. package/dist/utils/file-tree.d.ts.map +1 -1
  66. package/dist/utils/file-tree.js +2 -0
  67. package/package.json +4 -4
  68. package/tsconfig.tsbuildinfo +1 -1
  69. package/dist/tools/codegen-agent.d.ts +0 -3
  70. package/dist/tools/codegen-agent.d.ts.map +0 -1
  71. package/dist/tools/codegen-agent.js +0 -40
package/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # @empiricalrun/test-gen
2
2
 
3
+ ## 0.64.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 387f475: chore: move more types to shared-types package
8
+ - 39f1aa8: fix: add exception handling to codegen
9
+ - 09a1126: [WIP] refactor: process manager to have strict options to avoid failure due…
10
+ - 1f74b60: fix: clarify how file create tool can create directories
11
+ - e5f8110: fix: ripgrep should work with ampersand in query
12
+ - b39d75c: feat: add build url to some tools, to run tests on preview urls
13
+ - 99d8490: fix: override page screenshot to fix cua on mobile emulation
14
+ - 226c361: fix: validate file existence in text edit tools, browser agent and run test tool and update fileName to filePath
15
+ - 41fc766: feat: collect artifacts after process end, add fallback for actionSummary
16
+ - d00c867: fix: add test for artifact extraction function and fix the bug
17
+ - d018e6b: chore: change default model to claude sonnet 4
18
+ - b908890: feat: added useToolExecutionOnEcs feature flag to use ecs for tool execution
19
+ - Updated dependencies [387f475]
20
+ - Updated dependencies [587532f]
21
+ - Updated dependencies [226c361]
22
+ - Updated dependencies [0ef2e11]
23
+ - Updated dependencies [8c7e9c6]
24
+ - @empiricalrun/llm@0.17.3
25
+ - @empiricalrun/test-run@0.10.0
26
+
27
+ ## 0.64.0
28
+
29
+ ### Minor Changes
30
+
31
+ - 1a5ec8d: feat: stateless tool execution and named args for tool execute fn
32
+
33
+ ### Patch Changes
34
+
35
+ - e5b9f7e: feat: consume repoPath in browser agent
36
+ - 43dc453: fix: record locators before execution for more reliable codegen
37
+ - 24d9415: fix: error message in browser agent tool call + removed unused code
38
+ - Updated dependencies [1a5ec8d]
39
+ - @empiricalrun/llm@0.17.2
40
+
3
41
  ## 0.63.0
4
42
 
5
43
  ### Minor Changes
@@ -9,13 +9,14 @@ type GenerateTestsType = {
9
9
  repoDir: string;
10
10
  traceId?: string;
11
11
  editFileWithGeneratedCode: boolean;
12
+ envOverrides: Record<string, string>;
12
13
  };
13
14
  export declare function convertProjectsFilterToProject({ pwProjectsFilter, repoDir, testFilePath, }: {
14
15
  pwProjectsFilter: string[];
15
16
  repoDir: string;
16
17
  testFilePath: string;
17
18
  }): Promise<string>;
18
- export declare function generateTestsUsingMasterAgent({ testCaseName, testCaseSuites, testFilePath, filePathToUpdate, projectName, testGenToken, repoDir, traceId, editFileWithGeneratedCode, }: GenerateTestsType): Promise<{
19
+ export declare function generateTestsUsingMasterAgent({ testCaseName, testCaseSuites, testFilePath, filePathToUpdate, projectName, testGenToken, repoDir, traceId, editFileWithGeneratedCode, envOverrides, }: GenerateTestsType): Promise<{
19
20
  isError: boolean;
20
21
  error: string;
21
22
  actionsSummary?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAc3D,KAAK,iBAAiB,GAAG;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yBAAyB,EAAE,OAAO,CAAC;CACpC,CAAC;AAEF,wBAAsB,8BAA8B,CAAC,EACnD,gBAAgB,EAChB,OAAO,EACP,YAAY,GACb,EAAE;IACD,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,MAAM,CAAC,CAQlB;AAED,wBAAsB,6BAA6B,CAAC,EAClD,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,OAAO,EACP,OAAO,EACP,yBAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,aAAa,EAAE,CAAC;CAC7B,CAAC,CAmFD"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAgB3D,KAAK,iBAAiB,GAAG;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yBAAyB,EAAE,OAAO,CAAC;IACnC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC,CAAC;AAEF,wBAAsB,8BAA8B,CAAC,EACnD,gBAAgB,EAChB,OAAO,EACP,YAAY,GACb,EAAE;IACD,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,MAAM,CAAC,CAQlB;AAED,wBAAsB,6BAA6B,CAAC,EAClD,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,OAAO,EACP,OAAO,EACP,yBAAyB,EACzB,YAAY,GACb,EAAE,iBAAiB,GAAG,OAAO,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,aAAa,EAAE,CAAC;CAC7B,CAAC,CAqGD"}
@@ -8,18 +8,22 @@ exports.generateTestsUsingMasterAgent = generateTestsUsingMasterAgent;
8
8
  const test_run_1 = require("@empiricalrun/test-run");
9
9
  const detect_port_1 = __importDefault(require("detect-port"));
10
10
  const fs_1 = __importDefault(require("fs"));
11
+ const path_1 = __importDefault(require("path"));
12
+ const utils_1 = require("../../artifacts/utils");
11
13
  const web_1 = require("../../bin/utils/platform/web");
12
14
  const server_1 = require("../../file/server");
13
15
  const exec_1 = require("../../utils/exec");
14
- const utils_1 = require("./utils");
16
+ const utils_2 = require("./utils");
15
17
  async function convertProjectsFilterToProject({ pwProjectsFilter, repoDir, testFilePath, }) {
16
- const playwrightConfig = await (0, utils_1.readPlaywrightConfig)(repoDir);
17
- const project = await (0, utils_1.detectProjectName)(testFilePath, playwrightConfig, pwProjectsFilter);
18
+ const playwrightConfig = await (0, utils_2.readPlaywrightConfig)(repoDir);
19
+ const project = await (0, utils_2.detectProjectName)(testFilePath, playwrightConfig, pwProjectsFilter);
18
20
  return project;
19
21
  }
20
- async function generateTestsUsingMasterAgent({ testCaseName, testCaseSuites, testFilePath, filePathToUpdate, projectName, testGenToken, repoDir, traceId, editFileWithGeneratedCode, }) {
21
- if (!fs_1.default.existsSync(testFilePath)) {
22
- throw new Error(`File for master agent to run not found: ${testFilePath}`);
22
+ async function generateTestsUsingMasterAgent({ testCaseName, testCaseSuites, testFilePath, filePathToUpdate, projectName, testGenToken, repoDir, traceId, editFileWithGeneratedCode, envOverrides, }) {
23
+ const absTestFilePath = path_1.default.join(repoDir, testFilePath);
24
+ if (!fs_1.default.existsSync(absTestFilePath)) {
25
+ const errorMsg = `File for master agent to run not found: ${testFilePath}`;
26
+ throw new Error(errorMsg);
23
27
  }
24
28
  const pm = new exec_1.ProcessManager();
25
29
  const availablePort = await (0, detect_port_1.default)(3030);
@@ -32,7 +36,8 @@ async function generateTestsUsingMasterAgent({ testCaseName, testCaseSuites, tes
32
36
  });
33
37
  await fileServer.startFileService();
34
38
  fileServer.setFilePath(filePathToUpdate);
35
- const pageVar = await (0, web_1.getPageVariableNameFromCreateTest)(filePathToUpdate);
39
+ const absFilePathToUpdate = path_1.default.join(repoDir, filePathToUpdate);
40
+ const pageVar = await (0, web_1.getPageVariableNameFromCreateTest)(absFilePathToUpdate);
36
41
  const testsDir = "tests";
37
42
  const cmd = await (0, test_run_1.runSpecificTestsCmd)({
38
43
  tests: [
@@ -54,7 +59,8 @@ async function generateTestsUsingMasterAgent({ testCaseName, testCaseSuites, tes
54
59
  const cmdLog = `${cmd.command} ${cmd.args.join(" ")}`;
55
60
  console.log(`[generateTestsUsingMasterAgent] Running command: ${cmdLog}`);
56
61
  await pm.execute(cmd.command, cmd.args, {
57
- env: {
62
+ envOverrides: {
63
+ ...envOverrides,
58
64
  IPC_FILE_SERVICE_PORT: availablePort.toString(),
59
65
  PW_TEST_HTML_REPORT_OPEN: "never",
60
66
  TEST_GEN_TOKEN: testGenToken,
@@ -66,12 +72,14 @@ async function generateTestsUsingMasterAgent({ testCaseName, testCaseSuites, tes
66
72
  // Enable this for the page.pause approach in codegen
67
73
  PW_CODEGEN_NO_INSPECTOR: "1",
68
74
  },
75
+ cwd: repoDir,
69
76
  });
70
77
  }
71
78
  catch (e) {
72
79
  error = `Failed to generate test using master agent ${e}`;
73
- console.error(error);
80
+ console.error(`[generateTestsUsingMasterAgent] ${error}`);
74
81
  }
82
+ let artifacts = [];
75
83
  if (error) {
76
84
  // Clean up the file if there is any error
77
85
  try {
@@ -81,14 +89,19 @@ async function generateTestsUsingMasterAgent({ testCaseName, testCaseSuites, tes
81
89
  await (0, web_1.lintErrors)(filePathToUpdate);
82
90
  }
83
91
  catch (e) {
84
- console.error("Failed to remove extra scripts from files post test gen error", e);
92
+ console.error(`[generateTestsUsingMasterAgent] Failed to remove extra scripts from files post test gen error:`, e);
85
93
  }
86
94
  }
95
+ artifacts = [...artifacts, ...(0, utils_1.findPlaywrightArtifacts)(repoDir)];
96
+ const serverArtifacts = fileServer.getArtifactInputsFromServer() || [];
97
+ artifacts = [...serverArtifacts, ...artifacts];
87
98
  await fileServer.stop();
88
99
  return {
89
100
  isError: !!error,
90
101
  error: error || "",
91
- actionsSummary: fileServer.getActionsSummary(),
92
- artifacts: fileServer.getArtifactInputsFromServer(),
102
+ actionsSummary: fileServer.getActionsSummary() ||
103
+ error ||
104
+ "Unknown error, there was no summary or error reported",
105
+ artifacts,
93
106
  };
94
107
  }
@@ -4,7 +4,7 @@ import { Page } from "playwright";
4
4
  import { PlaywrightTestConfig } from "playwright/test";
5
5
  export declare function isRegExp(obj: any): obj is RegExp;
6
6
  export declare function prepareBrowsingAgentTask(steps: string[]): string;
7
- export declare function replaceTodoWithCreateTest(testFilePath: string): Promise<void>;
7
+ export declare function replaceTodoWithCreateTest(testFilePath: string, repoDir: string): Promise<void>;
8
8
  export declare function markTestAsOnly({ testCaseName, testCaseSuites, specPath, }: {
9
9
  testCaseName: string;
10
10
  testCaseSuites: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAI3D,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAsBvD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,MAAM,CAKhD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,UAIvD;AAiFD,wBAAsB,yBAAyB,CAAC,YAAY,EAAE,MAAM,iBAsBnE;AAED,wBAAsB,cAAc,CAAC,EACnC,YAAY,EACZ,cAAc,EACd,QAAQ,GACT,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB,iBAoBA;AAED,wBAAsB,yBAAyB,CAAC,EAC9C,QAAQ,EACR,QAAQ,EACR,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyDlB;AAyBD,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,IAAI,iBA8HxD;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,oBAAoB,CAAC,CA2B/B;AAWD,wBAAsB,oBAAoB,CACxC,gBAAgB,EAAE,oBAAoB,GACrC,OAAO,CAAC,MAAM,EAAE,CAAC,CAQnB;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,oBAAoB,EACtC,gBAAgB,GAAE,MAAM,EAAU,GACjC,OAAO,CAAC,MAAM,CAAC,CA+CjB"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAI3D,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAsBvD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,MAAM,CAKhD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,UAIvD;AAiFD,wBAAsB,yBAAyB,CAC7C,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,iBAwBhB;AAED,wBAAsB,cAAc,CAAC,EACnC,YAAY,EACZ,cAAc,EACd,QAAQ,GACT,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB,iBAoBA;AAED,wBAAsB,yBAAyB,CAAC,EAC9C,QAAQ,EACR,QAAQ,EACR,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyDlB;AAyBD,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,IAAI,iBA8HxD;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,oBAAoB,CAAC,CA2B/B;AAWD,wBAAsB,oBAAoB,CACxC,gBAAgB,EAAE,oBAAoB,GACrC,OAAO,CAAC,MAAM,EAAE,CAAC,CAQnB;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,oBAAoB,EACtC,gBAAgB,GAAE,MAAM,EAAU,GACjC,OAAO,CAAC,MAAM,CAAC,CA+CjB"}
@@ -93,10 +93,11 @@ async function prepareFileForUpdateScenario({ testCase, specPath, trace, }) {
93
93
  });
94
94
  return createTestFilePath;
95
95
  }
96
- async function replaceTodoWithCreateTest(testFilePath) {
96
+ async function replaceTodoWithCreateTest(testFilePath, repoDir) {
97
97
  // This method is an alternative to prepareFileForUpdateScenario
98
98
  // TODO: Does not support scoped variables and updates in POM files
99
- const fileContent = fs_1.default.readFileSync(testFilePath, "utf-8");
99
+ const absoluteTestFilePath = path_1.default.join(repoDir, testFilePath);
100
+ const fileContent = fs_1.default.readFileSync(absoluteTestFilePath, "utf-8");
100
101
  const todoRegex = /\/\/ TODO\(agent(?:\s+on\s+(\w+))?\):\s*(.*)/;
101
102
  const todoMatch = fileContent.match(todoRegex);
102
103
  if (!todoMatch) {
@@ -104,8 +105,8 @@ async function replaceTodoWithCreateTest(testFilePath) {
104
105
  }
105
106
  const [, pageVarName] = todoMatch;
106
107
  const pageVariable = pageVarName || "page"; // Default to "page" if not specified
107
- fs_1.default.writeFileSync(testFilePath, fileContent.replace(todoRegex, (_, __, todoText) => `await createTest("${todoText.replace(/"/g, '\\"')}", ${pageVariable});`));
108
- await addImportForCreateTest(testFilePath);
108
+ fs_1.default.writeFileSync(absoluteTestFilePath, fileContent.replace(todoRegex, (_, __, todoText) => `await createTest("${todoText.replace(/"/g, '\\"')}", ${pageVariable});`));
109
+ await addImportForCreateTest(absoluteTestFilePath);
109
110
  }
110
111
  async function markTestAsOnly({ testCaseName, testCaseSuites, specPath, }) {
111
112
  const testFileContent = fs_1.default.readFileSync(specPath, "utf-8");
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/index.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,mBAAmB,EACpB,MAAM,wBAAwB,CAAC;AAyChC,wBAAsB,kBAAkB,CAAC,EACvC,mBAAmB,EACnB,aAAa,EACb,oBAAoB,EACpB,SAAS,GACV,EAAE;IACD,aAAa,EAAE,mBAAmB,CAAC;IACnC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,iBAsHA;AAuBD,wBAAsB,wBAAwB,CAAC,EAC7C,aAAa,EACb,aAAa,GACd,EAAE;IACD,aAAa,EAAE,mBAAmB,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;CACvB,iBA4DA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/index.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,mBAAmB,EACpB,MAAM,wBAAwB,CAAC;AAyChC,wBAAsB,kBAAkB,CAAC,EACvC,mBAAmB,EACnB,aAAa,EACb,oBAAoB,EACpB,SAAS,GACV,EAAE;IACD,aAAa,EAAE,mBAAmB,CAAC;IACnC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,iBAuHA;AAuBD,wBAAsB,wBAAwB,CAAC,EAC7C,aAAa,EACb,aAAa,GACd,EAAE;IACD,aAAa,EAAE,mBAAmB,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;CACvB,iBA6DA"}
@@ -110,6 +110,7 @@ async function runChatAgentForCLI({ useDiskForChatState, selectedModel, initialP
110
110
  repoPath: process.cwd(),
111
111
  apiKey: process.env.EMPIRICALRUN_API_KEY,
112
112
  trace,
113
+ featureFlags: [],
113
114
  });
114
115
  const fileInfo = await (0, file_tree_1.getFileInfoFromFS)(process.cwd());
115
116
  await (0, agent_loop_1.chatAgentLoop)({
@@ -172,6 +173,7 @@ async function runChatAgentForDashboard({ chatSessionId, selectedModel, }) {
172
173
  repoPath: process.cwd(),
173
174
  apiKey: process.env.EMPIRICALRUN_API_KEY,
174
175
  trace,
176
+ featureFlags: [],
175
177
  });
176
178
  await (0, git_1.checkoutBranch)(branchName, process.cwd());
177
179
  let chatModel = (0, chat_1.createChatModel)(chatState.messages, selectedModel);
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.modelLabels = exports.defaultModel = void 0;
4
4
  const chat_1 = require("@empiricalrun/llm/chat");
5
- const DEFAULT_CHAT_MODEL_ID = "gemini-2.5-pro-preview-03-25";
5
+ const DEFAULT_CHAT_MODEL_ID = "claude-sonnet-4-20250514";
6
6
  function getDefaultChatModelId() {
7
7
  if (!chat_1.SUPPORTED_CHAT_MODELS.some((m) => m.id === DEFAULT_CHAT_MODEL_ID)) {
8
8
  throw new Error("Default chat model is not in SUPPORTED_CHAT_MODELS");
@@ -1 +1 @@
1
- {"version":3,"file":"computer.d.ts","sourceRoot":"","sources":["../../../src/agent/cua/computer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AACpF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,KAAK,oBAAoB,GACrB,wBAAwB,CAAC,KAAK,GAC9B,wBAAwB,CAAC,WAAW,GACpC,wBAAwB,CAAC,IAAI,GAC7B,wBAAwB,CAAC,QAAQ,GACjC,wBAAwB,CAAC,IAAI,GAC7B,wBAAwB,CAAC,UAAU,GACnC,wBAAwB,CAAC,MAAM,GAC/B,wBAAwB,CAAC,IAAI,GAC7B,wBAAwB,CAAC,IAAI,CAAC;AAElC,wBAAsB,aAAa,CAAC,IAAI,EAAE,IAAI,mBAG7C;AAgCD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,oBAAoB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAC5D,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC;IACT,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC,CAkJD"}
1
+ {"version":3,"file":"computer.d.ts","sourceRoot":"","sources":["../../../src/agent/cua/computer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AACpF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,KAAK,oBAAoB,GACrB,wBAAwB,CAAC,KAAK,GAC9B,wBAAwB,CAAC,WAAW,GACpC,wBAAwB,CAAC,IAAI,GAC7B,wBAAwB,CAAC,QAAQ,GACjC,wBAAwB,CAAC,IAAI,GAC7B,wBAAwB,CAAC,UAAU,GACnC,wBAAwB,CAAC,MAAM,GAC/B,wBAAwB,CAAC,IAAI,GAC7B,wBAAwB,CAAC,IAAI,CAAC;AAElC,wBAAsB,aAAa,CAAC,IAAI,EAAE,IAAI,mBAO7C;AAgCD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,oBAAoB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAC5D,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC;IACT,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC,CAoKD"}
@@ -3,7 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getScreenshot = getScreenshot;
4
4
  exports.executeModelAction = executeModelAction;
5
5
  async function getScreenshot(page) {
6
- const screenshotBytes = await page.screenshot();
6
+ // We override the `scale` option to "css" to ensure the screenshot is
7
+ // consistent with the viewport size. Without this, the screenshot dimensions
8
+ // are viewport size * device pixel ratio (= 3 on iPhone device emulation).
9
+ // Docs: https://playwright.dev/docs/api/class-page#page-screenshot-option-scale
10
+ const screenshotBytes = await page.screenshot({ scale: "css" });
7
11
  return Buffer.from(screenshotBytes).toString("base64");
8
12
  }
9
13
  const CUA_KEY_TO_PLAYWRIGHT_KEY = {
@@ -40,14 +44,21 @@ async function executeModelAction(page, action, codegen) {
40
44
  let actionCode = "";
41
45
  let actionSummary = "";
42
46
  try {
47
+ // For every action, this method:
48
+ // 1. Record the action in codegen
49
+ // -> This allows codegen to find locators for the element
50
+ // before the action is executed - execution can be a destructive
51
+ // operation that modifies the DOM
52
+ // 2. Execute the action
53
+ // 3. Add to action summary
54
+ // 4. Add to action code
43
55
  switch (actionType) {
44
- // For every action, this method 1. executes the action,
45
- // 2. adds to action summary, and 3. adds to action code
46
56
  case "goto": {
47
57
  const { url } = action;
58
+ await codegen.recordAction({ type: "goto", url });
48
59
  await page.goto(url);
49
60
  actionSummary = `Navigated page to ${url}`;
50
- actionCode = await codegen.codeForAction({ type: "goto", url });
61
+ actionCode = await codegen.getCodeForLastAction();
51
62
  break;
52
63
  }
53
64
  case "click": {
@@ -61,20 +72,23 @@ async function executeModelAction(page, action, codegen) {
61
72
  pwButton = "middle";
62
73
  }
63
74
  if (pwButton) {
75
+ await codegen.recordAction({ type: "click", x, y });
64
76
  await page.mouse.click(x, y, { button: pwButton });
65
- actionCode = await codegen.codeForAction({ type: "click", x, y });
66
77
  actionSummary = `Click at (${x}, ${y}) with button '${button}'`;
78
+ actionCode = await codegen.getCodeForLastAction();
67
79
  }
68
80
  if (button === "back" || button === "forward") {
69
81
  if (button === "back") {
82
+ await codegen.recordAction({ type: "back" });
70
83
  await page.goBack();
71
- actionCode = await codegen.codeForAction({ type: "back" });
72
84
  actionSummary = `Navigated page back`;
85
+ actionCode = await codegen.getCodeForLastAction();
73
86
  }
74
87
  else if (button === "forward") {
88
+ await codegen.recordAction({ type: "forward" });
75
89
  await page.goForward();
76
- actionCode = await codegen.codeForAction({ type: "forward" });
77
90
  actionSummary = `Navigated page forward`;
91
+ actionCode = await codegen.getCodeForLastAction();
78
92
  }
79
93
  }
80
94
  break;
@@ -82,17 +96,28 @@ async function executeModelAction(page, action, codegen) {
82
96
  case "double_click": {
83
97
  const { x, y } = action;
84
98
  console.log(`Action: doubleclick at (${x}, ${y})`);
99
+ await codegen.recordAction({ type: "doubleclick", x, y });
85
100
  await page.mouse.dblclick(x, y, { button: "left" });
86
101
  actionSummary = `Double click at (${x}, ${y})`;
87
- actionCode = await codegen.codeForAction({ type: "doubleclick", x, y });
102
+ actionCode = await codegen.getCodeForLastAction();
103
+ break;
104
+ }
105
+ case "type": {
106
+ const { text } = action;
107
+ console.log(`Action: type text '${text}'`);
108
+ await codegen.recordAction({ type: "type", text });
109
+ await page.keyboard.type(text);
110
+ actionSummary = `Type text '${text}'`;
111
+ actionCode = await codegen.getCodeForLastAction();
88
112
  break;
89
113
  }
90
114
  case "move": {
91
115
  const { x, y } = action;
92
116
  console.log(`Action: mouse move to (${x}, ${y})`);
117
+ await codegen.recordAction({ type: "move", x, y });
93
118
  await page.mouse.move(x, y);
94
119
  actionSummary = `Mouse move to (${x}, ${y})`;
95
- actionCode = await codegen.codeForAction({ type: "move", x, y });
120
+ actionCode = await codegen.getCodeForLastAction();
96
121
  break;
97
122
  }
98
123
  case "drag": {
@@ -102,32 +127,35 @@ async function executeModelAction(page, action, codegen) {
102
127
  if (!path || path.length === 0) {
103
128
  break;
104
129
  }
130
+ await codegen.recordAction({ type: "drag", path });
105
131
  await page.mouse.move(path[0].x, path[0].y);
106
132
  await page.mouse.down();
107
133
  for (let i = 1; i < path.length; i++) {
108
134
  await page.mouse.move(path[i].x, path[i].y);
109
135
  }
110
136
  await page.mouse.up();
111
- actionCode = await codegen.codeForAction({ type: "drag", path });
137
+ actionCode = await codegen.getCodeForLastAction();
112
138
  break;
113
139
  }
114
140
  case "scroll": {
115
141
  const { x, y, scroll_x, scroll_y } = action;
116
142
  console.log(`Action: scroll at (${x}, ${y}) with offsets (scroll_x=${scroll_x}, scroll_y=${scroll_y})`);
117
- await page.mouse.move(x, y);
118
- await page.evaluate(`window.scrollBy(${scroll_x}, ${scroll_y})`);
119
- actionSummary = `Scroll at (${x}, ${y}) with offsets (scroll_x=${scroll_x}, scroll_y=${scroll_y})`;
120
- actionCode = await codegen.codeForAction({
143
+ await codegen.recordAction({
121
144
  type: "scroll",
122
145
  x,
123
146
  y,
124
147
  scroll_x,
125
148
  scroll_y,
126
149
  });
150
+ await page.mouse.move(x, y);
151
+ await page.evaluate(`window.scrollBy(${scroll_x}, ${scroll_y})`);
152
+ actionSummary = `Scroll at (${x}, ${y}) with offsets (scroll_x=${scroll_x}, scroll_y=${scroll_y})`;
153
+ actionCode = await codegen.getCodeForLastAction();
127
154
  break;
128
155
  }
129
156
  case "keypress": {
130
157
  const { keys } = action;
158
+ await codegen.recordAction({ type: "keypress", keys });
131
159
  const mappedKeys = keys.map((k) => {
132
160
  return CUA_KEY_TO_PLAYWRIGHT_KEY[k.toLowerCase()] || k;
133
161
  });
@@ -135,22 +163,15 @@ async function executeModelAction(page, action, codegen) {
135
163
  console.log(`Action: keypress for keys ${keys} -> '${mappedKey}'`);
136
164
  await page.keyboard.press(mappedKey);
137
165
  actionSummary = `Keypress for keys ${keys} (mapped to '${mappedKey}' for Playwright)`;
138
- actionCode = await codegen.codeForAction({ type: "keypress", keys });
139
- break;
140
- }
141
- case "type": {
142
- const { text } = action;
143
- console.log(`Action: type text '${text}'`);
144
- await page.keyboard.type(text);
145
- actionSummary = `Type text '${text}'`;
146
- actionCode = await codegen.codeForAction({ type: "type", text });
166
+ actionCode = await codegen.getCodeForLastAction();
147
167
  break;
148
168
  }
149
169
  case "wait": {
150
170
  console.log(`Action: wait`);
171
+ await codegen.recordAction({ type: "wait" });
151
172
  await page.waitForTimeout(2000);
152
173
  actionSummary = `Wait for 2 seconds`;
153
- actionCode = await codegen.codeForAction({ type: "wait" });
174
+ actionCode = await codegen.getCodeForLastAction();
154
175
  break;
155
176
  }
156
177
  case "screenshot": {
@@ -2,7 +2,9 @@ import type { Page } from "playwright";
2
2
  import { Action, BasePlaywrightCodegen } from "./types";
3
3
  export declare class ElementFromPointCodegen implements BasePlaywrightCodegen {
4
4
  private page;
5
+ private codeForLastAction;
5
6
  initialize(page: Page): Promise<void>;
6
- codeForAction(action: Action): Promise<string>;
7
+ recordAction(action: Action): Promise<void>;
8
+ getCodeForLastAction(): Promise<string>;
7
9
  }
8
10
  //# sourceMappingURL=element-from-point.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"element-from-point.d.ts","sourceRoot":"","sources":["../../../../src/agent/cua/pw-codegen/element-from-point.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGvC,OAAO,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AA4DxD,qBAAa,uBAAwB,YAAW,qBAAqB;IACnE,OAAO,CAAC,IAAI,CAAmB;IACzB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAKrC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CA0DrD"}
1
+ {"version":3,"file":"element-from-point.d.ts","sourceRoot":"","sources":["../../../../src/agent/cua/pw-codegen/element-from-point.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGvC,OAAO,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAwExD,qBAAa,uBAAwB,YAAW,qBAAqB;IACnE,OAAO,CAAC,IAAI,CAAmB;IAC/B,OAAO,CAAC,iBAAiB,CAAqB;IAExC,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAKrC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA8D3C,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;CAG9C"}
@@ -3,62 +3,73 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ElementFromPointCodegen = void 0;
4
4
  const utils_1 = require("../../browsing/utils");
5
5
  async function getLocatorForClick(page, { x, y }) {
6
- const locator = await page.evaluate(([x, y]) => {
7
- const element = document.elementFromPoint(x, y);
8
- const bbox = element?.getBoundingClientRect();
9
- return {
10
- locator: window.playwright.generateLocator(element),
11
- isIframe: element?.tagName === "IFRAME",
12
- x0: bbox?.x,
13
- y0: bbox?.y,
14
- src: element?.getAttribute("src"),
15
- id: element?.getAttribute("id"),
16
- };
17
- }, [x, y]);
18
- if (!locator.isIframe) {
19
- return locator.locator;
20
- }
21
- await (0, utils_1.injectPwLocatorGenerator)(page);
22
- const relativeX = x - locator.x0;
23
- const relativeY = y - locator.y0;
24
- // TODO: Reuse locator.locator for the frameLocator.
25
- let frameEl = locator.src
26
- ? page.locator(`[src="${locator.src}"]`)
27
- : page.locator(`#${locator.id}`);
28
- const frameLocator = locator.src
29
- ? `locator('[src="${locator.src}"]')`
30
- : `locator('#${locator.id}')`;
31
- const elementLocatorInsideFrame = await frameEl
32
- .contentFrame()
33
- .locator(":root")
34
- .evaluate((rootElement, coords) => {
35
- const xPos = coords[0];
36
- const yPos = coords[1];
37
- if (xPos === undefined || yPos === undefined) {
38
- throw new Error("Coordinates are undefined in evaluate call");
6
+ try {
7
+ const locator = await page.evaluate(([x, y]) => {
8
+ const element = document.elementFromPoint(x, y);
9
+ const bbox = element?.getBoundingClientRect();
10
+ return {
11
+ locator: window.playwright.generateLocator(element),
12
+ isIframe: element?.tagName === "IFRAME",
13
+ x0: bbox?.x,
14
+ y0: bbox?.y,
15
+ src: element?.getAttribute("src"),
16
+ id: element?.getAttribute("id"),
17
+ };
18
+ }, [x, y]);
19
+ if (!locator.isIframe) {
20
+ return locator.locator;
39
21
  }
40
- const element = document.elementFromPoint(xPos, yPos);
41
- return window.playwright.generateLocator(element);
42
- }, [relativeX, relativeY]);
43
- return `${frameLocator}.contentFrame().${elementLocatorInsideFrame}`;
22
+ await (0, utils_1.injectPwLocatorGenerator)(page);
23
+ const relativeX = x - locator.x0;
24
+ const relativeY = y - locator.y0;
25
+ // TODO: Reuse locator.locator for the frameLocator.
26
+ let frameEl = locator.src
27
+ ? page.locator(`[src="${locator.src}"]`)
28
+ : page.locator(`#${locator.id}`);
29
+ const frameLocator = locator.src
30
+ ? `locator('[src="${locator.src}"]')`
31
+ : `locator('#${locator.id}')`;
32
+ const elementLocatorInsideFrame = await frameEl
33
+ .contentFrame()
34
+ .locator(":root")
35
+ .evaluate((rootElement, coords) => {
36
+ const xPos = coords[0];
37
+ const yPos = coords[1];
38
+ if (xPos === undefined || yPos === undefined) {
39
+ throw new Error("Coordinates are undefined in evaluate call");
40
+ }
41
+ const element = document.elementFromPoint(xPos, yPos);
42
+ return window.playwright.generateLocator(element);
43
+ }, [relativeX, relativeY]);
44
+ return `${frameLocator}.contentFrame().${elementLocatorInsideFrame}`;
45
+ }
46
+ catch (e) {
47
+ console.error(`Error generating locator for click: ${e.message || e.toString()}`);
48
+ }
44
49
  }
45
50
  async function getLocatorForFill(page) {
46
- const locator = await page.evaluate(() => {
47
- const element = document.activeElement;
48
- return window.playwright.generateLocator(element);
49
- });
50
- return locator;
51
+ try {
52
+ const locator = await page.evaluate(() => {
53
+ const element = document.activeElement;
54
+ return window.playwright.generateLocator(element);
55
+ });
56
+ return locator;
57
+ }
58
+ catch (e) {
59
+ console.error(`Error generating locator for fill: ${e.message || e.toString()}`);
60
+ }
51
61
  }
52
62
  class ElementFromPointCodegen {
53
63
  page;
64
+ codeForLastAction;
54
65
  async initialize(page) {
55
66
  this.page = page;
56
67
  await (0, utils_1.injectPwLocatorGenerator)(page);
57
68
  }
58
- async codeForAction(action) {
69
+ async recordAction(action) {
59
70
  try {
60
71
  if (action.type === "goto") {
61
- return `await page.goto("${action.url}");\n`;
72
+ this.codeForLastAction = `await page.goto("${action.url}");\n`;
62
73
  }
63
74
  if (action.type === "click") {
64
75
  const { x, y } = action;
@@ -66,20 +77,24 @@ class ElementFromPointCodegen {
66
77
  throw new Error("Page is not initialized");
67
78
  }
68
79
  const locator = await getLocatorForClick(this.page, { x, y });
69
- return `await page.${locator}.click();\n`;
80
+ if (locator) {
81
+ this.codeForLastAction = `await page.${locator}.click();\n`;
82
+ }
70
83
  }
71
84
  if (action.type === "type") {
72
85
  if (!this.page) {
73
86
  throw new Error("Page is not initialized");
74
87
  }
75
88
  const locator = await getLocatorForFill(this.page);
76
- return `await page.${locator}.fill("${action.text}");\n`;
89
+ if (locator) {
90
+ this.codeForLastAction = `await page.${locator}.fill("${action.text}");\n`;
91
+ }
77
92
  }
78
93
  if (action.type === "back") {
79
- return `await page.goBack();\n`;
94
+ this.codeForLastAction = `await page.goBack();\n`;
80
95
  }
81
96
  if (action.type === "forward") {
82
- return `await page.goForward();\n`;
97
+ this.codeForLastAction = `await page.goForward();\n`;
83
98
  }
84
99
  if (action.type === "doubleclick") {
85
100
  const { x, y } = action;
@@ -87,32 +102,34 @@ class ElementFromPointCodegen {
87
102
  throw new Error("Page is not initialized");
88
103
  }
89
104
  const locator = await getLocatorForClick(this.page, { x, y });
90
- return `await page.${locator}.dblclick();\n`;
105
+ this.codeForLastAction = `await page.${locator}.dblclick();\n`;
91
106
  }
92
107
  if (action.type === "move") {
93
108
  const { x, y } = action;
94
- return `await page.mouse.move(${x}, ${y});\n`;
109
+ this.codeForLastAction = `await page.mouse.move(${x}, ${y});\n`;
95
110
  }
96
111
  if (action.type === "drag") {
97
112
  // const { path } = action;
98
113
  // TODO: This needs to be fixed
99
- return `No code generated: drag action not supported by code generation`;
114
+ this.codeForLastAction = `No code generated: drag action not supported by code generation`;
100
115
  }
101
116
  if (action.type === "scroll") {
102
- return `No code to generate: will rely on Playwright's ability to auto-wait`;
117
+ this.codeForLastAction = `No code to generate: will rely on Playwright's ability to auto-wait`;
103
118
  }
104
119
  if (action.type === "keypress") {
105
120
  const { keys } = action;
106
- return `await page.keyboard.press("${keys.join("+")}");\n`;
121
+ this.codeForLastAction = `await page.keyboard.press("${keys.join("+")}");\n`;
107
122
  }
108
123
  if (action.type === "wait") {
109
- return `No code to generate: will rely on Playwright's ability to auto-wait`;
124
+ this.codeForLastAction = `No code to generate: will rely on Playwright's ability to auto-wait`;
110
125
  }
111
- throw new Error(`Unsupported action: ${JSON.stringify(action)}`);
112
126
  }
113
127
  catch (e) {
114
- return `Error generating code for action: ${e.message || e.toString()}`;
128
+ this.codeForLastAction = `Error generating code for action: ${e.message || e.toString()}`;
115
129
  }
116
130
  }
131
+ async getCodeForLastAction() {
132
+ return this.codeForLastAction || "No code generated for the last action";
133
+ }
117
134
  }
118
135
  exports.ElementFromPointCodegen = ElementFromPointCodegen;
@@ -41,6 +41,7 @@ export type Action = {
41
41
  };
42
42
  export interface BasePlaywrightCodegen {
43
43
  initialize(page: Page): Promise<void>;
44
- codeForAction(action: Action): Promise<string>;
44
+ recordAction(action: Action): Promise<void>;
45
+ getCodeForLastAction(): Promise<string>;
45
46
  }
46
47
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/agent/cua/pw-codegen/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,MAAM,MAAM,GACd;IACE,IAAI,EAAE,OAAO,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX,GACD;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX,GACD;IACE,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,IAAI,EAAE,SAAS,CAAC;CACjB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAClC,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,GACD;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb,GACD;IACE,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEN,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAChD"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/agent/cua/pw-codegen/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,MAAM,MAAM,GACd;IAEE,IAAI,EAAE,OAAO,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX,GACD;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX,GACD;IACE,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,IAAI,EAAE,SAAS,CAAC;CACjB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAClC,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,GACD;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb,GACD;IACE,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEN,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CACzC"}