@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.
- package/CHANGELOG.md +38 -0
- package/dist/agent/browsing/run.d.ts +2 -1
- package/dist/agent/browsing/run.d.ts.map +1 -1
- package/dist/agent/browsing/run.js +25 -12
- package/dist/agent/browsing/utils.d.ts +1 -1
- package/dist/agent/browsing/utils.d.ts.map +1 -1
- package/dist/agent/browsing/utils.js +5 -4
- package/dist/agent/chat/index.d.ts.map +1 -1
- package/dist/agent/chat/index.js +2 -0
- package/dist/agent/chat/models.js +1 -1
- package/dist/agent/cua/computer.d.ts.map +1 -1
- package/dist/agent/cua/computer.js +45 -24
- package/dist/agent/cua/pw-codegen/element-from-point.d.ts +3 -1
- package/dist/agent/cua/pw-codegen/element-from-point.d.ts.map +1 -1
- package/dist/agent/cua/pw-codegen/element-from-point.js +73 -56
- package/dist/agent/cua/pw-codegen/types.d.ts +2 -1
- package/dist/agent/cua/pw-codegen/types.d.ts.map +1 -1
- package/dist/artifacts/utils.d.ts +21 -0
- package/dist/artifacts/utils.d.ts.map +1 -0
- package/dist/artifacts/utils.js +102 -0
- package/dist/bin/index.js +2 -1
- package/dist/bin/utils/platform/web/index.d.ts.map +1 -1
- package/dist/bin/utils/platform/web/index.js +2 -0
- package/dist/file/server.js +1 -1
- package/dist/test-build/index.js +1 -1
- package/dist/tool-call-service/index.d.ts +5 -2
- package/dist/tool-call-service/index.d.ts.map +1 -1
- package/dist/tool-call-service/index.js +11 -2
- package/dist/tool-call-service/utils.d.ts +1 -0
- package/dist/tool-call-service/utils.d.ts.map +1 -1
- package/dist/tool-call-service/utils.js +6 -2
- package/dist/tools/commit-and-create-pr.d.ts +1 -1
- package/dist/tools/commit-and-create-pr.d.ts.map +1 -1
- package/dist/tools/commit-and-create-pr.js +1 -1
- package/dist/tools/diagnosis-fetcher.d.ts +1 -1
- package/dist/tools/diagnosis-fetcher.d.ts.map +1 -1
- package/dist/tools/diagnosis-fetcher.js +1 -1
- package/dist/tools/download-build.d.ts +1 -1
- package/dist/tools/download-build.d.ts.map +1 -1
- package/dist/tools/download-build.js +1 -1
- package/dist/tools/environment-crud.d.ts +1 -1
- package/dist/tools/environment-crud.d.ts.map +1 -1
- package/dist/tools/environment-crud.js +1 -1
- package/dist/tools/grep/index.d.ts +1 -1
- package/dist/tools/grep/index.d.ts.map +1 -1
- package/dist/tools/grep/index.js +4 -3
- package/dist/tools/str_replace_editor.d.ts +5 -7
- package/dist/tools/str_replace_editor.d.ts.map +1 -1
- package/dist/tools/str_replace_editor.js +259 -247
- package/dist/tools/test-gen-browser.d.ts +1 -1
- package/dist/tools/test-gen-browser.d.ts.map +1 -1
- package/dist/tools/test-gen-browser.js +45 -20
- package/dist/tools/test-run-fetcher/index.d.ts +1 -1
- package/dist/tools/test-run-fetcher/index.d.ts.map +1 -1
- package/dist/tools/test-run-fetcher/index.js +1 -1
- package/dist/tools/test-run.d.ts +1 -1
- package/dist/tools/test-run.d.ts.map +1 -1
- package/dist/tools/test-run.js +35 -12
- package/dist/tools/utils/index.d.ts +0 -13
- package/dist/tools/utils/index.d.ts.map +1 -1
- package/dist/tools/utils/index.js +0 -47
- package/dist/utils/exec.d.ts +4 -4
- package/dist/utils/exec.d.ts.map +1 -1
- package/dist/utils/exec.js +2 -4
- package/dist/utils/file-tree.d.ts.map +1 -1
- package/dist/utils/file-tree.js +2 -0
- package/package.json +4 -4
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/tools/codegen-agent.d.ts +0 -3
- package/dist/tools/codegen-agent.d.ts.map +0 -1
- 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;
|
|
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
|
|
16
|
+
const utils_2 = require("./utils");
|
|
15
17
|
async function convertProjectsFilterToProject({ pwProjectsFilter, repoDir, testFilePath, }) {
|
|
16
|
-
const playwrightConfig = await (0,
|
|
17
|
-
const project = await (0,
|
|
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
|
-
|
|
22
|
-
|
|
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
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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,
|
|
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
|
|
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(
|
|
108
|
-
await addImportForCreateTest(
|
|
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,
|
|
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"}
|
package/dist/agent/chat/index.js
CHANGED
|
@@ -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 = "
|
|
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,
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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;
|
|
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
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
|
69
|
+
async recordAction(action) {
|
|
59
70
|
try {
|
|
60
71
|
if (action.type === "goto") {
|
|
61
|
-
|
|
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
|
-
|
|
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
|
-
|
|
89
|
+
if (locator) {
|
|
90
|
+
this.codeForLastAction = `await page.${locator}.fill("${action.text}");\n`;
|
|
91
|
+
}
|
|
77
92
|
}
|
|
78
93
|
if (action.type === "back") {
|
|
79
|
-
|
|
94
|
+
this.codeForLastAction = `await page.goBack();\n`;
|
|
80
95
|
}
|
|
81
96
|
if (action.type === "forward") {
|
|
82
|
-
|
|
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
|
-
|
|
105
|
+
this.codeForLastAction = `await page.${locator}.dblclick();\n`;
|
|
91
106
|
}
|
|
92
107
|
if (action.type === "move") {
|
|
93
108
|
const { x, y } = action;
|
|
94
|
-
|
|
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
|
-
|
|
114
|
+
this.codeForLastAction = `No code generated: drag action not supported by code generation`;
|
|
100
115
|
}
|
|
101
116
|
if (action.type === "scroll") {
|
|
102
|
-
|
|
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
|
-
|
|
121
|
+
this.codeForLastAction = `await page.keyboard.press("${keys.join("+")}");\n`;
|
|
107
122
|
}
|
|
108
123
|
if (action.type === "wait") {
|
|
109
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
|
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"}
|