@empiricalrun/test-gen 0.61.0 → 0.63.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.
- package/CHANGELOG.md +51 -0
- package/dist/agent/browsing/run.d.ts +2 -0
- package/dist/agent/browsing/run.d.ts.map +1 -1
- package/dist/agent/browsing/run.js +11 -8
- package/dist/agent/browsing/utils.d.ts.map +1 -1
- package/dist/agent/browsing/utils.js +1 -1
- package/dist/agent/chat/agent-loop.js +2 -3
- package/dist/agent/chat/exports.d.ts +2 -2
- package/dist/agent/chat/exports.d.ts.map +1 -1
- package/dist/agent/chat/exports.js +1 -1
- package/dist/agent/chat/index.d.ts.map +1 -1
- package/dist/agent/chat/index.js +24 -4
- package/dist/agent/chat/models.d.ts +1 -3
- package/dist/agent/chat/models.d.ts.map +1 -1
- package/dist/agent/chat/models.js +4 -25
- package/dist/agent/cua/computer.d.ts +6 -6
- package/dist/agent/cua/computer.d.ts.map +1 -1
- package/dist/agent/cua/computer.js +38 -83
- package/dist/agent/cua/index.d.ts +2 -1
- package/dist/agent/cua/index.d.ts.map +1 -1
- package/dist/agent/cua/index.js +26 -33
- package/dist/agent/cua/pw-codegen/element-from-point.d.ts +8 -0
- package/dist/agent/cua/pw-codegen/element-from-point.d.ts.map +1 -0
- package/dist/agent/cua/pw-codegen/element-from-point.js +118 -0
- package/dist/agent/cua/pw-codegen/pw-pause/index.d.ts +15 -0
- package/dist/agent/cua/pw-codegen/pw-pause/index.d.ts.map +1 -0
- package/dist/agent/cua/pw-codegen/pw-pause/index.js +84 -0
- package/dist/agent/cua/pw-codegen/pw-pause/utils.d.ts +16 -0
- package/dist/agent/cua/pw-codegen/pw-pause/utils.d.ts.map +1 -0
- package/dist/agent/cua/pw-codegen/pw-pause/utils.js +98 -0
- package/dist/agent/cua/pw-codegen/types.d.ts +46 -0
- package/dist/agent/cua/pw-codegen/types.d.ts.map +1 -0
- package/dist/agent/cua/pw-codegen/types.js +2 -0
- package/dist/agent/master/browser-tests/cua.spec.js +13 -1
- package/dist/artifacts/index.d.ts +52 -0
- package/dist/artifacts/index.d.ts.map +1 -0
- package/dist/artifacts/index.js +237 -0
- package/dist/bin/index.js +7 -11
- package/dist/bin/utils/index.d.ts +5 -3
- package/dist/bin/utils/index.d.ts.map +1 -1
- package/dist/bin/utils/index.js +13 -0
- package/dist/bin/utils/platform/web/index.d.ts +1 -1
- package/dist/bin/utils/platform/web/index.d.ts.map +1 -1
- package/dist/bin/utils/platform/web/index.js +3 -2
- package/dist/bin/utils/scenarios/index.d.ts +3 -3
- package/dist/file/client.d.ts +2 -0
- package/dist/file/client.d.ts.map +1 -1
- package/dist/file/client.js +16 -0
- package/dist/file/server.d.ts +3 -1
- package/dist/file/server.d.ts.map +1 -1
- package/dist/file/server.js +27 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/test-build/index.d.ts +6 -2
- package/dist/test-build/index.d.ts.map +1 -1
- package/dist/test-build/index.js +9 -7
- package/dist/tool-call-service/index.d.ts +14 -7
- package/dist/tool-call-service/index.d.ts.map +1 -1
- package/dist/tool-call-service/index.js +36 -10
- package/dist/tools/commit-and-create-pr.d.ts.map +1 -1
- package/dist/tools/commit-and-create-pr.js +11 -4
- package/dist/tools/diagnosis-fetcher.d.ts.map +1 -1
- package/dist/tools/diagnosis-fetcher.js +4 -3
- package/dist/tools/download-build.d.ts.map +1 -1
- package/dist/tools/download-build.js +3 -3
- package/dist/tools/environment-crud.d.ts.map +1 -1
- package/dist/tools/environment-crud.js +6 -4
- package/dist/tools/grep/index.d.ts.map +1 -1
- package/dist/tools/grep/index.js +13 -11
- package/dist/tools/str_replace_editor.d.ts +1 -1
- package/dist/tools/str_replace_editor.d.ts.map +1 -1
- package/dist/tools/str_replace_editor.js +38 -28
- package/dist/tools/test-gen-browser.d.ts.map +1 -1
- package/dist/tools/test-gen-browser.js +18 -4
- package/dist/tools/test-run-fetcher/index.d.ts.map +1 -1
- package/dist/tools/test-run-fetcher/index.js +2 -1
- package/dist/tools/test-run.d.ts.map +1 -1
- package/dist/tools/test-run.js +10 -8
- package/dist/tools/utils/index.d.ts +17 -2
- package/dist/tools/utils/index.d.ts.map +1 -1
- package/dist/tools/utils/index.js +51 -7
- package/dist/utils/checkpoint.d.ts +5 -1
- package/dist/utils/checkpoint.d.ts.map +1 -1
- package/dist/utils/checkpoint.js +8 -3
- package/dist/utils/exec.d.ts +2 -0
- package/dist/utils/exec.d.ts.map +1 -1
- package/dist/utils/exec.js +4 -1
- package/dist/utils/git.d.ts +12 -7
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +27 -17
- package/dist/utils/slug.d.ts +16 -0
- package/dist/utils/slug.d.ts.map +1 -1
- package/dist/utils/slug.js +27 -1
- package/package.json +6 -4
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/pw-test.d.ts +0 -2
- package/dist/utils/pw-test.d.ts.map +0 -1
- package/dist/utils/pw-test.js +0 -13
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ToolCallService = void 0;
|
|
4
4
|
const chat_1 = require("@empiricalrun/llm/chat");
|
|
5
|
+
const artifacts_1 = require("../artifacts");
|
|
5
6
|
const commit_and_create_pr_1 = require("../tools/commit-and-create-pr");
|
|
6
7
|
const diagnosis_fetcher_1 = require("../tools/diagnosis-fetcher");
|
|
7
8
|
const download_build_1 = require("../tools/download-build");
|
|
@@ -19,10 +20,16 @@ class ToolCallService {
|
|
|
19
20
|
chatSessionId;
|
|
20
21
|
selectedModel;
|
|
21
22
|
branchName;
|
|
22
|
-
|
|
23
|
+
repoPath;
|
|
24
|
+
apiKey;
|
|
25
|
+
trace;
|
|
26
|
+
constructor({ chatSessionId, selectedModel, branchName, repoPath, apiKey, trace, }) {
|
|
23
27
|
this.chatSessionId = chatSessionId;
|
|
24
28
|
this.selectedModel = selectedModel;
|
|
25
29
|
this.branchName = branchName;
|
|
30
|
+
this.trace = trace;
|
|
31
|
+
this.repoPath = repoPath;
|
|
32
|
+
this.apiKey = apiKey;
|
|
26
33
|
this.tools = [
|
|
27
34
|
grep_1.grepTool,
|
|
28
35
|
test_run_1.runTestTool,
|
|
@@ -33,8 +40,6 @@ class ToolCallService {
|
|
|
33
40
|
environment_crud_1.getEnvironmentTool,
|
|
34
41
|
download_build_1.downloadBuildTool,
|
|
35
42
|
];
|
|
36
|
-
}
|
|
37
|
-
async getTools() {
|
|
38
43
|
if ((0, chat_1.getProviderForModel)(this.selectedModel) !== "claude") {
|
|
39
44
|
this.tools.push(...str_replace_editor_1.textEditorTools);
|
|
40
45
|
}
|
|
@@ -42,9 +47,13 @@ class ToolCallService {
|
|
|
42
47
|
this.toolExecutors[tool.schema.name] = tool.execute;
|
|
43
48
|
});
|
|
44
49
|
if ((0, chat_1.getProviderForModel)(this.selectedModel) === "claude") {
|
|
45
|
-
this.toolExecutors
|
|
50
|
+
this.toolExecutors = {
|
|
51
|
+
...this.toolExecutors,
|
|
52
|
+
// Support for Claude 3x and 4: They use different tool names
|
|
53
|
+
str_replace_editor: str_replace_editor_1.strReplaceEditorExecutor,
|
|
54
|
+
str_replace_based_edit_tool: str_replace_editor_1.strReplaceEditorExecutor,
|
|
55
|
+
};
|
|
46
56
|
}
|
|
47
|
-
return { tools: this.tools };
|
|
48
57
|
}
|
|
49
58
|
async sendToQueue(toolCalls) {
|
|
50
59
|
const requestId = toolCalls[0]?.id;
|
|
@@ -59,8 +68,8 @@ class ToolCallService {
|
|
|
59
68
|
branchName: this.branchName,
|
|
60
69
|
});
|
|
61
70
|
}
|
|
62
|
-
async execute(toolCalls
|
|
63
|
-
const executeSpan = trace?.span({
|
|
71
|
+
async execute(toolCalls) {
|
|
72
|
+
const executeSpan = this.trace?.span({
|
|
64
73
|
name: "execute_tools",
|
|
65
74
|
input: { toolCalls: toolCalls.map((tc) => ({ name: tc.name })) },
|
|
66
75
|
});
|
|
@@ -70,31 +79,48 @@ class ToolCallService {
|
|
|
70
79
|
name: `tool: ${toolCall.name}`,
|
|
71
80
|
input: toolCall.input,
|
|
72
81
|
});
|
|
82
|
+
const uploadArtifactsQueue = new artifacts_1.UploadArtifactsQueue(this.repoPath, toolCall.id);
|
|
83
|
+
const collectArtifactsFn = (artifactsInput) => {
|
|
84
|
+
uploadArtifactsQueue.addTask(artifactsInput).catch((error) => {
|
|
85
|
+
console.error("Error collecting artifacts:", error);
|
|
86
|
+
});
|
|
87
|
+
return;
|
|
88
|
+
};
|
|
73
89
|
const toolExecutor = this.toolExecutors[toolCall.name];
|
|
74
90
|
if (!toolExecutor) {
|
|
75
91
|
const errorResult = {
|
|
76
92
|
isError: true,
|
|
77
93
|
result: `Invalid function/tool call: ${toolCall.name} not found`,
|
|
94
|
+
artifacts: null,
|
|
78
95
|
};
|
|
79
96
|
toolResults.push(errorResult);
|
|
80
97
|
span?.end({ output: errorResult });
|
|
81
98
|
continue;
|
|
82
99
|
}
|
|
100
|
+
if (!this.apiKey) {
|
|
101
|
+
throw new Error("API key is required for tool execution");
|
|
102
|
+
}
|
|
83
103
|
try {
|
|
84
|
-
const result = await toolExecutor(toolCall.input, trace);
|
|
85
|
-
|
|
104
|
+
const result = await toolExecutor(toolCall.input, this.repoPath, this.apiKey, this.trace, collectArtifactsFn);
|
|
105
|
+
const artifacts = await uploadArtifactsQueue.waitForCompletion();
|
|
106
|
+
toolResults.push({ ...result, artifacts });
|
|
86
107
|
span?.end({ output: result });
|
|
87
108
|
}
|
|
88
109
|
catch (error) {
|
|
89
110
|
const errorResult = {
|
|
90
111
|
isError: true,
|
|
91
112
|
result: error instanceof Error ? error.message : String(error),
|
|
113
|
+
artifacts: null,
|
|
92
114
|
};
|
|
93
115
|
toolResults.push(errorResult);
|
|
94
116
|
span?.end({ output: errorResult });
|
|
95
117
|
}
|
|
96
118
|
}
|
|
97
|
-
await (0, checkpoint_1.createCheckpoint)(
|
|
119
|
+
await (0, checkpoint_1.createCheckpoint)({
|
|
120
|
+
toolCalls,
|
|
121
|
+
branchName: this.branchName,
|
|
122
|
+
repoPath: this.repoPath,
|
|
123
|
+
});
|
|
98
124
|
executeSpan?.end({ output: { toolResults } });
|
|
99
125
|
return toolResults;
|
|
100
126
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit-and-create-pr.d.ts","sourceRoot":"","sources":["../../src/tools/commit-and-create-pr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAOnD,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAiB1D;AA2CD,eAAO,MAAM,qBAAqB,EAAE,
|
|
1
|
+
{"version":3,"file":"commit-and-create-pr.d.ts","sourceRoot":"","sources":["../../src/tools/commit-and-create-pr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAOnD,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAiB1D;AA2CD,eAAO,MAAM,qBAAqB,EAAE,IAsFnC,CAAC"}
|
|
@@ -55,11 +55,13 @@ Don't ask the user for this information, just come up with it yourself.
|
|
|
55
55
|
`,
|
|
56
56
|
parameters: createPullRequestSchema,
|
|
57
57
|
},
|
|
58
|
-
execute: async (input) => {
|
|
58
|
+
execute: async (input, repoPath, apiKey) => {
|
|
59
59
|
try {
|
|
60
60
|
const { pullRequestTitle, pullRequestDescription } = input;
|
|
61
|
-
const branchName = await (0, git_1.getCurrentBranchName)();
|
|
62
|
-
const repoUrl = (0, child_process_1.execSync)("git config --get remote.origin.url"
|
|
61
|
+
const branchName = await (0, git_1.getCurrentBranchName)(repoPath);
|
|
62
|
+
const repoUrl = (0, child_process_1.execSync)("git config --get remote.origin.url", {
|
|
63
|
+
cwd: repoPath,
|
|
64
|
+
})
|
|
63
65
|
.toString()
|
|
64
66
|
.trim();
|
|
65
67
|
const { owner, repo } = parseGitHubUrl(repoUrl);
|
|
@@ -70,8 +72,11 @@ Don't ask the user for this information, just come up with it yourself.
|
|
|
70
72
|
head: `${owner}:${branchName}`,
|
|
71
73
|
state: "open",
|
|
72
74
|
},
|
|
75
|
+
apiKey,
|
|
73
76
|
}));
|
|
74
|
-
(0, child_process_1.execSync)(`git push origin ${branchName} --set-upstream
|
|
77
|
+
(0, child_process_1.execSync)(`git push origin ${branchName} --set-upstream`, {
|
|
78
|
+
cwd: repoPath,
|
|
79
|
+
});
|
|
75
80
|
const existingPR = existingPRs?.find((pr) => pr.head.ref === branchName);
|
|
76
81
|
if (existingPR) {
|
|
77
82
|
// Append the new description to the existing PR description
|
|
@@ -82,6 +87,7 @@ Don't ask the user for this information, just come up with it yourself.
|
|
|
82
87
|
body: {
|
|
83
88
|
body: updatedDescription,
|
|
84
89
|
},
|
|
90
|
+
apiKey,
|
|
85
91
|
});
|
|
86
92
|
return {
|
|
87
93
|
isError: false,
|
|
@@ -98,6 +104,7 @@ Don't ask the user for this information, just come up with it yourself.
|
|
|
98
104
|
base: "main",
|
|
99
105
|
body: initialDescription,
|
|
100
106
|
},
|
|
107
|
+
apiKey,
|
|
101
108
|
}));
|
|
102
109
|
return {
|
|
103
110
|
isError: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnosis-fetcher.d.ts","sourceRoot":"","sources":["../../src/tools/diagnosis-fetcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAenD,eAAO,MAAM,wBAAwB,EAAE,
|
|
1
|
+
{"version":3,"file":"diagnosis-fetcher.d.ts","sourceRoot":"","sources":["../../src/tools/diagnosis-fetcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAenD,eAAO,MAAM,wBAAwB,EAAE,IAqFtC,CAAC"}
|
|
@@ -19,7 +19,7 @@ exports.fetchDiagnosisReportTool = {
|
|
|
19
19
|
description: "Fetch details about a test case diagnosis using its URL or slug",
|
|
20
20
|
parameters: DiagnosisSchema,
|
|
21
21
|
},
|
|
22
|
-
execute: async (input) => {
|
|
22
|
+
execute: async (input, repoPath, apiKey) => {
|
|
23
23
|
const { diagnosisUrl } = input;
|
|
24
24
|
// Extract the slug from the URL - it's the part after the last '--'
|
|
25
25
|
const slug = diagnosisUrl.split("--").pop();
|
|
@@ -33,6 +33,7 @@ exports.fetchDiagnosisReportTool = {
|
|
|
33
33
|
try {
|
|
34
34
|
data = await (0, utils_1.makeDashboardRequest)({
|
|
35
35
|
path: `/api/diagnosis/${slug}/detailed`,
|
|
36
|
+
apiKey,
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
39
|
catch (error) {
|
|
@@ -43,8 +44,8 @@ exports.fetchDiagnosisReportTool = {
|
|
|
43
44
|
}
|
|
44
45
|
const { test_case, diagnosis } = data.data;
|
|
45
46
|
const project = diagnosis?.test_project || "unknown";
|
|
46
|
-
const sourceContext = await promises_1.default.readFile(path_1.default.join("tests", test_case.file_path), "utf-8");
|
|
47
|
-
const repoName = path_1.default.basename(
|
|
47
|
+
const sourceContext = await promises_1.default.readFile(path_1.default.join(repoPath, "tests", test_case.file_path), "utf-8");
|
|
48
|
+
const repoName = path_1.default.basename(repoPath);
|
|
48
49
|
const cleanErrorStack = diagnosis?.failed_run_metadata?.stack?.replace(`"/runner/_work/${repoName}/${repoName}/source-repo/"`, "");
|
|
49
50
|
// Format the response as markdown
|
|
50
51
|
const markdownResponse = `
|
|
@@ -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;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,
|
|
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,IAkC/B,CAAC"}
|
|
@@ -14,8 +14,8 @@ have a build URL, you can try getting the environment details with the getEnviro
|
|
|
14
14
|
Environment details will include the build URL.`,
|
|
15
15
|
parameters: exports.downloadBuildToolSchema,
|
|
16
16
|
},
|
|
17
|
-
execute: async (input) => {
|
|
18
|
-
if (!(await (0, test_build_1.hasDownloadScript)())) {
|
|
17
|
+
execute: async (input, repoPath, apiKey) => {
|
|
18
|
+
if (!(await (0, test_build_1.hasDownloadScript)(repoPath))) {
|
|
19
19
|
return {
|
|
20
20
|
isError: true,
|
|
21
21
|
result: `This repo does not have a download script in package.json.
|
|
@@ -24,7 +24,7 @@ You probably don't need to worry about this, since it means this repo does not h
|
|
|
24
24
|
}
|
|
25
25
|
const { buildUrl } = input;
|
|
26
26
|
try {
|
|
27
|
-
await (0, test_build_1.downloadBuild)(buildUrl);
|
|
27
|
+
await (0, test_build_1.downloadBuild)({ buildUrl, repoPath, apiKey });
|
|
28
28
|
return {
|
|
29
29
|
isError: false,
|
|
30
30
|
result: "Build downloaded successfully",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environment-crud.d.ts","sourceRoot":"","sources":["../../src/tools/environment-crud.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"environment-crud.d.ts","sourceRoot":"","sources":["../../src/tools/environment-crud.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AA6DnD,eAAO,MAAM,kBAAkB,EAAE,IA6EhC,CAAC;AAGF,eAAO,MAAM,gBAAgB,EAAE,IAAI,EAAyB,CAAC"}
|
|
@@ -5,10 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.environmentTools = exports.getEnvironmentTool = void 0;
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
8
9
|
const zod_1 = require("zod");
|
|
9
10
|
const utils_1 = require("./utils");
|
|
10
|
-
const getProjectRepoName = () => {
|
|
11
|
-
const packageJson = fs_1.default.readFileSync("package.json", "utf8");
|
|
11
|
+
const getProjectRepoName = (repoPath) => {
|
|
12
|
+
const packageJson = fs_1.default.readFileSync(path_1.default.join(repoPath, "package.json"), "utf8");
|
|
12
13
|
if (!packageJson) {
|
|
13
14
|
throw new Error("Could not find or read package.json file");
|
|
14
15
|
}
|
|
@@ -30,11 +31,11 @@ exports.getEnvironmentTool = {
|
|
|
30
31
|
description: "Fetch details of an existing environment",
|
|
31
32
|
parameters: GetEnvironmentSchema,
|
|
32
33
|
},
|
|
33
|
-
execute: async (input) => {
|
|
34
|
+
execute: async (input, repoPath, apiKey) => {
|
|
34
35
|
// Get project repo name
|
|
35
36
|
let projectRepoName;
|
|
36
37
|
try {
|
|
37
|
-
projectRepoName = getProjectRepoName();
|
|
38
|
+
projectRepoName = getProjectRepoName(repoPath);
|
|
38
39
|
}
|
|
39
40
|
catch (error) {
|
|
40
41
|
return {
|
|
@@ -52,6 +53,7 @@ exports.getEnvironmentTool = {
|
|
|
52
53
|
response = await (0, utils_1.makeDashboardRequest)({
|
|
53
54
|
path: `/api/environments?${queryParams.toString()}`,
|
|
54
55
|
method: "GET",
|
|
56
|
+
apiKey,
|
|
55
57
|
});
|
|
56
58
|
}
|
|
57
59
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/grep/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/grep/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,wBAAwB,CAAC;AA6H/D,eAAO,MAAM,QAAQ,EAAE,IAoBtB,CAAC"}
|
package/dist/tools/grep/index.js
CHANGED
|
@@ -23,9 +23,9 @@ const GrepInputSchema = zod_1.z.object({
|
|
|
23
23
|
.optional()
|
|
24
24
|
.describe("File pattern to search in (e.g., '*.ts' for TypeScript files)"),
|
|
25
25
|
});
|
|
26
|
-
async function usingSystemGrep(input) {
|
|
26
|
+
async function usingSystemGrep(input, repoPath) {
|
|
27
27
|
try {
|
|
28
|
-
const dir = input.directory ||
|
|
28
|
+
const dir = path_1.default.join(repoPath, input.directory || "");
|
|
29
29
|
// Create exclude pattern for grep
|
|
30
30
|
const excludePatterns = repo_tree_1.DEFAULT_EXCLUDE.map((pattern) => typeof pattern === "string" ? pattern : pattern.source)
|
|
31
31
|
.map((pattern) => `--exclude-dir="${pattern}"`)
|
|
@@ -71,11 +71,13 @@ async function usingSystemGrep(input) {
|
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
-
async function usingRipgrep(input) {
|
|
74
|
+
async function usingRipgrep(input, repoPath) {
|
|
75
75
|
try {
|
|
76
|
-
const dir = path_1.default.join(
|
|
77
|
-
const escapedPattern = input.pattern
|
|
78
|
-
|
|
76
|
+
const dir = path_1.default.join(repoPath, input.directory || "");
|
|
77
|
+
const escapedPattern = input.pattern
|
|
78
|
+
.replace(/\s+/g, "\\ ")
|
|
79
|
+
.replace(/([[\]()])/g, "\\$1");
|
|
80
|
+
const results = (0, ripgrep_1.ripgrep)(dir, {
|
|
79
81
|
string: escapedPattern,
|
|
80
82
|
globs: input.filePattern ? [input.filePattern] : undefined,
|
|
81
83
|
});
|
|
@@ -84,7 +86,7 @@ async function usingRipgrep(input) {
|
|
|
84
86
|
// Can add submatches and offset info to the summary if needed
|
|
85
87
|
return {
|
|
86
88
|
lines: result.lines.text,
|
|
87
|
-
path: path_1.default.relative(
|
|
89
|
+
path: path_1.default.relative(repoPath, result.path.text),
|
|
88
90
|
// line number is 1-indexed
|
|
89
91
|
line_number: result.line_number,
|
|
90
92
|
};
|
|
@@ -96,7 +98,7 @@ ${result.path}:${result.line_number}
|
|
|
96
98
|
${result.lines}\`\`\`
|
|
97
99
|
`;
|
|
98
100
|
});
|
|
99
|
-
const relDir = path_1.default.relative(
|
|
101
|
+
const relDir = path_1.default.relative(repoPath, dir);
|
|
100
102
|
const header = `Found ${resultsSummary.length} results for "${input.pattern}" in "${relDir}".
|
|
101
103
|
All paths are relative to the current working directory.`;
|
|
102
104
|
return {
|
|
@@ -121,13 +123,13 @@ If ripgrep is not available, it will fall back to using system grep.
|
|
|
121
123
|
Search is case insensitive and regex patterns are not supported.`,
|
|
122
124
|
parameters: GrepInputSchema,
|
|
123
125
|
},
|
|
124
|
-
execute: async (input) => {
|
|
126
|
+
execute: async (input, repoPath) => {
|
|
125
127
|
if ((0, ripgrep_1.isRgAvailable)()) {
|
|
126
|
-
return usingRipgrep(input);
|
|
128
|
+
return usingRipgrep(input, repoPath);
|
|
127
129
|
}
|
|
128
130
|
else {
|
|
129
131
|
console.warn("ripgrep is not available, falling back to system grep.");
|
|
130
|
-
return usingSystemGrep(input);
|
|
132
|
+
return usingSystemGrep(input, repoPath);
|
|
131
133
|
}
|
|
132
134
|
},
|
|
133
135
|
};
|
|
@@ -17,7 +17,7 @@ export declare function cleanupBackupFiles(repoDir: string): number;
|
|
|
17
17
|
* Our implementation of Claude's built-in text editor tool
|
|
18
18
|
* https://docs.anthropic.com/en/docs/build-with-claude/tool-use/text-editor-tool
|
|
19
19
|
*/
|
|
20
|
-
export declare function strReplaceEditorExecutor(input: StrReplaceInput): Promise<ToolResult>;
|
|
20
|
+
export declare function strReplaceEditorExecutor(input: StrReplaceInput, repoPath: string): Promise<ToolResult>;
|
|
21
21
|
export declare const textEditorTools: Tool[];
|
|
22
22
|
export {};
|
|
23
23
|
//# sourceMappingURL=str_replace_editor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"str_replace_editor.d.ts","sourceRoot":"","sources":["../../src/tools/str_replace_editor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AA2B1D,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAqED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAwC1D;AAMD;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"str_replace_editor.d.ts","sourceRoot":"","sources":["../../src/tools/str_replace_editor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AA2B1D,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAqED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAwC1D;AAMD;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,eAAe,EACtB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CAkNrB;AAuHD,eAAO,MAAM,eAAe,EAAE,IAAI,EAKjC,CAAC"}
|
|
@@ -139,23 +139,25 @@ function escapeRegExp(text) {
|
|
|
139
139
|
* Our implementation of Claude's built-in text editor tool
|
|
140
140
|
* https://docs.anthropic.com/en/docs/build-with-claude/tool-use/text-editor-tool
|
|
141
141
|
*/
|
|
142
|
-
async function strReplaceEditorExecutor(input) {
|
|
142
|
+
async function strReplaceEditorExecutor(input, repoPath) {
|
|
143
|
+
const repoDir = repoPath;
|
|
143
144
|
const { path: filePath } = input;
|
|
145
|
+
const absoluteFilePath = path_1.default.join(repoDir, filePath);
|
|
144
146
|
try {
|
|
145
147
|
let content;
|
|
146
148
|
let lines;
|
|
147
149
|
let newContent;
|
|
148
150
|
switch (input.command) {
|
|
149
151
|
case "view":
|
|
150
|
-
if (!fs_1.default.existsSync(
|
|
152
|
+
if (!fs_1.default.existsSync(absoluteFilePath)) {
|
|
151
153
|
return {
|
|
152
154
|
result: "Error: File not found",
|
|
153
155
|
isError: true,
|
|
154
156
|
};
|
|
155
157
|
}
|
|
156
158
|
// Handle directory view
|
|
157
|
-
if (fs_1.default.statSync(
|
|
158
|
-
const files = fs_1.default.readdirSync(
|
|
159
|
+
if (fs_1.default.statSync(absoluteFilePath).isDirectory()) {
|
|
160
|
+
const files = fs_1.default.readdirSync(absoluteFilePath);
|
|
159
161
|
return {
|
|
160
162
|
result: files.join("\n"),
|
|
161
163
|
isError: false,
|
|
@@ -164,7 +166,7 @@ async function strReplaceEditorExecutor(input) {
|
|
|
164
166
|
else {
|
|
165
167
|
// Check if file is binary, which is not supported
|
|
166
168
|
const { isBinary } = await import("istextorbinary");
|
|
167
|
-
const binary = isBinary(
|
|
169
|
+
const binary = isBinary(absoluteFilePath);
|
|
168
170
|
if (binary) {
|
|
169
171
|
return {
|
|
170
172
|
result: "Error: File is binary, which is not supported",
|
|
@@ -173,7 +175,7 @@ async function strReplaceEditorExecutor(input) {
|
|
|
173
175
|
}
|
|
174
176
|
}
|
|
175
177
|
// Handle file view
|
|
176
|
-
content = fs_1.default.readFileSync(
|
|
178
|
+
content = fs_1.default.readFileSync(absoluteFilePath, "utf8");
|
|
177
179
|
lines = content.split("\n");
|
|
178
180
|
if (input.view_range) {
|
|
179
181
|
const [start, end] = input.view_range;
|
|
@@ -194,13 +196,19 @@ async function strReplaceEditorExecutor(input) {
|
|
|
194
196
|
if (input.file_text === undefined || input.file_text === null) {
|
|
195
197
|
throw new Error("file_text is required for create command");
|
|
196
198
|
}
|
|
197
|
-
|
|
199
|
+
if (filePath.endsWith("test.ts")) {
|
|
200
|
+
throw new Error("Creating test.ts files is not allowed. Did you mean spec.ts?");
|
|
201
|
+
}
|
|
202
|
+
if (filePath.endsWith("spec.ts") && !filePath.startsWith("tests/")) {
|
|
203
|
+
throw new Error("Creating spec.ts files is not allowed outside tests/ directory");
|
|
204
|
+
}
|
|
205
|
+
const parentDir = path_1.default.dirname(absoluteFilePath);
|
|
198
206
|
if (parentDir !== "." && !fs_1.default.existsSync(parentDir)) {
|
|
199
207
|
// Ensure parent directory exists
|
|
200
208
|
fs_1.default.mkdirSync(parentDir, { recursive: true });
|
|
201
209
|
}
|
|
202
|
-
fs_1.default.writeFileSync(
|
|
203
|
-
let createTypescriptResult = await (0, web_1.runTypescriptCompiler)();
|
|
210
|
+
fs_1.default.writeFileSync(absoluteFilePath, input.file_text);
|
|
211
|
+
let createTypescriptResult = await (0, web_1.runTypescriptCompiler)(repoDir);
|
|
204
212
|
if (!createTypescriptResult.success) {
|
|
205
213
|
return {
|
|
206
214
|
result: `File ${filePath} has been created. However, type checks are failing with errors:\n${createTypescriptResult.errors.join("\n")}`,
|
|
@@ -219,8 +227,8 @@ async function strReplaceEditorExecutor(input) {
|
|
|
219
227
|
// "" is valid as new_str, so we check for nullish -- not falsy
|
|
220
228
|
throw new Error("new_str is required for str_replace command");
|
|
221
229
|
}
|
|
222
|
-
createBackup(
|
|
223
|
-
content = fs_1.default.readFileSync(
|
|
230
|
+
createBackup(absoluteFilePath);
|
|
231
|
+
content = fs_1.default.readFileSync(absoluteFilePath, "utf8");
|
|
224
232
|
// Normalize newlines in both the content and search string
|
|
225
233
|
const normalizedContent = content.replace(/\r\n/g, "\n");
|
|
226
234
|
const normalizedOldStr = input.old_str
|
|
@@ -252,8 +260,8 @@ async function strReplaceEditorExecutor(input) {
|
|
|
252
260
|
};
|
|
253
261
|
}
|
|
254
262
|
newContent = normalizedContent.replace(normalizedOldStr, input.new_str);
|
|
255
|
-
fs_1.default.writeFileSync(
|
|
256
|
-
let strReplaceTypescriptResult = await (0, web_1.runTypescriptCompiler)();
|
|
263
|
+
fs_1.default.writeFileSync(absoluteFilePath, newContent);
|
|
264
|
+
let strReplaceTypescriptResult = await (0, web_1.runTypescriptCompiler)(repoDir);
|
|
257
265
|
if (!strReplaceTypescriptResult.success) {
|
|
258
266
|
return {
|
|
259
267
|
result: `Edits to file ${filePath} have been applied. However, type checks are failing with errors:\n${strReplaceTypescriptResult.errors.join("\n")}`,
|
|
@@ -271,8 +279,8 @@ async function strReplaceEditorExecutor(input) {
|
|
|
271
279
|
if (input.insert_line === undefined || !input.new_str) {
|
|
272
280
|
throw new Error("insert_line and new_str are required for insert command");
|
|
273
281
|
}
|
|
274
|
-
createBackup(
|
|
275
|
-
content = fs_1.default.readFileSync(
|
|
282
|
+
createBackup(absoluteFilePath);
|
|
283
|
+
content = fs_1.default.readFileSync(absoluteFilePath, "utf8");
|
|
276
284
|
lines = content.split("\n");
|
|
277
285
|
if (input.insert_line < 1) {
|
|
278
286
|
throw new Error("insert_line must be greater than or equal to 1 (line numbers are 1-indexed).");
|
|
@@ -281,8 +289,8 @@ async function strReplaceEditorExecutor(input) {
|
|
|
281
289
|
throw new Error(`The file at ${filePath} has only ${lines.length} lines, so insert_line must be less than or equal to ${lines.length + 1}. At the maximum value of ${lines.length + 1}, you can insert at the end of the file.`);
|
|
282
290
|
}
|
|
283
291
|
lines.splice(input.insert_line - 1, 0, input.new_str);
|
|
284
|
-
fs_1.default.writeFileSync(
|
|
285
|
-
let insertTypescriptResult = await (0, web_1.runTypescriptCompiler)();
|
|
292
|
+
fs_1.default.writeFileSync(absoluteFilePath, lines.join("\n"));
|
|
293
|
+
let insertTypescriptResult = await (0, web_1.runTypescriptCompiler)(repoDir);
|
|
286
294
|
if (!insertTypescriptResult.success) {
|
|
287
295
|
return {
|
|
288
296
|
result: `Insertion in file ${filePath} was applied. However, type checks are failing with errors:\n${insertTypescriptResult.errors.join("\n")}`,
|
|
@@ -296,8 +304,8 @@ async function strReplaceEditorExecutor(input) {
|
|
|
296
304
|
};
|
|
297
305
|
}
|
|
298
306
|
case "undo_edit":
|
|
299
|
-
if (hasBackup(
|
|
300
|
-
restoreBackup(
|
|
307
|
+
if (hasBackup(absoluteFilePath)) {
|
|
308
|
+
restoreBackup(absoluteFilePath);
|
|
301
309
|
return {
|
|
302
310
|
result: `Successfully restored ${filePath} from backup`,
|
|
303
311
|
isError: false,
|
|
@@ -335,11 +343,11 @@ File contents are returned with line numbers, starting from 1.
|
|
|
335
343
|
path: zod_1.z.string().describe("The path to the file or directory to view."),
|
|
336
344
|
}),
|
|
337
345
|
},
|
|
338
|
-
execute: async (input) => {
|
|
346
|
+
execute: async (input, repoPath) => {
|
|
339
347
|
return strReplaceEditorExecutor({
|
|
340
348
|
command: "view",
|
|
341
349
|
path: input.path,
|
|
342
|
-
});
|
|
350
|
+
}, repoPath);
|
|
343
351
|
},
|
|
344
352
|
};
|
|
345
353
|
const fileCreateTool = {
|
|
@@ -351,12 +359,12 @@ const fileCreateTool = {
|
|
|
351
359
|
file_text: zod_1.z.string().describe("The contents of the new file."),
|
|
352
360
|
}),
|
|
353
361
|
},
|
|
354
|
-
execute: async (input) => {
|
|
362
|
+
execute: async (input, repoPath) => {
|
|
355
363
|
return strReplaceEditorExecutor({
|
|
356
364
|
command: "create",
|
|
357
365
|
path: input.path,
|
|
358
366
|
file_text: input.file_text,
|
|
359
|
-
});
|
|
367
|
+
}, repoPath);
|
|
360
368
|
},
|
|
361
369
|
};
|
|
362
370
|
const stringReplaceTool = {
|
|
@@ -370,13 +378,13 @@ in the file. If old_str is not unique, the tool will return an error.`,
|
|
|
370
378
|
new_str: zod_1.z.string().describe("The string to replace old_str with."),
|
|
371
379
|
}),
|
|
372
380
|
},
|
|
373
|
-
execute: async (input) => {
|
|
381
|
+
execute: async (input, repoPath) => {
|
|
374
382
|
return strReplaceEditorExecutor({
|
|
375
383
|
command: "str_replace",
|
|
376
384
|
path: input.path,
|
|
377
385
|
old_str: input.old_str,
|
|
378
386
|
new_str: input.new_str,
|
|
379
|
-
});
|
|
387
|
+
}, repoPath);
|
|
380
388
|
},
|
|
381
389
|
};
|
|
382
390
|
const stringInsertTool = {
|
|
@@ -389,17 +397,19 @@ const stringInsertTool = {
|
|
|
389
397
|
.number()
|
|
390
398
|
.int()
|
|
391
399
|
.min(1)
|
|
392
|
-
.describe(
|
|
400
|
+
.describe(`The line number on which to insert the text (1 for beginning of file).
|
|
401
|
+
To insert a string at the beginning of the file, you should use insert_line = 1.
|
|
402
|
+
To insert a string at the end of the file, you should use insert_line = (total lines + 1).`),
|
|
393
403
|
new_str: zod_1.z.string().describe("The string to insert."),
|
|
394
404
|
}),
|
|
395
405
|
},
|
|
396
|
-
execute: async (input) => {
|
|
406
|
+
execute: async (input, repoPath) => {
|
|
397
407
|
return strReplaceEditorExecutor({
|
|
398
408
|
command: "insert",
|
|
399
409
|
path: input.path,
|
|
400
410
|
insert_line: input.insert_line,
|
|
401
411
|
new_str: input.new_str,
|
|
402
|
-
});
|
|
412
|
+
}, repoPath);
|
|
403
413
|
},
|
|
404
414
|
};
|
|
405
415
|
exports.textEditorTools = [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-gen-browser.d.ts","sourceRoot":"","sources":["../../src/tools/test-gen-browser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"test-gen-browser.d.ts","sourceRoot":"","sources":["../../src/tools/test-gen-browser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AA2FnD,eAAO,MAAM,4BAA4B,EAAE,IA8G1C,CAAC"}
|
|
@@ -9,6 +9,7 @@ const promises_1 = __importDefault(require("fs/promises"));
|
|
|
9
9
|
const zod_1 = require("zod");
|
|
10
10
|
const run_1 = require("../agent/browsing/run");
|
|
11
11
|
const utils_1 = require("../agent/browsing/utils");
|
|
12
|
+
const pw_pause_1 = require("../agent/cua/pw-codegen/pw-pause");
|
|
12
13
|
const web_1 = require("../bin/utils/platform/web");
|
|
13
14
|
const scenarios_1 = require("../bin/utils/scenarios");
|
|
14
15
|
const BrowserAgentSchema = zod_1.z.object({
|
|
@@ -87,8 +88,8 @@ exports.generateTestWithBrowserAgent = {
|
|
|
87
88
|
description: BROWSER_AGENT_DESCRIPTION,
|
|
88
89
|
parameters: BrowserAgentSchema,
|
|
89
90
|
},
|
|
90
|
-
execute: async (input, trace) => {
|
|
91
|
-
const repoDir =
|
|
91
|
+
execute: async (input, repoPath, apiKey, trace, collectArtifacts) => {
|
|
92
|
+
const repoDir = repoPath;
|
|
92
93
|
const { testName, testSuites, fileName, changeToMake, project } = input;
|
|
93
94
|
try {
|
|
94
95
|
const { projects } = await (0, test_run_1.getAllPlaywrightProjects)(repoDir);
|
|
@@ -113,6 +114,7 @@ exports.generateTestWithBrowserAgent = {
|
|
|
113
114
|
result: `Test block not found for test name: "${testName}" in file: "${fileName}" with describe blocks: "${testSuites.join(", ")}"`,
|
|
114
115
|
};
|
|
115
116
|
}
|
|
117
|
+
// Prepare the file for the browser agent
|
|
116
118
|
const fileBackup = await promises_1.default.readFile(fileName, "utf-8");
|
|
117
119
|
try {
|
|
118
120
|
await (0, utils_1.replaceTodoWithCreateTest)(fileName);
|
|
@@ -125,6 +127,14 @@ exports.generateTestWithBrowserAgent = {
|
|
|
125
127
|
result: `Error running tool: ${error}`,
|
|
126
128
|
};
|
|
127
129
|
}
|
|
130
|
+
try {
|
|
131
|
+
// Prepare playwright for codegen
|
|
132
|
+
console.log("[generateTestWithBrowserAgent] Preparing playwright for codegen");
|
|
133
|
+
await (0, pw_pause_1.preparePlaywrightForCodegen)(repoDir);
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
console.warn("[generateTestWithBrowserAgent] Error preparing playwright for codegen", err);
|
|
137
|
+
}
|
|
128
138
|
const testGenToken = (0, scenarios_1.buildTokenFromOptions)({ name: testName, file: fileName, prompt: changeToMake }, { useComputerUseAgent: true });
|
|
129
139
|
console.log("[generateTestWithBrowserAgent] Validations passed, starting agent");
|
|
130
140
|
const toolResult = await (0, run_1.generateTestsUsingMasterAgent)({
|
|
@@ -138,9 +148,13 @@ exports.generateTestWithBrowserAgent = {
|
|
|
138
148
|
repoDir,
|
|
139
149
|
editFileWithGeneratedCode: false,
|
|
140
150
|
});
|
|
141
|
-
// Undo the TODO -> createTest changes
|
|
151
|
+
// Cleanup: Undo the TODO -> createTest changes
|
|
152
|
+
await (0, pw_pause_1.revertToOriginalPwCode)(repoDir);
|
|
142
153
|
await promises_1.default.writeFile(fileName, fileBackup, "utf-8");
|
|
143
|
-
const { isError, error, actionsSummary } = toolResult;
|
|
154
|
+
const { isError, error, actionsSummary, artifacts } = toolResult;
|
|
155
|
+
if (artifacts) {
|
|
156
|
+
void collectArtifacts?.(artifacts);
|
|
157
|
+
}
|
|
144
158
|
if (!isError) {
|
|
145
159
|
return {
|
|
146
160
|
isError,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/test-run-fetcher/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAcnD,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOnE;AAED,eAAO,MAAM,sBAAsB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/test-run-fetcher/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAcnD,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOnE;AAED,eAAO,MAAM,sBAAsB,EAAE,IA6HpC,CAAC"}
|
|
@@ -24,7 +24,7 @@ exports.fetchTestRunReportTool = {
|
|
|
24
24
|
description: "Fetch details about a test run using its URL",
|
|
25
25
|
parameters: TestRunSchema,
|
|
26
26
|
},
|
|
27
|
-
execute: async (input) => {
|
|
27
|
+
execute: async (input, repoPath, apiKey) => {
|
|
28
28
|
const { testRunUrl } = input;
|
|
29
29
|
// Remove query parameters if they exist
|
|
30
30
|
const urlWithoutParams = testRunUrl.split("?")[0] || testRunUrl;
|
|
@@ -42,6 +42,7 @@ exports.fetchTestRunReportTool = {
|
|
|
42
42
|
try {
|
|
43
43
|
data = await (0, utils_1.makeDashboardRequest)({
|
|
44
44
|
path: `/api/test-runs/${runId}?repo_name=${repoName}`,
|
|
45
|
+
apiKey,
|
|
45
46
|
});
|
|
46
47
|
}
|
|
47
48
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-run.d.ts","sourceRoot":"","sources":["../../src/tools/test-run.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"test-run.d.ts","sourceRoot":"","sources":["../../src/tools/test-run.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,wBAAwB,CAAC;AA4C/D,eAAO,MAAM,WAAW,EAAE,IAiEzB,CAAC"}
|