@empiricalrun/test-gen 0.79.2 → 0.79.3
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 +8 -0
- package/dist/agent/chat/exports.d.ts +1 -0
- package/dist/agent/chat/exports.d.ts.map +1 -1
- package/dist/agent/chat/exports.js +3 -1
- package/dist/agent/chat/index.js +1 -1
- package/dist/agent/chat/prompt/repo.d.ts.map +1 -1
- package/dist/agent/chat/prompt/repo.js +4 -3
- package/dist/agent/fast-triage/index.d.ts +8 -0
- package/dist/agent/fast-triage/index.d.ts.map +1 -0
- package/dist/agent/fast-triage/index.js +51 -0
- package/dist/agent/index.d.ts +2 -1
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +4 -1
- package/dist/agent/triage/index.js +2 -2
- package/dist/bin/index.js +5 -3
- package/dist/bin/utils/platform/web/index.d.ts.map +1 -1
- package/dist/bin/utils/platform/web/index.js +3 -2
- package/dist/dashboard/client.d.ts +11 -1
- package/dist/dashboard/client.d.ts.map +1 -1
- package/dist/dashboard/client.js +22 -9
- package/dist/file-info/adapters/github/index.d.ts.map +1 -1
- package/dist/file-info/adapters/github/index.js +1 -1
- package/dist/generate-summary/frame-sampling.d.ts +12 -0
- package/dist/generate-summary/frame-sampling.d.ts.map +1 -0
- package/dist/generate-summary/frame-sampling.js +72 -0
- package/dist/generate-summary/generate-error-stack-summary.d.ts +11 -0
- package/dist/generate-summary/generate-error-stack-summary.d.ts.map +1 -0
- package/dist/generate-summary/generate-error-stack-summary.js +44 -0
- package/dist/generate-summary/generate-failed-step-screenshot-diff-summary.d.ts +58 -0
- package/dist/generate-summary/generate-failed-step-screenshot-diff-summary.d.ts.map +1 -0
- package/dist/generate-summary/generate-failed-step-screenshot-diff-summary.js +460 -0
- package/dist/generate-summary/generate-grouped-summary.d.ts +18 -0
- package/dist/generate-summary/generate-grouped-summary.d.ts.map +1 -0
- package/dist/generate-summary/generate-grouped-summary.js +91 -0
- package/dist/generate-summary/merge-summary.d.ts +16 -0
- package/dist/generate-summary/merge-summary.d.ts.map +1 -0
- package/dist/generate-summary/merge-summary.js +46 -0
- package/dist/generate-summary/pick-videos-for-comparison.d.ts +9 -0
- package/dist/generate-summary/pick-videos-for-comparison.d.ts.map +1 -0
- package/dist/generate-summary/pick-videos-for-comparison.js +54 -0
- package/dist/telemetry/index.d.ts.map +1 -1
- package/dist/telemetry/index.js +3 -1
- package/dist/tools/definitions/delete-file.js +1 -1
- package/dist/tools/definitions/grep.d.ts.map +1 -1
- package/dist/tools/definitions/grep.js +1 -1
- package/dist/tools/definitions/rename-file.js +2 -2
- package/dist/tools/definitions/safe-bash.d.ts.map +1 -1
- package/dist/tools/definitions/safe-bash.js +10 -8
- package/dist/tools/definitions/str_replace_editor.d.ts.map +1 -1
- package/dist/tools/definitions/str_replace_editor.js +12 -4
- package/dist/tools/definitions/trace-dot-zip.d.ts +7 -0
- package/dist/tools/definitions/trace-dot-zip.d.ts.map +1 -0
- package/dist/tools/definitions/trace-dot-zip.js +16 -0
- package/dist/tools/definitions/utils.js +1 -1
- package/dist/tools/delete-file/index.d.ts.map +1 -1
- package/dist/tools/delete-file/index.js +9 -6
- package/dist/tools/diagnosis-fetcher.d.ts.map +1 -1
- package/dist/tools/diagnosis-fetcher.js +40 -2
- package/dist/tools/fetch-file/index.d.ts.map +1 -1
- package/dist/tools/fetch-file/index.js +102 -3
- package/dist/tools/file-operations/index.d.ts.map +1 -1
- package/dist/tools/file-operations/index.js +7 -5
- package/dist/tools/file-operations/shared/helpers.d.ts +13 -0
- package/dist/tools/file-operations/shared/helpers.d.ts.map +1 -1
- package/dist/tools/file-operations/shared/helpers.js +24 -0
- package/dist/tools/file-operations/view/index.d.ts.map +1 -1
- package/dist/tools/file-operations/view/index.js +9 -3
- package/dist/tools/grep/index.d.ts.map +1 -1
- package/dist/tools/grep/index.js +7 -2
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +6 -6
- package/dist/tools/merge-conflicts/index.d.ts.map +1 -1
- package/dist/tools/merge-conflicts/index.js +8 -8
- package/dist/tools/rename-file/index.d.ts.map +1 -1
- package/dist/tools/rename-file/index.js +11 -7
- package/dist/tools/run-test.d.ts.map +1 -1
- package/dist/tools/run-test.js +12 -7
- package/dist/tools/safe-bash/index.d.ts.map +1 -1
- package/dist/tools/safe-bash/index.js +18 -2
- package/dist/tools/test-gen-browser.d.ts.map +1 -1
- package/dist/tools/test-gen-browser.js +12 -9
- package/dist/tools/trace-dot-zip/index.d.ts +3 -1
- package/dist/tools/trace-dot-zip/index.d.ts.map +1 -1
- package/dist/tools/trace-dot-zip/index.js +8 -20
- package/dist/tools/trace-dot-zip/utils/console-trace.d.ts.map +1 -1
- package/dist/tools/trace-dot-zip/utils/console-trace.js +11 -5
- package/dist/tools/trace-dot-zip/utils/extract-screenshots.d.ts +27 -0
- package/dist/tools/trace-dot-zip/utils/extract-screenshots.d.ts.map +1 -0
- package/dist/tools/trace-dot-zip/utils/extract-screenshots.js +128 -0
- package/dist/tools/trace-dot-zip/utils/extract-steps.d.ts +12 -0
- package/dist/tools/trace-dot-zip/utils/extract-steps.d.ts.map +1 -0
- package/dist/tools/trace-dot-zip/utils/extract-steps.js +130 -0
- package/dist/tools/trace-dot-zip/utils/extract-zip.d.ts +13 -16
- package/dist/tools/trace-dot-zip/utils/extract-zip.d.ts.map +1 -1
- package/dist/tools/trace-dot-zip/utils/extract-zip.js +27 -167
- package/dist/tools/trace-dot-zip/utils/network-trace.d.ts.map +1 -1
- package/dist/tools/trace-dot-zip/utils/network-trace.js +136 -105
- package/dist/trace-utils/cli.d.ts +3 -0
- package/dist/trace-utils/cli.d.ts.map +1 -0
- package/dist/trace-utils/cli.js +302 -0
- package/dist/trace-utils/console.d.ts +11 -0
- package/dist/trace-utils/console.d.ts.map +1 -0
- package/dist/trace-utils/console.js +74 -0
- package/dist/trace-utils/dom-snapshot.d.ts +19 -0
- package/dist/trace-utils/dom-snapshot.d.ts.map +1 -0
- package/dist/trace-utils/dom-snapshot.js +328 -0
- package/dist/trace-utils/index.d.ts +8 -0
- package/dist/trace-utils/index.d.ts.map +1 -1
- package/dist/trace-utils/index.js +19 -1
- package/dist/trace-utils/network.d.ts +16 -0
- package/dist/trace-utils/network.d.ts.map +1 -0
- package/dist/trace-utils/network.js +178 -0
- package/dist/trace-utils/normalize-trace-url.d.ts +2 -0
- package/dist/trace-utils/normalize-trace-url.d.ts.map +1 -0
- package/dist/trace-utils/normalize-trace-url.js +15 -0
- package/dist/trace-utils/screenshots.d.ts +24 -0
- package/dist/trace-utils/screenshots.d.ts.map +1 -0
- package/dist/trace-utils/screenshots.js +197 -0
- package/dist/trace-utils/steps.d.ts +10 -0
- package/dist/trace-utils/steps.d.ts.map +1 -0
- package/dist/trace-utils/steps.js +126 -0
- package/dist/trace-utils/types.d.ts +51 -0
- package/dist/trace-utils/types.d.ts.map +1 -0
- package/dist/trace-utils/types.js +2 -0
- package/dist/utils/playwright-report-parser.d.ts +1 -12
- package/dist/utils/playwright-report-parser.d.ts.map +1 -1
- package/dist/utils/playwright-report-parser.js +8 -136
- package/dist/video-core/index.d.ts.map +1 -1
- package/dist/video-core/index.js +17 -33
- package/package.json +12 -6
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.pickVideosForComparison = void 0;
|
|
4
|
+
const getVideoSize = async (url) => {
|
|
5
|
+
const response = await fetch(url, { method: "HEAD" });
|
|
6
|
+
if (!response.ok) {
|
|
7
|
+
console.warn(`Failed to fetch ${url}: ${response.statusText}`);
|
|
8
|
+
return 0;
|
|
9
|
+
}
|
|
10
|
+
const contentLength = response.headers.get("content-length");
|
|
11
|
+
if (!contentLength) {
|
|
12
|
+
console.warn(`Content-Length header is missing for ${url}`);
|
|
13
|
+
return 0;
|
|
14
|
+
}
|
|
15
|
+
const videoSize = parseInt(contentLength, 10);
|
|
16
|
+
console.log(`Recording size for ${url} is ------> ${videoSize} bytes`);
|
|
17
|
+
return videoSize;
|
|
18
|
+
};
|
|
19
|
+
const pickVideosForComparison = async ({ testRunId, test, }) => {
|
|
20
|
+
const videosPickedForComparison = {
|
|
21
|
+
failure: "",
|
|
22
|
+
success: "",
|
|
23
|
+
};
|
|
24
|
+
try {
|
|
25
|
+
const failureVideoWithLargestSize = (await Promise.all(test.failure.videos.map(async (video) => {
|
|
26
|
+
const size = await getVideoSize(video);
|
|
27
|
+
return { videoUrl: video, size };
|
|
28
|
+
}))).reduce((max, current) => {
|
|
29
|
+
return current.size > max.size ? current : max;
|
|
30
|
+
}, { videoUrl: "", size: 0 });
|
|
31
|
+
console.log(`Picking failure recording with largest size ------> ${failureVideoWithLargestSize.size}, url - ${failureVideoWithLargestSize.videoUrl}`);
|
|
32
|
+
videosPickedForComparison.failure = failureVideoWithLargestSize.videoUrl;
|
|
33
|
+
const successVideoWithLargestSize = (await Promise.all(test?.success?.videos?.map(async (video) => {
|
|
34
|
+
const size = await getVideoSize(video);
|
|
35
|
+
return { videoUrl: video, size };
|
|
36
|
+
}))).reduce((max, current) => {
|
|
37
|
+
return current.size > max.size ? current : max;
|
|
38
|
+
}, { videoUrl: "", size: 0 });
|
|
39
|
+
console.log(`Picking success recording with largest size ------> ${successVideoWithLargestSize.size}, url - ${successVideoWithLargestSize.videoUrl}`);
|
|
40
|
+
videosPickedForComparison.success = successVideoWithLargestSize.videoUrl;
|
|
41
|
+
if (!videosPickedForComparison.failure) {
|
|
42
|
+
console.warn(`No failure run recordings found for test - "${test.title}", for testRunId - "${testRunId}"`);
|
|
43
|
+
}
|
|
44
|
+
if (!videosPickedForComparison.success) {
|
|
45
|
+
console.warn(`No last successful run recordings found for test - "${test.title}", for testRunId - "${testRunId}"`);
|
|
46
|
+
}
|
|
47
|
+
return videosPickedForComparison;
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
console.error("Error while processing bookmarks", e);
|
|
51
|
+
return videosPickedForComparison;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
exports.pickVideosForComparison = pickVideosForComparison;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/telemetry/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EACV,KAAK,EACN,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAM3E,MAAM,MAAM,YAAY,GAAG;IACzB,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,wBAAsB,UAAU,CAC9B,KAAK,EAAE,cAAc,EACrB,GAAG,CAAC,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAsBf;AAED,wBAAsB,yBAAyB,CAC7C,QAAQ,EAAE,eAAe,EACzB,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,MAAM,EACvB,GAAG,CAAC,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,wBAAsB,2BAA2B,CAC/C,QAAQ,EAAE,eAAe,EACzB,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,MAAM,EACvB,gBAAgB,EAAE,MAAM,EACxB,GAAG,CAAC,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,CAAC,EAAE,YAAY,CAAC;CACpB,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/telemetry/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EACV,KAAK,EACN,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAM3E,MAAM,MAAM,YAAY,GAAG;IACzB,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,wBAAsB,UAAU,CAC9B,KAAK,EAAE,cAAc,EACrB,GAAG,CAAC,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAsBf;AAED,wBAAsB,yBAAyB,CAC7C,QAAQ,EAAE,eAAe,EACzB,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,MAAM,EACvB,GAAG,CAAC,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,wBAAsB,2BAA2B,CAC/C,QAAQ,EAAE,eAAe,EACzB,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,MAAM,EACvB,gBAAgB,EAAE,MAAM,EACxB,GAAG,CAAC,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,CAAC,EAAE,YAAY,CAAC;CACpB,GAAG,IAAI,CAsBP"}
|
package/dist/telemetry/index.js
CHANGED
|
@@ -71,13 +71,15 @@ function trackLLMResponse(opts) {
|
|
|
71
71
|
properties: {
|
|
72
72
|
environment,
|
|
73
73
|
model_name: opts.modelName,
|
|
74
|
-
project_repo_name: opts.projectRepoName,
|
|
75
74
|
chat_session_id: opts.chatSessionId,
|
|
76
75
|
chat_session_source: opts.chatSessionSource,
|
|
77
76
|
tokens_input: opts.usage.tokens?.input || 0,
|
|
78
77
|
tokens_output: opts.usage.tokens?.output || 0,
|
|
79
78
|
cost_input: opts.usage.cost?.input || 0,
|
|
80
79
|
cost_output: opts.usage.cost?.output || 0,
|
|
80
|
+
// Moving project_repo_name -> repo_name for consistency with other events
|
|
81
|
+
project_repo_name: opts.projectRepoName,
|
|
82
|
+
repo_name: opts.projectRepoName,
|
|
81
83
|
},
|
|
82
84
|
}, opts.env);
|
|
83
85
|
}
|
|
@@ -5,7 +5,7 @@ const zod_1 = require("zod");
|
|
|
5
5
|
exports.DeleteFileInputSchema = zod_1.z.object({
|
|
6
6
|
path: zod_1.z
|
|
7
7
|
.string()
|
|
8
|
-
.describe("The path to the file to delete (relative
|
|
8
|
+
.describe("The path to the file to delete. Prefer using absolute paths with /repo/ prefix (e.g., /repo/tests/foo.spec.ts), but relative paths from the repository root are also supported (e.g., tests/foo.spec.ts)."),
|
|
9
9
|
});
|
|
10
10
|
exports.deleteFileTool = {
|
|
11
11
|
schema: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../../../src/tools/definitions/grep.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../../../src/tools/definitions/grep.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAqB5E,eAAO,MAAM,QAAQ,EAAE,cAWtB,CAAC"}
|
|
@@ -9,7 +9,7 @@ const GrepInputSchema = zod_1.z.object({
|
|
|
9
9
|
directory: zod_1.z
|
|
10
10
|
.string()
|
|
11
11
|
.optional()
|
|
12
|
-
.describe("The directory to search in (defaults to current directory)"),
|
|
12
|
+
.describe("The directory to search in (defaults to current directory). Prefer using absolute paths with /repo/ prefix (e.g., /repo/tests), but relative paths are also supported (e.g., tests)."),
|
|
13
13
|
filePattern: zod_1.z
|
|
14
14
|
.string()
|
|
15
15
|
.optional()
|
|
@@ -5,10 +5,10 @@ const zod_1 = require("zod");
|
|
|
5
5
|
const RenameFileInputSchema = zod_1.z.object({
|
|
6
6
|
oldPath: zod_1.z
|
|
7
7
|
.string()
|
|
8
|
-
.describe("The current path to the file to rename (relative
|
|
8
|
+
.describe("The current path to the file to rename. Prefer using absolute paths with /repo/ prefix (e.g., /repo/tests/foo.spec.ts), but relative paths from the repository root are also supported (e.g., tests/foo.spec.ts)."),
|
|
9
9
|
newPath: zod_1.z
|
|
10
10
|
.string()
|
|
11
|
-
.describe("The new path for the file (relative
|
|
11
|
+
.describe("The new path for the file. Prefer using absolute paths with /repo/ prefix (e.g., /repo/tests/new-dir/bar.spec.ts), but relative paths from the repository root are also supported (e.g., tests/new-dir/bar.spec.ts)."),
|
|
12
12
|
});
|
|
13
13
|
exports.renameFileTool = {
|
|
14
14
|
schema: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safe-bash.d.ts","sourceRoot":"","sources":["../../../src/tools/definitions/safe-bash.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,mBAAmB;;;iBAM9B,CAAC;AAEH,eAAO,MAAM,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"safe-bash.d.ts","sourceRoot":"","sources":["../../../src/tools/definitions/safe-bash.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,mBAAmB;;;iBAM9B,CAAC;AAEH,eAAO,MAAM,YAAY,EAAE,cAsB1B,CAAC"}
|
|
@@ -13,18 +13,20 @@ exports.safeBashTool = {
|
|
|
13
13
|
schema: {
|
|
14
14
|
name: "safeBash",
|
|
15
15
|
description: `Execute a bash script with branch protection and controlled git operations.
|
|
16
|
+
The reo dir is the cwd for this tool: No need to do "cd /repo".
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- Verifying the branch hasn't changed after execution
|
|
18
|
+
IMPORTANT: If the script modifies files that need to be pushed to the repo, the script MUST
|
|
19
|
+
stage them using 'git add' -- but DO NOT commit/push them. The executor harness will automatically
|
|
20
|
+
commit staged files and push to the remote.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
For example, if you use this tool to upgrade NPM packages, you should stage package.json and package-lock.json
|
|
23
|
+
files.
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
The tool returns typescript compiler result after running script, stdout, stderr, staged
|
|
26
|
+
files (which will be committed), and unstaged files.
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
This tool restricts commits/push, or branch switching, and will throw errors.
|
|
29
|
+
`,
|
|
28
30
|
parameters: exports.SafeBashInputSchema,
|
|
29
31
|
},
|
|
30
32
|
needsBrowser: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"str_replace_editor.d.ts","sourceRoot":"","sources":["../../../src/tools/definitions/str_replace_editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"str_replace_editor.d.ts","sourceRoot":"","sources":["../../../src/tools/definitions/str_replace_editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AA6FvE,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAK1D,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAExD,CAAC"}
|
|
@@ -16,7 +16,9 @@ File contents are returned with line numbers, starting from 1.
|
|
|
16
16
|
...`,
|
|
17
17
|
parameters: zod_1.z.object({
|
|
18
18
|
// Does not support view_range for now
|
|
19
|
-
path: zod_1.z
|
|
19
|
+
path: zod_1.z
|
|
20
|
+
.string()
|
|
21
|
+
.describe("The path to the file or directory to view. Prefer using absolute paths with /repo/ prefix (e.g., /repo/tests/foo.spec.ts), but relative paths are also supported (e.g., tests/foo.spec.ts)."),
|
|
20
22
|
}),
|
|
21
23
|
},
|
|
22
24
|
needsBrowser: false,
|
|
@@ -30,7 +32,9 @@ This tool will also create parent directories that do not exist.
|
|
|
30
32
|
For example, for path "tests/example/foo.spec.ts", the tool will create
|
|
31
33
|
directories "tests", "tests/example", and "tests/example/foo.spec.ts".`,
|
|
32
34
|
parameters: zod_1.z.object({
|
|
33
|
-
path: zod_1.z
|
|
35
|
+
path: zod_1.z
|
|
36
|
+
.string()
|
|
37
|
+
.describe("The path to the new file. Prefer using absolute paths with /repo/ prefix (e.g., /repo/tests/foo.spec.ts), but relative paths are also supported (e.g., tests/foo.spec.ts)."),
|
|
34
38
|
file_text: zod_1.z.string().describe("The contents of the new file."),
|
|
35
39
|
}),
|
|
36
40
|
},
|
|
@@ -43,7 +47,9 @@ const stringReplaceTool = {
|
|
|
43
47
|
description: `A tool to replace a string in a file. This tool requires old_str to be unique
|
|
44
48
|
in the file. If old_str is not unique, the tool will return an error.`,
|
|
45
49
|
parameters: zod_1.z.object({
|
|
46
|
-
path: zod_1.z
|
|
50
|
+
path: zod_1.z
|
|
51
|
+
.string()
|
|
52
|
+
.describe("The path to the file. Prefer using absolute paths with /repo/ prefix (e.g., /repo/tests/foo.spec.ts), but relative paths are also supported (e.g., tests/foo.spec.ts)."),
|
|
47
53
|
old_str: zod_1.z.string().describe("The string to be replaced."),
|
|
48
54
|
new_str: zod_1.z.string().describe("The string to replace old_str with."),
|
|
49
55
|
}),
|
|
@@ -56,7 +62,9 @@ const stringInsertTool = {
|
|
|
56
62
|
name: "stringInsertTool",
|
|
57
63
|
description: "A tool to insert a string at a specific line in a file.",
|
|
58
64
|
parameters: zod_1.z.object({
|
|
59
|
-
path: zod_1.z
|
|
65
|
+
path: zod_1.z
|
|
66
|
+
.string()
|
|
67
|
+
.describe("The path to the file. Prefer using absolute paths with /repo/ prefix (e.g., /repo/tests/foo.spec.ts), but relative paths are also supported (e.g., tests/foo.spec.ts)."),
|
|
60
68
|
insert_line: zod_1.z
|
|
61
69
|
.number()
|
|
62
70
|
.int()
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ToolDefinition } from "@empiricalrun/shared-types/chat-agent";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export declare const traceDotZipSchema: z.ZodObject<{
|
|
4
|
+
url: z.ZodString;
|
|
5
|
+
}, z.core.$strip>;
|
|
6
|
+
export declare const traceDotZip: ToolDefinition<z.infer<typeof traceDotZipSchema>>;
|
|
7
|
+
//# sourceMappingURL=trace-dot-zip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-dot-zip.d.ts","sourceRoot":"","sources":["../../../src/tools/definitions/trace-dot-zip.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,iBAAiB;;iBAE5B,CAAC;AAEH,eAAO,MAAM,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAQzE,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.traceDotZip = exports.traceDotZipSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.traceDotZipSchema = zod_1.z.object({
|
|
6
|
+
url: zod_1.z.string().describe(`The URL to the "trace.zip" file.`),
|
|
7
|
+
});
|
|
8
|
+
exports.traceDotZip = {
|
|
9
|
+
schema: {
|
|
10
|
+
name: "traceDotZip",
|
|
11
|
+
description: `Extracts failed network request and console error traces from a Playwright trace zip file. Pass a trace.zip URL to this tool and get a summary of failed network calls (by status codes) and console error logs (by "messageType") to understand network activity and console logs during the test run.`,
|
|
12
|
+
parameters: exports.traceDotZipSchema,
|
|
13
|
+
},
|
|
14
|
+
needsBrowser: false,
|
|
15
|
+
isInlineTool: false,
|
|
16
|
+
};
|
|
@@ -11,6 +11,6 @@ const getCommonTestNameSuitesFilePathSchema = (testNameDescription) => zod_1.z.o
|
|
|
11
11
|
.describe("The suites (describe blocks) where the test is located. If the test is not in any describe block, provide an empty array."),
|
|
12
12
|
filePath: zod_1.z
|
|
13
13
|
.string()
|
|
14
|
-
.describe("Path of the file where the test is located.
|
|
14
|
+
.describe("Path of the file where the test is located. Prefer using absolute paths with /repo/ prefix, but relative paths are also supported. File name must end with .spec.ts. For example: /repo/tests/lesson.spec.ts (preferred) or tests/lesson.spec.ts (also supported)"),
|
|
15
15
|
});
|
|
16
16
|
exports.getCommonTestNameSuitesFilePathSchema = getCommonTestNameSuitesFilePathSchema;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/delete-file/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,IAAI,EAEL,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/delete-file/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,IAAI,EAEL,MAAM,uCAAuC,CAAC;AAa/C,eAAO,MAAM,cAAc,EAAE,IAuE5B,CAAC"}
|
|
@@ -9,25 +9,28 @@ const promises_1 = require("fs/promises");
|
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
10
|
const web_1 = require("../../bin/utils/platform/web");
|
|
11
11
|
const delete_file_1 = require("../definitions/delete-file");
|
|
12
|
+
const helpers_1 = require("../file-operations/shared/helpers");
|
|
12
13
|
exports.deleteFileTool = {
|
|
13
14
|
...delete_file_1.deleteFileTool,
|
|
14
15
|
execute: async ({ input, repoPath, collectArtifacts, logger, }) => {
|
|
15
16
|
try {
|
|
16
|
-
|
|
17
|
+
// Normalize the path to support both /repo/... and relative paths
|
|
18
|
+
const normalizedPath = (0, helpers_1.normalizePath)(input.path);
|
|
19
|
+
const filePath = path_1.default.join(repoPath, normalizedPath);
|
|
17
20
|
// Validate that the file exists and is actually a file (not a directory)
|
|
18
21
|
try {
|
|
19
22
|
const stats = await (0, promises_1.stat)(filePath);
|
|
20
23
|
if (!stats.isFile()) {
|
|
21
24
|
return {
|
|
22
25
|
isError: true,
|
|
23
|
-
result: `Error: '${
|
|
26
|
+
result: `Error: '${normalizedPath}' is not a file. Use a different tool to delete directories.`,
|
|
24
27
|
};
|
|
25
28
|
}
|
|
26
29
|
}
|
|
27
30
|
catch {
|
|
28
31
|
return {
|
|
29
32
|
isError: true,
|
|
30
|
-
result: `Error: File '${
|
|
33
|
+
result: `Error: File '${normalizedPath}' does not exist.`,
|
|
31
34
|
};
|
|
32
35
|
}
|
|
33
36
|
const resolvedPath = path_1.default.resolve(filePath);
|
|
@@ -40,18 +43,18 @@ exports.deleteFileTool = {
|
|
|
40
43
|
}
|
|
41
44
|
await (0, promises_1.unlink)(filePath);
|
|
42
45
|
// Stage the deletion
|
|
43
|
-
(0, child_process_1.execSync)(`git add "${
|
|
46
|
+
(0, child_process_1.execSync)(`git add "${normalizedPath}"`, { cwd: repoPath });
|
|
44
47
|
// Run TypeScript compilation check
|
|
45
48
|
const tscResult = await (0, web_1.runTypescriptCompiler)(repoPath);
|
|
46
49
|
if (!tscResult.success) {
|
|
47
50
|
return {
|
|
48
|
-
result: `File ${
|
|
51
|
+
result: `File ${normalizedPath} has been deleted. However, type checks are failing with errors:\n\n${tscResult.errors.join("\n")}`,
|
|
49
52
|
isError: false,
|
|
50
53
|
};
|
|
51
54
|
}
|
|
52
55
|
return {
|
|
53
56
|
isError: false,
|
|
54
|
-
result: `Successfully deleted file: ${
|
|
57
|
+
result: `Successfully deleted file: ${normalizedPath}`,
|
|
55
58
|
};
|
|
56
59
|
}
|
|
57
60
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnosis-fetcher.d.ts","sourceRoot":"","sources":["../../src/tools/diagnosis-fetcher.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"diagnosis-fetcher.d.ts","sourceRoot":"","sources":["../../src/tools/diagnosis-fetcher.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uCAAuC,CAAC;AAmBlE,eAAO,MAAM,wBAAwB,EAAE,IAsItC,CAAC"}
|
|
@@ -7,6 +7,9 @@ const DiagnosisSchema = zod_1.z.object({
|
|
|
7
7
|
diagnosisId: zod_1.z
|
|
8
8
|
.string()
|
|
9
9
|
.describe("12 character random string that identifies a failing test case in a test run"),
|
|
10
|
+
projectSlug: zod_1.z
|
|
11
|
+
.string()
|
|
12
|
+
.describe("The project slug extracted from the URL path, e.g. 'my-project' from https://dash.empirical.run/my-project/..."),
|
|
10
13
|
});
|
|
11
14
|
exports.fetchDiagnosisReportTool = {
|
|
12
15
|
schema: {
|
|
@@ -42,7 +45,7 @@ In the above, the diagnosis id is after the double hyphen, which is "ULRHHNwiGZ2
|
|
|
42
45
|
needsBrowser: false,
|
|
43
46
|
isInlineTool: true,
|
|
44
47
|
execute: async ({ input, apiClient }) => {
|
|
45
|
-
const { diagnosisId } = input;
|
|
48
|
+
const { diagnosisId, projectSlug } = input;
|
|
46
49
|
let data = null;
|
|
47
50
|
if (!apiClient) {
|
|
48
51
|
throw new Error("Dashboard API client is not available.");
|
|
@@ -61,7 +64,18 @@ In the above, the diagnosis id is after the double hyphen, which is "ULRHHNwiGZ2
|
|
|
61
64
|
result: `Failed to fetch diagnosis details: ${error instanceof Error ? error.message : String(error)}`,
|
|
62
65
|
};
|
|
63
66
|
}
|
|
64
|
-
const { test_case, diagnosis } = data.data;
|
|
67
|
+
const { test_case, diagnosis, test_run } = data.data;
|
|
68
|
+
const repoName = projectSlug.includes("-tests")
|
|
69
|
+
? projectSlug
|
|
70
|
+
: `${projectSlug}-tests`;
|
|
71
|
+
let testRunEnriched = null;
|
|
72
|
+
try {
|
|
73
|
+
const testRunData = await apiClient.request(`/api/test-runs/${test_run.id}?repo_name=${repoName}`, { method: "GET" });
|
|
74
|
+
testRunEnriched = testRunData.data;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Ignore errors fetching enriched test run data
|
|
78
|
+
}
|
|
65
79
|
const project = diagnosis.test_project || "unknown";
|
|
66
80
|
const retries = diagnosis.retry_details?.retries;
|
|
67
81
|
const retryInfo = retries?.reduce((acc, current) => {
|
|
@@ -75,6 +89,18 @@ In the above, the diagnosis id is after the double hyphen, which is "ULRHHNwiGZ2
|
|
|
75
89
|
return `${acc}\n\n## Playwright project: ${project}\n\n${JSON.stringify(value, null, 2)}`;
|
|
76
90
|
}, "");
|
|
77
91
|
}
|
|
92
|
+
const enrichedTestRun = testRunEnriched?.test_run?.testRun;
|
|
93
|
+
const environmentInfo = enrichedTestRun?.environment_name
|
|
94
|
+
? `## Environment
|
|
95
|
+
- Name: ${enrichedTestRun.environment_name}
|
|
96
|
+
- Slug: ${enrichedTestRun.environment_slug}`
|
|
97
|
+
: "";
|
|
98
|
+
const buildInfo = enrichedTestRun?.build_url
|
|
99
|
+
? `## Build info
|
|
100
|
+
- Build URL: ${enrichedTestRun.build_url}
|
|
101
|
+
- Git branch: ${enrichedTestRun.build_branch}
|
|
102
|
+
- Git commit: ${enrichedTestRun.commit}`
|
|
103
|
+
: "";
|
|
78
104
|
const markdownResponse = `
|
|
79
105
|
# Test Case Information
|
|
80
106
|
- **Name**: ${test_case.name}
|
|
@@ -82,6 +108,18 @@ In the above, the diagnosis id is after the double hyphen, which is "ULRHHNwiGZ2
|
|
|
82
108
|
- **File path**: tests/${test_case.file_path}
|
|
83
109
|
- **Playwright project**: ${project}
|
|
84
110
|
|
|
111
|
+
# Test Run #${test_run.id}
|
|
112
|
+
|
|
113
|
+
## Info
|
|
114
|
+
- Status: ${test_run.state}
|
|
115
|
+
- Started at: ${test_run.run_started_at}
|
|
116
|
+
- Ended at: ${test_run.run_ended_at}
|
|
117
|
+
- Duration: ${test_run.duration} seconds
|
|
118
|
+
|
|
119
|
+
${environmentInfo}
|
|
120
|
+
|
|
121
|
+
${buildInfo}
|
|
122
|
+
|
|
85
123
|
# What happened in this test run
|
|
86
124
|
|
|
87
125
|
${retryInfo}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/fetch-file/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,IAAI,EAGL,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/fetch-file/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,IAAI,EAGL,MAAM,uCAAuC,CAAC;AAG/C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA2HxB,QAAA,MAAM,eAAe;;iBAEnB,CAAC;AAEH,eAAO,MAAM,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAmJ/D,CAAC"}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.fetchFileTool = void 0;
|
|
7
|
+
const fs_1 = require("fs");
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
4
9
|
const zod_1 = require("zod");
|
|
5
10
|
const url_validation_1 = require("../../utils/url-validation");
|
|
6
11
|
const utils_1 = require("./utils");
|
|
@@ -11,6 +16,88 @@ const SUPPORTED_IMAGE_TYPES = [
|
|
|
11
16
|
"image/webp",
|
|
12
17
|
];
|
|
13
18
|
const SUPPORTED_TEXT_TYPES = ["text/markdown", "text/plain"];
|
|
19
|
+
function applyLineLimitIfNeeded(text, featureFlags, url) {
|
|
20
|
+
const isLimitEnabled = featureFlags.includes("useLimitOnFetchFile");
|
|
21
|
+
if (!isLimitEnabled) {
|
|
22
|
+
return text;
|
|
23
|
+
}
|
|
24
|
+
const lines = text.split("\n");
|
|
25
|
+
if (lines.length <= 100) {
|
|
26
|
+
return text;
|
|
27
|
+
}
|
|
28
|
+
const trimmedText = lines.slice(0, 100).join("\n");
|
|
29
|
+
const message = `\n\n[Output trimmed: This file contains ${lines.length} lines, showing first 100 lines. To get the full output, use the Bash tool to fetch via curl and search the response: curl "${url}"]`;
|
|
30
|
+
return trimmedText + message;
|
|
31
|
+
}
|
|
32
|
+
async function handleLocalFile(filePath, logger, featureFlags) {
|
|
33
|
+
const ext = path_1.default.extname(filePath).toLowerCase();
|
|
34
|
+
const isImage = [".png", ".jpg", ".jpeg", ".gif", ".webp"].includes(ext);
|
|
35
|
+
const isText = [".md", ".txt", ".markdown"].includes(ext);
|
|
36
|
+
if (!isImage && !isText) {
|
|
37
|
+
return {
|
|
38
|
+
result: `Unsupported file type: ${ext}. Must be an image (PNG, JPEG, GIF, WebP) or text file (.md, .txt).`,
|
|
39
|
+
isError: true,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const buffer = await fs_1.promises.readFile(filePath);
|
|
44
|
+
if (isImage) {
|
|
45
|
+
const contentType = ext === ".png"
|
|
46
|
+
? "image/png"
|
|
47
|
+
: ext === ".gif"
|
|
48
|
+
? "image/gif"
|
|
49
|
+
: ext === ".webp"
|
|
50
|
+
? "image/webp"
|
|
51
|
+
: "image/jpeg";
|
|
52
|
+
const processedBuffer = await (0, utils_1.downscaleImageIfNeeded)(buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength), logger);
|
|
53
|
+
const base64 = Buffer.from(processedBuffer).toString("base64");
|
|
54
|
+
logger.info("Successfully read local image file", {
|
|
55
|
+
tool: "fetchFileTool",
|
|
56
|
+
filePath,
|
|
57
|
+
contentType,
|
|
58
|
+
size: processedBuffer.byteLength,
|
|
59
|
+
});
|
|
60
|
+
return {
|
|
61
|
+
result: [
|
|
62
|
+
{
|
|
63
|
+
type: contentType,
|
|
64
|
+
base64Data: base64,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
isError: false,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
const text = buffer.toString("utf-8");
|
|
72
|
+
const processedText = applyLineLimitIfNeeded(text, featureFlags, `file://${filePath}`);
|
|
73
|
+
logger.info("Successfully read local text file", {
|
|
74
|
+
tool: "fetchFileTool",
|
|
75
|
+
filePath,
|
|
76
|
+
size: text.length,
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
result: [
|
|
80
|
+
{
|
|
81
|
+
type: "text",
|
|
82
|
+
text: processedText,
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
isError: false,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (fileError) {
|
|
90
|
+
logger.error("Failed to read local file", {
|
|
91
|
+
tool: "fetchFileTool",
|
|
92
|
+
filePath,
|
|
93
|
+
error: fileError.message,
|
|
94
|
+
});
|
|
95
|
+
return {
|
|
96
|
+
result: `Failed to read file: ${fileError.message}`,
|
|
97
|
+
isError: true,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
14
101
|
const fetchFileSchema = zod_1.z.object({
|
|
15
102
|
url: zod_1.z.string(),
|
|
16
103
|
});
|
|
@@ -20,6 +107,10 @@ exports.fetchFileTool = {
|
|
|
20
107
|
description: `Use this tool to fetch file data from any valid URL that responds with an image (PNG, JPEG, GIF, WebP) or markdown file.
|
|
21
108
|
For images, it returns the image in base64 format for you to view or analyse. For markdown files, it returns the text content for you to read and process.
|
|
22
109
|
|
|
110
|
+
## Supported URL schemes
|
|
111
|
+
- \`https://\` - Fetch from remote URLs
|
|
112
|
+
- \`file://\` - Fetch from local filesystem (e.g., \`file:///path/to/image.png\`)
|
|
113
|
+
|
|
23
114
|
## Caveats
|
|
24
115
|
1. This will not work to fetch markdown files from a repo due to access control issues. Use file view tools for that.
|
|
25
116
|
|
|
@@ -27,18 +118,25 @@ For images, it returns the image in base64 format for you to view or analyse. Fo
|
|
|
27
118
|
1. Understand a test report (for the runTest tool) by fetching screenshots and error context files (.md) which contain the accessibility tree of the page at the
|
|
28
119
|
time of test failures. Both of these are available in the attachments section of the test report from the runTest tool call.
|
|
29
120
|
|
|
30
|
-
2. While adding new tests, if the user message contains image URLs, use this tool to fetch the images, and understand the steps that the user is looking to cover
|
|
121
|
+
2. While adding new tests, if the user message contains image URLs, use this tool to fetch the images, and understand the steps that the user is looking to cover.
|
|
122
|
+
|
|
123
|
+
3. View screenshots extracted by the traceUtils tool (which returns file:// URLs).`,
|
|
31
124
|
parameters: fetchFileSchema,
|
|
32
125
|
},
|
|
33
126
|
needsBrowser: false,
|
|
34
127
|
isInlineTool: true,
|
|
35
|
-
execute: async ({ input, logger, }) => {
|
|
128
|
+
execute: async ({ input, logger, featureFlags, }) => {
|
|
36
129
|
const { url } = input;
|
|
37
130
|
logger.info("Starting file fetch", {
|
|
38
131
|
tool: "fetchFileTool",
|
|
39
132
|
url,
|
|
40
133
|
});
|
|
41
134
|
try {
|
|
135
|
+
// Handle file:// URLs
|
|
136
|
+
if (url.startsWith("file://")) {
|
|
137
|
+
const filePath = url.replace("file://", "");
|
|
138
|
+
return handleLocalFile(filePath, logger, featureFlags);
|
|
139
|
+
}
|
|
42
140
|
const headResponse = await (0, url_validation_1.validateUrlAccess)(url);
|
|
43
141
|
if (!headResponse.ok) {
|
|
44
142
|
logger.error("Failed to fetch file", {
|
|
@@ -105,6 +203,7 @@ time of test failures. Both of these are available in the attachments section of
|
|
|
105
203
|
else {
|
|
106
204
|
// Handle text/markdown files
|
|
107
205
|
const text = await contentResponse.text();
|
|
206
|
+
const processedText = applyLineLimitIfNeeded(text, featureFlags, url);
|
|
108
207
|
logger.info("Successfully fetched text file", {
|
|
109
208
|
tool: "fetchFileTool",
|
|
110
209
|
url,
|
|
@@ -115,7 +214,7 @@ time of test failures. Both of these are available in the attachments section of
|
|
|
115
214
|
result: [
|
|
116
215
|
{
|
|
117
216
|
type: "text",
|
|
118
|
-
text:
|
|
217
|
+
text: processedText,
|
|
119
218
|
},
|
|
120
219
|
],
|
|
121
220
|
isError: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/file-operations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EACL,gBAAgB,EAChB,IAAI,EAEJ,UAAU,EACX,MAAM,uCAAuC,CAAC;AAQ/C,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/file-operations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EACL,gBAAgB,EAChB,IAAI,EAEJ,UAAU,EACX,MAAM,uCAAuC,CAAC;AAQ/C,OAAO,EAAiB,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAGxE;;;GAGG;AACH,iBAAe,wBAAwB,CAAC,EACtC,KAAK,EACL,QAAQ,EACR,gBAAgB,EAChB,SAAS,GACV,EAAE;IACD,KAAK,EAAE,qBAAqB,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,SAAS,CAAC,EAAE,mBAAmB,CAAC;CACjC,GAAG,OAAO,CAAC,UAAU,CAAC,CAqDtB;AAgFD,QAAA,MAAM,eAAe,EAAE,IAAI,EAK1B,CAAC;AAEF,QAAA,MAAM,aAAa,EAAE,IAAI,EAAmB,CAAC;AAE7C,OAAO,EAAE,wBAAwB,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -10,6 +10,7 @@ const str_replace_editor_1 = require("../definitions/str_replace_editor");
|
|
|
10
10
|
const create_1 = require("./create");
|
|
11
11
|
const insert_1 = require("./insert");
|
|
12
12
|
const replace_1 = require("./replace");
|
|
13
|
+
const helpers_1 = require("./shared/helpers");
|
|
13
14
|
const view_1 = require("./view");
|
|
14
15
|
/**
|
|
15
16
|
* Our implementation of Claude's built-in text editor tool
|
|
@@ -17,8 +18,9 @@ const view_1 = require("./view");
|
|
|
17
18
|
*/
|
|
18
19
|
async function strReplaceEditorExecutor({ input, repoPath, collectArtifacts, apiClient, }) {
|
|
19
20
|
const repoDir = repoPath;
|
|
20
|
-
|
|
21
|
-
const
|
|
21
|
+
// Normalize the path to support both /repo/... and relative paths
|
|
22
|
+
const normalizedFilePath = (0, helpers_1.normalizePath)(input.path);
|
|
23
|
+
const absoluteFilePath = path_1.default.join(repoDir, normalizedFilePath);
|
|
22
24
|
const repoName = path_1.default.basename(repoPath);
|
|
23
25
|
try {
|
|
24
26
|
switch (input.command) {
|
|
@@ -32,7 +34,7 @@ async function strReplaceEditorExecutor({ input, repoPath, collectArtifacts, api
|
|
|
32
34
|
case "create":
|
|
33
35
|
return (0, create_1.fileCreateExecutor)({
|
|
34
36
|
input,
|
|
35
|
-
filePath,
|
|
37
|
+
filePath: normalizedFilePath,
|
|
36
38
|
absoluteFilePath,
|
|
37
39
|
repoDir,
|
|
38
40
|
collectArtifacts,
|
|
@@ -40,7 +42,7 @@ async function strReplaceEditorExecutor({ input, repoPath, collectArtifacts, api
|
|
|
40
42
|
case "str_replace":
|
|
41
43
|
return (0, replace_1.fileStrReplaceExecutor)({
|
|
42
44
|
input,
|
|
43
|
-
filePath,
|
|
45
|
+
filePath: normalizedFilePath,
|
|
44
46
|
absoluteFilePath,
|
|
45
47
|
repoDir,
|
|
46
48
|
collectArtifacts,
|
|
@@ -48,7 +50,7 @@ async function strReplaceEditorExecutor({ input, repoPath, collectArtifacts, api
|
|
|
48
50
|
case "insert":
|
|
49
51
|
return (0, insert_1.fileInsertExecutor)({
|
|
50
52
|
input,
|
|
51
|
-
filePath,
|
|
53
|
+
filePath: normalizedFilePath,
|
|
52
54
|
absoluteFilePath,
|
|
53
55
|
repoDir,
|
|
54
56
|
collectArtifacts,
|
|
@@ -8,6 +8,19 @@ export interface StrReplaceInputParams {
|
|
|
8
8
|
insert_line?: number;
|
|
9
9
|
insert_text?: string;
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Normalizes a path by removing the /repo/ prefix if present.
|
|
13
|
+
* This supports both absolute paths (/repo/...) and relative paths.
|
|
14
|
+
*
|
|
15
|
+
* @param filePath - The path to normalize (can be /repo/path/to/file or path/to/file)
|
|
16
|
+
* @returns The normalized relative path from repository root
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* normalizePath('/repo/tests/foo.spec.ts') // returns 'tests/foo.spec.ts'
|
|
20
|
+
* normalizePath('tests/foo.spec.ts') // returns 'tests/foo.spec.ts'
|
|
21
|
+
* normalizePath('/repo/./tests/foo.spec.ts') // returns 'tests/foo.spec.ts'
|
|
22
|
+
*/
|
|
23
|
+
export declare function normalizePath(filePath: string): string;
|
|
11
24
|
export declare function formatLinesWithNumbers(content: string, viewRange?: [number, number]): string;
|
|
12
25
|
export declare function isBinaryFile(filePath: string): boolean;
|
|
13
26
|
export declare function getUniqueOccurences(contents: string, old_str: string): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../src/tools/file-operations/shared/helpers.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IAGb,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAG9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IAGjB,SAAS,CAAC,EAAE,MAAM,CAAC;IAKnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,MAAM,CAaR;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CA2DtD;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,EAAE,CAyDjD"}
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../src/tools/file-operations/shared/helpers.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IAGb,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAG9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IAGjB,SAAS,CAAC,EAAE,MAAM,CAAC;IAKnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAatD;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,MAAM,CAaR;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CA2DtD;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,EAAE,CAyDjD"}
|