@empiricalrun/test-gen 0.76.0 → 0.78.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 +47 -0
- package/dist/agent/base/index.d.ts +25 -21
- package/dist/agent/base/index.d.ts.map +1 -1
- package/dist/agent/base/index.js +50 -37
- package/dist/agent/browsing/run.d.ts +1 -2
- package/dist/agent/browsing/run.d.ts.map +1 -1
- package/dist/agent/browsing/run.js +3 -9
- package/dist/agent/browsing/utils.d.ts +2 -9
- package/dist/agent/browsing/utils.d.ts.map +1 -1
- package/dist/agent/browsing/utils.js +5 -109
- package/dist/agent/chat/agent-loop.d.ts +5 -5
- package/dist/agent/chat/agent-loop.d.ts.map +1 -1
- package/dist/agent/chat/agent-loop.js +3 -8
- package/dist/agent/chat/exports.d.ts +6 -5
- package/dist/agent/chat/exports.d.ts.map +1 -1
- package/dist/agent/chat/exports.js +4 -9
- package/dist/agent/chat/index.d.ts +2 -2
- package/dist/agent/chat/index.d.ts.map +1 -1
- package/dist/agent/chat/index.js +23 -35
- package/dist/agent/chat/models.d.ts +0 -2
- package/dist/agent/chat/models.d.ts.map +1 -1
- package/dist/agent/chat/models.js +12 -26
- package/dist/agent/chat/prompt/pw-utils-docs.d.ts +1 -1
- package/dist/agent/chat/prompt/pw-utils-docs.d.ts.map +1 -1
- package/dist/agent/chat/prompt/pw-utils-docs.js +52 -0
- package/dist/agent/chat/prompt/repo.d.ts.map +1 -1
- package/dist/agent/chat/prompt/repo.js +11 -22
- package/dist/agent/chat/prompt/test-case-def.d.ts +2 -0
- package/dist/agent/chat/prompt/test-case-def.d.ts.map +1 -0
- package/dist/agent/chat/prompt/test-case-def.js +44 -0
- package/dist/agent/chat/state.d.ts +8 -14
- package/dist/agent/chat/state.d.ts.map +1 -1
- package/dist/agent/chat/state.js +15 -60
- package/dist/agent/chat/utils.d.ts +2 -2
- package/dist/agent/chat/utils.d.ts.map +1 -1
- package/dist/agent/chat/utils.js +14 -7
- package/dist/agent/cli.d.ts.map +1 -1
- package/dist/agent/cli.js +49 -58
- package/dist/agent/code-review/executor/index.d.ts +5 -0
- package/dist/agent/code-review/executor/index.d.ts.map +1 -0
- package/dist/agent/code-review/executor/index.js +13 -0
- package/dist/agent/code-review/index.d.ts +8 -3
- package/dist/agent/code-review/index.d.ts.map +1 -1
- package/dist/agent/code-review/index.js +118 -21
- package/dist/agent/code-review/parser.d.ts +5 -0
- package/dist/agent/code-review/parser.d.ts.map +1 -0
- package/dist/agent/code-review/parser.js +70 -0
- package/dist/agent/code-review/types.d.ts +36 -0
- package/dist/agent/code-review/types.d.ts.map +1 -0
- package/dist/agent/code-review/types.js +13 -0
- package/dist/agent/cua/index.d.ts.map +1 -1
- package/dist/agent/cua/index.js +18 -2
- package/dist/agent/cua/model.d.ts.map +1 -1
- package/dist/agent/cua/model.js +4 -1
- package/dist/agent/cua/pw-codegen/pw-pause/index.d.ts.map +1 -1
- package/dist/agent/triage/index.d.ts +3 -3
- package/dist/agent/triage/index.d.ts.map +1 -1
- package/dist/agent/triage/index.js +16 -20
- package/dist/agent/video-analysis/executor/index.d.ts +5 -0
- package/dist/agent/video-analysis/executor/index.d.ts.map +1 -0
- package/dist/agent/video-analysis/executor/index.js +10 -0
- package/dist/agent/video-analysis/index.d.ts +2 -2
- package/dist/agent/video-analysis/index.d.ts.map +1 -1
- package/dist/agent/video-analysis/index.js +38 -13
- package/dist/artifacts/index.d.ts +1 -1
- package/dist/artifacts/index.d.ts.map +1 -1
- package/dist/artifacts/index.js +3 -1
- package/dist/artifacts/utils.d.ts.map +1 -1
- package/dist/bin/index.js +11 -21
- package/dist/constants/index.d.ts +14 -0
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/index.js +33 -1
- package/dist/file/server.d.ts +1 -3
- package/dist/file/server.d.ts.map +1 -1
- package/dist/file/server.js +0 -13
- package/dist/file-info/adapters/file-system/index.d.ts.map +1 -1
- package/dist/file-info/adapters/file-system/reader.d.ts.map +1 -1
- package/dist/file-info/adapters/file-system/reader.js +8 -1
- package/dist/file-info/adapters/github/index.d.ts.map +1 -1
- package/dist/file-info/adapters/github/reader.d.ts +1 -1
- package/dist/file-info/adapters/github/reader.d.ts.map +1 -1
- package/dist/file-info/adapters/github/reader.js +8 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/tools/analyse-video/index.d.ts +5 -0
- package/dist/tools/analyse-video/index.d.ts.map +1 -0
- package/dist/tools/analyse-video/index.js +56 -0
- package/dist/tools/create-pull-request/index.js +4 -6
- package/dist/tools/create-pull-request/utils.d.ts +1 -1
- package/dist/tools/definitions/{fetch-video-analysis.d.ts → analyse-video.d.ts} +17 -12
- package/dist/tools/definitions/analyse-video.d.ts.map +1 -0
- package/dist/tools/definitions/analyse-video.js +60 -0
- package/dist/tools/definitions/review-pull-request.d.ts +3 -0
- package/dist/tools/definitions/review-pull-request.d.ts.map +1 -0
- package/dist/tools/definitions/review-pull-request.js +16 -0
- package/dist/tools/definitions/str_replace_editor.d.ts +1 -0
- package/dist/tools/definitions/str_replace_editor.d.ts.map +1 -1
- package/dist/tools/definitions/str_replace_editor.js +4 -1
- package/dist/tools/definitions/test-gen-browser.d.ts +0 -3
- package/dist/tools/definitions/test-gen-browser.d.ts.map +1 -1
- package/dist/tools/definitions/test-gen-browser.js +33 -8
- package/dist/tools/delete-file/index.d.ts.map +1 -1
- package/dist/tools/delete-file/index.js +1 -19
- package/dist/tools/executor/base.d.ts +32 -0
- package/dist/tools/executor/base.d.ts.map +1 -0
- package/dist/tools/executor/base.js +131 -0
- package/dist/tools/executor/index.d.ts +3 -22
- package/dist/tools/executor/index.d.ts.map +1 -1
- package/dist/tools/executor/index.js +7 -100
- package/dist/tools/executor/utils/checkpoint.d.ts +1 -1
- package/dist/tools/executor/utils/checkpoint.d.ts.map +1 -1
- package/dist/tools/executor/utils/checkpoint.js +6 -2
- package/dist/tools/executor/utils/git.d.ts +2 -2
- package/dist/tools/executor/utils/git.d.ts.map +1 -1
- package/dist/tools/executor/utils/git.js +7 -3
- package/dist/tools/executor/utils/index.d.ts +5 -3
- package/dist/tools/executor/utils/index.d.ts.map +1 -1
- package/dist/tools/executor/utils/index.js +23 -2
- package/dist/tools/fetch-session-diff/index.js +2 -2
- package/dist/tools/file-operations/create.d.ts.map +1 -1
- package/dist/tools/file-operations/create.js +1 -4
- package/dist/tools/file-operations/index.d.ts +2 -1
- package/dist/tools/file-operations/index.d.ts.map +1 -1
- package/dist/tools/file-operations/index.js +4 -1
- package/dist/tools/file-operations/insert.d.ts +1 -2
- package/dist/tools/file-operations/insert.d.ts.map +1 -1
- package/dist/tools/file-operations/insert.js +1 -4
- package/dist/tools/file-operations/replace.d.ts.map +1 -1
- package/dist/tools/file-operations/replace.js +21 -25
- package/dist/tools/file-operations/shared/helpers.d.ts +3 -5
- package/dist/tools/file-operations/shared/helpers.d.ts.map +1 -1
- package/dist/tools/file-operations/shared/helpers.js +1 -5
- package/dist/tools/grep/index.d.ts.map +1 -1
- package/dist/tools/grep/index.js +18 -11
- package/dist/tools/index.d.ts +5 -5
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +17 -16
- package/dist/tools/merge-conflicts/index.d.ts.map +1 -1
- package/dist/tools/merge-conflicts/index.js +1 -1
- package/dist/tools/rename-file/index.js +1 -1
- package/dist/tools/review-pull-request/index.d.ts.map +1 -1
- package/dist/tools/review-pull-request/index.js +44 -65
- package/dist/tools/run-test.d.ts.map +1 -1
- package/dist/tools/run-test.js +25 -3
- package/dist/tools/test-gen-browser.d.ts.map +1 -1
- package/dist/tools/test-gen-browser.js +51 -47
- package/dist/tools/upgrade-packages/index.d.ts.map +1 -1
- package/dist/tools/upgrade-packages/index.js +4 -0
- package/dist/tools/upgrade-packages/utils.d.ts +1 -0
- package/dist/tools/upgrade-packages/utils.d.ts.map +1 -1
- package/dist/tools/upgrade-packages/utils.js +1 -0
- package/dist/trace-utils/index.d.ts +1 -1
- package/dist/trace-utils/index.d.ts.map +1 -1
- package/dist/trace-utils/index.js +1 -1
- package/dist/utils/dedup/dedup-image.d.ts +22 -0
- package/dist/utils/dedup/dedup-image.d.ts.map +1 -0
- package/dist/utils/dedup/dedup-image.js +26 -0
- package/dist/utils/dedup/find-threshold.d.ts +2 -0
- package/dist/utils/dedup/find-threshold.d.ts.map +1 -0
- package/dist/utils/dedup/find-threshold.js +42 -0
- package/dist/utils/hash.d.ts +2 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +24 -0
- package/dist/utils/model.d.ts +1 -1
- package/dist/utils/model.d.ts.map +1 -1
- package/dist/utils/model.js +7 -5
- package/dist/utils/repo-tree.d.ts +0 -1
- package/dist/utils/repo-tree.d.ts.map +1 -1
- package/dist/utils/repo-tree.js +2 -14
- package/dist/utils/slug.js +1 -1
- package/dist/video-core/agent-orchestrator.d.ts +13 -0
- package/dist/video-core/agent-orchestrator.d.ts.map +1 -0
- package/dist/video-core/agent-orchestrator.js +59 -0
- package/dist/video-core/index.d.ts +39 -0
- package/dist/video-core/index.d.ts.map +1 -0
- package/dist/video-core/index.js +134 -0
- package/dist/video-core/model-limits.d.ts +4 -0
- package/dist/video-core/model-limits.d.ts.map +1 -0
- package/dist/video-core/model-limits.js +73 -0
- package/dist/video-core/storage-manager.d.ts +5 -0
- package/dist/video-core/storage-manager.d.ts.map +1 -0
- package/dist/video-core/storage-manager.js +62 -0
- package/dist/video-core/types.d.ts +13 -0
- package/dist/video-core/types.d.ts.map +1 -0
- package/dist/video-core/types.js +2 -0
- package/dist/video-core/utils.d.ts +15 -0
- package/dist/video-core/utils.d.ts.map +1 -0
- package/dist/video-core/utils.js +194 -0
- package/dist/video-core/xml-parser.d.ts +3 -0
- package/dist/video-core/xml-parser.d.ts.map +1 -0
- package/dist/video-core/xml-parser.js +27 -0
- package/package.json +6 -6
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/agent/chat/prompt/index.d.ts +0 -6
- package/dist/agent/chat/prompt/index.d.ts.map +0 -1
- package/dist/agent/chat/prompt/index.js +0 -200
- package/dist/agent/code-review/prompt.d.ts +0 -2
- package/dist/agent/code-review/prompt.d.ts.map +0 -1
- package/dist/agent/code-review/prompt.js +0 -55
- package/dist/agent/diagnosis-agent/index.d.ts +0 -11
- package/dist/agent/diagnosis-agent/index.d.ts.map +0 -1
- package/dist/agent/diagnosis-agent/index.js +0 -88
- package/dist/agent/diagnosis-agent/strict-mode-violation.d.ts +0 -10
- package/dist/agent/diagnosis-agent/strict-mode-violation.d.ts.map +0 -1
- package/dist/agent/diagnosis-agent/strict-mode-violation.js +0 -30
- package/dist/tools/definitions/extract-frames-from-video.d.ts +0 -39
- package/dist/tools/definitions/extract-frames-from-video.d.ts.map +0 -1
- package/dist/tools/definitions/extract-frames-from-video.js +0 -60
- package/dist/tools/definitions/fetch-video-analysis.d.ts.map +0 -1
- package/dist/tools/definitions/fetch-video-analysis.js +0 -61
- package/dist/tools/extract-frames-from-video/index.d.ts +0 -7
- package/dist/tools/extract-frames-from-video/index.d.ts.map +0 -1
- package/dist/tools/extract-frames-from-video/index.js +0 -145
- package/dist/tools/fetch-video-analysis/index.d.ts +0 -5
- package/dist/tools/fetch-video-analysis/index.d.ts.map +0 -1
- package/dist/tools/fetch-video-analysis/index.js +0 -149
- package/dist/tools/fetch-video-analysis/open-ai.d.ts +0 -6
- package/dist/tools/fetch-video-analysis/open-ai.d.ts.map +0 -1
- package/dist/tools/fetch-video-analysis/open-ai.js +0 -37
- package/dist/tools/fetch-video-analysis/utils.d.ts +0 -16
- package/dist/tools/fetch-video-analysis/utils.d.ts.map +0 -1
- package/dist/tools/fetch-video-analysis/utils.js +0 -121
- package/dist/tools/fetch-video-analysis/video-analysis.d.ts +0 -7
- package/dist/tools/fetch-video-analysis/video-analysis.d.ts.map +0 -1
- package/dist/tools/fetch-video-analysis/video-analysis.js +0 -70
- package/dist/tools/file-operations/shared/git-helper.d.ts +0 -4
- package/dist/tools/file-operations/shared/git-helper.d.ts.map +0 -1
- package/dist/tools/file-operations/shared/git-helper.js +0 -29
- package/dist/utils/dedup-image-fs.d.ts +0 -27
- package/dist/utils/dedup-image-fs.d.ts.map +0 -1
- package/dist/utils/dedup-image-fs.js +0 -88
- package/dist/utils/dedup-image.d.ts +0 -25
- package/dist/utils/dedup-image.d.ts.map +0 -1
- package/dist/utils/dedup-image.js +0 -80
- package/dist/utils/local-ffmpeg-client.d.ts +0 -27
- package/dist/utils/local-ffmpeg-client.d.ts.map +0 -1
- package/dist/utils/local-ffmpeg-client.js +0 -299
- package/eslint.config.mjs +0 -43
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.uploadSummaryToR2 = exports.uploadFramesToR2 = void 0;
|
|
4
|
+
exports.uploadChatStateToR2 = uploadChatStateToR2;
|
|
5
|
+
const r2_uploader_1 = require("@empiricalrun/r2-uploader");
|
|
6
|
+
const uploadToR2 = async (files, videoUrlHash) => {
|
|
7
|
+
const label = `video-analysis-upload:${videoUrlHash}`;
|
|
8
|
+
const start = Date.now();
|
|
9
|
+
console.log(`[${label}] preparing ${files.length} files for upload...`);
|
|
10
|
+
console.log(`[${label}] starting upload of ${files.length} files to video-analysis/${videoUrlHash}/...`);
|
|
11
|
+
const interval = setInterval(() => {
|
|
12
|
+
const secs = Math.round((Date.now() - start) / 1000);
|
|
13
|
+
console.log(`[${label}] uploading... ${secs}s elapsed`);
|
|
14
|
+
}, 1000);
|
|
15
|
+
try {
|
|
16
|
+
await (0, r2_uploader_1.uploadInMemoryFiles)({
|
|
17
|
+
files,
|
|
18
|
+
destinationDir: videoUrlHash,
|
|
19
|
+
uploadBucket: "video-analysis",
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
finally {
|
|
23
|
+
clearInterval(interval);
|
|
24
|
+
const secs = Math.round((Date.now() - start) / 1000);
|
|
25
|
+
console.log(`[${label}] upload complete in ${secs}s`);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const uploadFramesToR2 = async (videoUrlHash, frames) => {
|
|
29
|
+
console.log(`[uploadFramesToR2] queuing ${frames.length} frames for upload`);
|
|
30
|
+
for (const frame of frames) {
|
|
31
|
+
(0, r2_uploader_1.sendTaskToQueue)(async () => {
|
|
32
|
+
const frameFile = {
|
|
33
|
+
buffer: Buffer.from(frame.base64, "base64"),
|
|
34
|
+
fileName: frame.fileName,
|
|
35
|
+
mimeType: "image/png",
|
|
36
|
+
};
|
|
37
|
+
await uploadToR2([frameFile], videoUrlHash);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
await (0, r2_uploader_1.waitForTaskQueueToFinish)();
|
|
41
|
+
console.log(`[uploadFramesToR2] all ${frames.length} frames uploaded`);
|
|
42
|
+
};
|
|
43
|
+
exports.uploadFramesToR2 = uploadFramesToR2;
|
|
44
|
+
const uploadSummaryToR2 = async (videoInfo) => {
|
|
45
|
+
await uploadToR2([
|
|
46
|
+
{
|
|
47
|
+
buffer: Buffer.from(JSON.stringify(videoInfo, null, 2)),
|
|
48
|
+
fileName: "summary.json",
|
|
49
|
+
mimeType: "application/json",
|
|
50
|
+
},
|
|
51
|
+
], videoInfo.analysis_id);
|
|
52
|
+
};
|
|
53
|
+
exports.uploadSummaryToR2 = uploadSummaryToR2;
|
|
54
|
+
async function uploadChatStateToR2(allMessages, videoUrlHash) {
|
|
55
|
+
await uploadToR2([
|
|
56
|
+
{
|
|
57
|
+
buffer: Buffer.from(JSON.stringify(allMessages)),
|
|
58
|
+
fileName: "chat-state.json",
|
|
59
|
+
mimeType: "application/json",
|
|
60
|
+
},
|
|
61
|
+
], videoUrlHash);
|
|
62
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { VideoAnalysisToolResponse } from "@empiricalrun/shared-types";
|
|
2
|
+
export interface AnalysisProcessingContext {
|
|
3
|
+
rawAnalysis: string;
|
|
4
|
+
artifactsPath: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ProcessedAnalysis {
|
|
7
|
+
parsedXml: VideoAnalysisToolResponse[];
|
|
8
|
+
keyFrameImagesMap: Map<string, {
|
|
9
|
+
type: "image/png";
|
|
10
|
+
base64Data: string;
|
|
11
|
+
}>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/video-core/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAE5E,MAAM,WAAW,yBAAyB;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,yBAAyB,EAAE,CAAC;IACvC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC3E"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ToolResultPart, UniqueFrameInfos, VideoAnalysisToolResponse } from "@empiricalrun/shared-types";
|
|
2
|
+
export declare const getR2BaseUrlByHash: (videoUrlHash: string) => string;
|
|
3
|
+
export declare const parseXmlSummaryToJson: (xmlContent: string) => Array<VideoAnalysisToolResponse>;
|
|
4
|
+
export declare function loadKeyFrameImages(keyFrames: string[], extractionArtifactsDir: string): Promise<Map<string, {
|
|
5
|
+
type: "image/png";
|
|
6
|
+
base64Data: string;
|
|
7
|
+
}>>;
|
|
8
|
+
export declare function createInterleavedResults(parsedAnalysis: VideoAnalysisToolResponse[], uniqueFrameInfos: UniqueFrameInfos[]): ToolResultPart[];
|
|
9
|
+
export interface VideoValidationResult {
|
|
10
|
+
isValid: boolean;
|
|
11
|
+
error?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function validateVideoAccess(videoUrl: string): Promise<VideoValidationResult>;
|
|
14
|
+
export declare function downloadVideo(videoUrl: string, outputPath: string): Promise<void>;
|
|
15
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/video-core/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,yBAAyB,EAC1B,MAAM,4BAA4B,CAAC;AAIpC,eAAO,MAAM,kBAAkB,GAAI,cAAc,MAAM,WAEtD,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,YAAY,MAAM,KACjB,KAAK,CAAC,yBAAyB,CAyCjC,CAAC;AA0DF,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EAAE,EACnB,sBAAsB,EAAE,MAAM,GAC7B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAkBjE;AAED,wBAAgB,wBAAwB,CACtC,cAAc,EAAE,yBAAyB,EAAE,EAC3C,gBAAgB,EAAE,gBAAgB,EAAE,GACnC,cAAc,EAAE,CAwClB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,qBAAqB,CAAC,CAgBhC;AAED,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAoDf"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseXmlSummaryToJson = exports.getR2BaseUrlByHash = void 0;
|
|
7
|
+
exports.loadKeyFrameImages = loadKeyFrameImages;
|
|
8
|
+
exports.createInterleavedResults = createInterleavedResults;
|
|
9
|
+
exports.validateVideoAccess = validateVideoAccess;
|
|
10
|
+
exports.downloadVideo = downloadVideo;
|
|
11
|
+
const fs_1 = require("fs");
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const getR2BaseUrlByHash = (videoUrlHash) => {
|
|
14
|
+
return `https://video-analysis.empirical.run/${videoUrlHash}/`;
|
|
15
|
+
};
|
|
16
|
+
exports.getR2BaseUrlByHash = getR2BaseUrlByHash;
|
|
17
|
+
const parseXmlSummaryToJson = (xmlContent) => {
|
|
18
|
+
const sections = [];
|
|
19
|
+
try {
|
|
20
|
+
// Find the summary block first to limit parsing scope
|
|
21
|
+
const summaryMatch = xmlContent.match(/<summary>([\s\S]*?)<\/summary>/);
|
|
22
|
+
if (!summaryMatch) {
|
|
23
|
+
return sections;
|
|
24
|
+
}
|
|
25
|
+
const summaryContent = summaryMatch[1];
|
|
26
|
+
if (!summaryContent) {
|
|
27
|
+
return sections;
|
|
28
|
+
}
|
|
29
|
+
// Extract all section blocks using matchAll to avoid infinite loop
|
|
30
|
+
const sectionMatches = Array.from(summaryContent.matchAll(/<section>([\s\S]*?)<\/section>/g) || []);
|
|
31
|
+
for (const sectionMatch of sectionMatches) {
|
|
32
|
+
const sectionContent = sectionMatch?.[1];
|
|
33
|
+
if (!sectionContent)
|
|
34
|
+
continue;
|
|
35
|
+
const keyFrameMatch = sectionContent.match(/<key_frame>(.*?)<\/key_frame>/);
|
|
36
|
+
const descriptionMatch = sectionContent.match(/<description>(.*?)<\/description>/);
|
|
37
|
+
if (keyFrameMatch?.[1] && descriptionMatch?.[1]) {
|
|
38
|
+
sections.push({
|
|
39
|
+
key_frame: keyFrameMatch[1].trim(),
|
|
40
|
+
description: descriptionMatch[1].trim(),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch (error) { }
|
|
46
|
+
return sections;
|
|
47
|
+
};
|
|
48
|
+
exports.parseXmlSummaryToJson = parseXmlSummaryToJson;
|
|
49
|
+
async function fileExists(filePath) {
|
|
50
|
+
return fs_1.promises
|
|
51
|
+
.access(filePath)
|
|
52
|
+
.then(() => true)
|
|
53
|
+
.catch(() => false);
|
|
54
|
+
}
|
|
55
|
+
// Try unique_frames directory first, then consolidated_frames as fallback
|
|
56
|
+
async function findFramePath(frameId, baseDir) {
|
|
57
|
+
const uniqueFramePath = path_1.default.join(baseDir, "unique_frames", `${frameId}.png`);
|
|
58
|
+
const consolidatedFramePath = path_1.default.join(baseDir, "frames", `${frameId}.png`);
|
|
59
|
+
if (await fileExists(uniqueFramePath)) {
|
|
60
|
+
return uniqueFramePath;
|
|
61
|
+
}
|
|
62
|
+
if (await fileExists(consolidatedFramePath)) {
|
|
63
|
+
return consolidatedFramePath;
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
async function loadFrameImage(framePath) {
|
|
68
|
+
const imageBuffer = await fs_1.promises.readFile(framePath);
|
|
69
|
+
const base64Data = imageBuffer.toString("base64");
|
|
70
|
+
return {
|
|
71
|
+
type: "image/png",
|
|
72
|
+
base64Data: base64Data,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
async function loadSingleFrame(frameId, extractionArtifactsDir) {
|
|
76
|
+
try {
|
|
77
|
+
const framePath = await findFramePath(frameId, extractionArtifactsDir);
|
|
78
|
+
if (!framePath) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
const imageData = await loadFrameImage(framePath);
|
|
82
|
+
return {
|
|
83
|
+
frameId: frameId,
|
|
84
|
+
imageData,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async function loadKeyFrameImages(keyFrames, extractionArtifactsDir) {
|
|
92
|
+
const frameImageParts = await Promise.all(keyFrames.map((frameId) => loadSingleFrame(frameId, extractionArtifactsDir)));
|
|
93
|
+
const frameImageMap = new Map();
|
|
94
|
+
frameImageParts
|
|
95
|
+
.filter((part) => part !== null)
|
|
96
|
+
.forEach(({ frameId, imageData }) => {
|
|
97
|
+
frameImageMap.set(frameId, imageData);
|
|
98
|
+
});
|
|
99
|
+
return frameImageMap;
|
|
100
|
+
}
|
|
101
|
+
function createInterleavedResults(parsedAnalysis, uniqueFrameInfos) {
|
|
102
|
+
const interleavedResults = [];
|
|
103
|
+
if (parsedAnalysis && Array.isArray(parsedAnalysis)) {
|
|
104
|
+
for (const section of parsedAnalysis) {
|
|
105
|
+
// Add section text
|
|
106
|
+
interleavedResults.push({
|
|
107
|
+
type: "text",
|
|
108
|
+
text: JSON.stringify(section),
|
|
109
|
+
});
|
|
110
|
+
// Add corresponding frame image if available
|
|
111
|
+
if (section.key_frame && uniqueFrameInfos.length > 0) {
|
|
112
|
+
const sectionFrameId = section.key_frame;
|
|
113
|
+
// Extract frame index from frameId (e.g., "frame_6" -> 6)
|
|
114
|
+
const frameNumberMatch = sectionFrameId.match(/frame_(\d+)/);
|
|
115
|
+
const frameIndex = frameNumberMatch && frameNumberMatch[1]
|
|
116
|
+
? parseInt(frameNumberMatch[1], 10)
|
|
117
|
+
: null;
|
|
118
|
+
if (frameIndex !== null) {
|
|
119
|
+
// Find the corresponding uploaded frame by index
|
|
120
|
+
const uploadedFrame = uniqueFrameInfos.find((frame) => frame.index === frameIndex);
|
|
121
|
+
if (uploadedFrame) {
|
|
122
|
+
interleavedResults.push({
|
|
123
|
+
type: "image/png",
|
|
124
|
+
url: uploadedFrame.url,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return interleavedResults;
|
|
132
|
+
}
|
|
133
|
+
async function validateVideoAccess(videoUrl) {
|
|
134
|
+
try {
|
|
135
|
+
const response = await fetch(videoUrl, { method: "HEAD" });
|
|
136
|
+
if (!response.ok) {
|
|
137
|
+
return {
|
|
138
|
+
isValid: false,
|
|
139
|
+
error: `Failed to access video at ${videoUrl}: ${response.statusText}`,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return { isValid: true };
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
return {
|
|
146
|
+
isValid: false,
|
|
147
|
+
error: `Network error accessing video: ${error instanceof Error ? error.message : String(error)}`,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
async function downloadVideo(videoUrl, outputPath) {
|
|
152
|
+
if (await fileExists(outputPath)) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const response = await fetch(videoUrl);
|
|
156
|
+
if (!response.ok) {
|
|
157
|
+
throw new Error(`Failed to download video: ${response.statusText}`);
|
|
158
|
+
}
|
|
159
|
+
const contentLength = response.headers.get("content-length");
|
|
160
|
+
const totalSize = contentLength ? parseInt(contentLength, 10) : 0;
|
|
161
|
+
if (!response.body) {
|
|
162
|
+
throw new Error("Response body is null");
|
|
163
|
+
}
|
|
164
|
+
const reader = response.body.getReader();
|
|
165
|
+
const chunks = [];
|
|
166
|
+
let downloadedSize = 0;
|
|
167
|
+
const startTime = Date.now();
|
|
168
|
+
while (true) {
|
|
169
|
+
const { done, value } = await reader.read();
|
|
170
|
+
if (done)
|
|
171
|
+
break;
|
|
172
|
+
chunks.push(value);
|
|
173
|
+
downloadedSize += value.length;
|
|
174
|
+
const elapsedSeconds = (Date.now() - startTime) / 1000;
|
|
175
|
+
const speed = elapsedSeconds > 0 ? downloadedSize / elapsedSeconds : 0;
|
|
176
|
+
const speedMBps = (speed / 1024 / 1024).toFixed(1);
|
|
177
|
+
if (totalSize > 0) {
|
|
178
|
+
const percentage = Math.round((downloadedSize / totalSize) * 100);
|
|
179
|
+
const progressBar = "█".repeat(Math.floor(percentage / 5)) +
|
|
180
|
+
"░".repeat(20 - Math.floor(percentage / 5));
|
|
181
|
+
process.stdout.write(`\r[${progressBar}] ${percentage}% (${(downloadedSize / 1024 / 1024).toFixed(1)} MB) ${speedMBps} MB/s`);
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
process.stdout.write(`\rDownloaded: ${(downloadedSize / 1024 / 1024).toFixed(1)} MB @ ${speedMBps} MB/s`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const buffer = new Uint8Array(downloadedSize);
|
|
188
|
+
let offset = 0;
|
|
189
|
+
for (const chunk of chunks) {
|
|
190
|
+
buffer.set(chunk, offset);
|
|
191
|
+
offset += chunk.length;
|
|
192
|
+
}
|
|
193
|
+
await fs_1.promises.writeFile(outputPath, buffer);
|
|
194
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xml-parser.d.ts","sourceRoot":"","sources":["../../src/video-core/xml-parser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAmBvE,wBAAsB,4BAA4B,CAAC,EACjD,WAAW,EACX,aAAa,GACd,EAAE,yBAAyB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAiBxD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.processAnalysisAndLoadFrames = processAnalysisAndLoadFrames;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
function extractKeyFramesFromAnalysis(analysisData) {
|
|
6
|
+
const keyFrames = [];
|
|
7
|
+
if (analysisData && Array.isArray(analysisData)) {
|
|
8
|
+
analysisData.forEach((section) => {
|
|
9
|
+
if (section.key_frame && typeof section.key_frame === "string") {
|
|
10
|
+
keyFrames.push(section.key_frame);
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
return keyFrames;
|
|
15
|
+
}
|
|
16
|
+
async function processAnalysisAndLoadFrames({ rawAnalysis, artifactsPath, }) {
|
|
17
|
+
const parsedXml = (0, utils_1.parseXmlSummaryToJson)(rawAnalysis);
|
|
18
|
+
const keyFrames = extractKeyFramesFromAnalysis(parsedXml);
|
|
19
|
+
let keyFrameImagesMap = new Map();
|
|
20
|
+
if (keyFrames.length > 0) {
|
|
21
|
+
try {
|
|
22
|
+
keyFrameImagesMap = await (0, utils_1.loadKeyFrameImages)(keyFrames, artifactsPath);
|
|
23
|
+
}
|
|
24
|
+
catch (error) { }
|
|
25
|
+
}
|
|
26
|
+
return { parsedXml, keyFrameImagesMap };
|
|
27
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empiricalrun/test-gen",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.78.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "public"
|
|
@@ -62,7 +62,6 @@
|
|
|
62
62
|
"date-fns": "^3.6.0",
|
|
63
63
|
"detect-port": "^1.6.1",
|
|
64
64
|
"dotenv": "^16.4.5",
|
|
65
|
-
"eslint": "^9.30.0",
|
|
66
65
|
"express": "^4.19.2",
|
|
67
66
|
"ignore": "^5.3.1",
|
|
68
67
|
"inquirer": "^12.4.2",
|
|
@@ -82,11 +81,12 @@
|
|
|
82
81
|
"ts-morph": "^23.0.0",
|
|
83
82
|
"tsx": "^4.16.2",
|
|
84
83
|
"typescript": "^5.3.3",
|
|
84
|
+
"videostil": "^0.1.2",
|
|
85
85
|
"yauzl": "^3.1.3",
|
|
86
86
|
"zod": "^3.23.8",
|
|
87
87
|
"@empiricalrun/ast-parser": "^0.0.10",
|
|
88
|
-
"@empiricalrun/llm": "^0.
|
|
89
|
-
"@empiricalrun/r2-uploader": "^0.
|
|
88
|
+
"@empiricalrun/llm": "^0.24.0",
|
|
89
|
+
"@empiricalrun/r2-uploader": "^0.4.0",
|
|
90
90
|
"@empiricalrun/test-run": "^0.11.1"
|
|
91
91
|
},
|
|
92
92
|
"devDependencies": {
|
|
@@ -106,13 +106,13 @@
|
|
|
106
106
|
"playwright": "1.53.2",
|
|
107
107
|
"serve-handler": "^6.1.6",
|
|
108
108
|
"ts-patch": "^3.3.0",
|
|
109
|
-
"@empiricalrun/shared-types": "0.
|
|
109
|
+
"@empiricalrun/shared-types": "0.12.0"
|
|
110
110
|
},
|
|
111
111
|
"scripts": {
|
|
112
112
|
"dev": "tspc --build --watch",
|
|
113
113
|
"build": "tspc --build && cp -r src/browser-injected-scripts dist",
|
|
114
114
|
"clean": "tspc --build --clean",
|
|
115
|
-
"lint": "
|
|
115
|
+
"lint": "biome check --unsafe",
|
|
116
116
|
"test": "vitest run",
|
|
117
117
|
"test-browser": "pnpm build && RUNNING_BROWSER_TESTS_FOR_TEST_GEN=1 npx playwright test",
|
|
118
118
|
"test:watch": "vitest",
|
package/tsconfig.tsbuildinfo
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["./src/index.ts","./src/logger.ts","./src/actions/assert.ts","./src/actions/click.ts","./src/actions/done.ts","./src/actions/fill.ts","./src/actions/goto.ts","./src/actions/hover.ts","./src/actions/index.ts","./src/actions/next-task.ts","./src/actions/press.ts","./src/actions/skill.ts","./src/actions/text-content.ts","./src/actions/constants/index.ts","./src/actions/utils/index.ts","./src/agent/cli.ts","./src/agent/index.ts","./src/agent/base/index.ts","./src/agent/browsing/index.ts","./src/agent/browsing/run.ts","./src/agent/browsing/utils.ts","./src/agent/chat/agent-loop.ts","./src/agent/chat/exports.ts","./src/agent/chat/filesystem-cache.ts","./src/agent/chat/index.ts","./src/agent/chat/models.ts","./src/agent/chat/state.ts","./src/agent/chat/types.ts","./src/agent/chat/utils.ts","./src/agent/chat/prompt/
|
|
1
|
+
{"root":["./src/index.ts","./src/logger.ts","./src/actions/assert.ts","./src/actions/click.ts","./src/actions/done.ts","./src/actions/fill.ts","./src/actions/goto.ts","./src/actions/hover.ts","./src/actions/index.ts","./src/actions/next-task.ts","./src/actions/press.ts","./src/actions/skill.ts","./src/actions/text-content.ts","./src/actions/constants/index.ts","./src/actions/utils/index.ts","./src/agent/cli.ts","./src/agent/index.ts","./src/agent/base/index.ts","./src/agent/browsing/index.ts","./src/agent/browsing/run.ts","./src/agent/browsing/utils.ts","./src/agent/chat/agent-loop.ts","./src/agent/chat/exports.ts","./src/agent/chat/filesystem-cache.ts","./src/agent/chat/index.ts","./src/agent/chat/models.ts","./src/agent/chat/state.ts","./src/agent/chat/types.ts","./src/agent/chat/utils.ts","./src/agent/chat/prompt/pw-utils-docs.ts","./src/agent/chat/prompt/repo.ts","./src/agent/chat/prompt/test-case-def.ts","./src/agent/code-review/index.ts","./src/agent/code-review/parser.ts","./src/agent/code-review/types.ts","./src/agent/code-review/executor/index.ts","./src/agent/codegen/create-test-block.ts","./src/agent/codegen/fix-ts-errors.ts","./src/agent/codegen/lexical-scoped-vars.ts","./src/agent/codegen/skills-retriever.ts","./src/agent/codegen/test-update-feedback.ts","./src/agent/codegen/types.ts","./src/agent/codegen/update-flow.ts","./src/agent/codegen/use-skill.ts","./src/agent/codegen/utils.ts","./src/agent/cua/computer.ts","./src/agent/cua/index.ts","./src/agent/cua/model.ts","./src/agent/cua/pw-codegen/element-from-point.ts","./src/agent/cua/pw-codegen/types.ts","./src/agent/cua/pw-codegen/pw-pause/for-recorder.ts","./src/agent/cua/pw-codegen/pw-pause/index.ts","./src/agent/cua/pw-codegen/pw-pause/ipc.ts","./src/agent/cua/pw-codegen/pw-pause/patch.ts","./src/agent/cua/pw-codegen/pw-pause/types.ts","./src/agent/cua/pw-codegen/pw-pause/utils.ts","./src/agent/master/action-tool-calls.ts","./src/agent/master/element-annotation.ts","./src/agent/master/execute-browser-action.ts","./src/agent/master/execute-skill-action.ts","./src/agent/master/next-action.ts","./src/agent/master/planner.ts","./src/agent/master/run.ts","./src/agent/master/scroller.ts","./src/agent/master/with-hints.ts","./src/agent/master/browser-tests/cua.spec.ts","./src/agent/master/browser-tests/fixtures.ts","./src/agent/master/browser-tests/index.spec.ts","./src/agent/master/browser-tests/skills.spec.ts","./src/agent/master/icon-descriptor/index.ts","./src/agent/master/icon-descriptor/normalize-svg.ts","./src/agent/planner/run-time-planner.ts","./src/agent/planner/run.ts","./src/agent/triage/index.ts","./src/agent/video-analysis/index.ts","./src/agent/video-analysis/executor/index.ts","./src/artifacts/index.ts","./src/artifacts/utils.ts","./src/auth/cli-auth.ts","./src/auth/index.ts","./src/auth/token-store.ts","./src/bin/environments.ts","./src/bin/index.ts","./src/bin/setup.ts","./src/bin/logger/index.ts","./src/bin/utils/context.ts","./src/bin/utils/index.ts","./src/bin/utils/fs/index.ts","./src/bin/utils/platform/web/index.ts","./src/bin/utils/platform/web/test-files/ts-path-import-validate.ts","./src/bin/utils/scenarios/index.ts","./src/browser-injected-scripts/annotate-elements.spec.ts","./src/constants/index.ts","./src/dashboard/client.ts","./src/dashboard/index.ts","./src/dashboard/totp.ts","./src/dashboard/types.ts","./src/errors/index.ts","./src/evals/append-create-test-agent.evals.ts","./src/evals/fetch-pom-skills-agent.evals.ts","./src/evals/master-agent.evals.ts","./src/evals/type.ts","./src/evals/update-scenario-agent.evals.ts","./src/file/client.ts","./src/file/server.ts","./src/file-info/index.ts","./src/file-info/adapters/file-system/index.ts","./src/file-info/adapters/file-system/reader.ts","./src/file-info/adapters/github/index.ts","./src/file-info/adapters/github/reader.ts","./src/human-in-the-loop/cli.ts","./src/human-in-the-loop/index.ts","./src/human-in-the-loop/ipc.ts","./src/page/index.ts","./src/prompts/lib/ts-transformer.ts","./src/recorder/env-variables.ts","./src/recorder/index.ts","./src/recorder/request.ts","./src/recorder/temp-files.ts","./src/recorder/upload.ts","./src/recorder/validation.ts","./src/test-build/index.ts","./src/tools/diagnosis-fetcher.ts","./src/tools/index.ts","./src/tools/list-environments.ts","./src/tools/run-test.ts","./src/tools/test-gen-browser.ts","./src/tools/analyse-video/index.ts","./src/tools/create-pull-request/index.ts","./src/tools/create-pull-request/utils.ts","./src/tools/definitions/analyse-video.ts","./src/tools/definitions/delete-file.ts","./src/tools/definitions/download-build.ts","./src/tools/definitions/grep.ts","./src/tools/definitions/list-tests-and-projects.ts","./src/tools/definitions/merge-conflicts.ts","./src/tools/definitions/rename-file.ts","./src/tools/definitions/review-pull-request.ts","./src/tools/definitions/run-test.ts","./src/tools/definitions/str_replace_editor.ts","./src/tools/definitions/test-gen-browser.ts","./src/tools/definitions/upgrade-packages.ts","./src/tools/definitions/utils.ts","./src/tools/delete-file/index.ts","./src/tools/download-build/index.ts","./src/tools/executor/base.ts","./src/tools/executor/index.ts","./src/tools/executor/utils/checkpoint.ts","./src/tools/executor/utils/git.ts","./src/tools/executor/utils/index.ts","./src/tools/executor/utils/pr-description.ts","./src/tools/fetch-file/index.ts","./src/tools/fetch-last-successful-test-run/index.ts","./src/tools/fetch-session-diff/index.ts","./src/tools/file-operations/create.ts","./src/tools/file-operations/index.ts","./src/tools/file-operations/insert.ts","./src/tools/file-operations/replace.ts","./src/tools/file-operations/shared/helpers.ts","./src/tools/file-operations/view/index.ts","./src/tools/grep/index.ts","./src/tools/grep/types.ts","./src/tools/grep/ripgrep/index.ts","./src/tools/issues/create-issue.ts","./src/tools/issues/index.ts","./src/tools/issues/list-issues.ts","./src/tools/issues/metadata-schema.ts","./src/tools/issues/update-issue.ts","./src/tools/issues/utils.ts","./src/tools/list-tests-and-projects/index.ts","./src/tools/merge-conflicts/index.ts","./src/tools/rename-file/index.ts","./src/tools/review-pull-request/index.ts","./src/tools/test-run-fetcher/index.ts","./src/tools/test-run-fetcher/types.ts","./src/tools/trace-dot-zip/index.ts","./src/tools/trace-dot-zip/types.ts","./src/tools/trace-dot-zip/utils/console-trace.ts","./src/tools/trace-dot-zip/utils/extract-zip.ts","./src/tools/trace-dot-zip/utils/network-trace.ts","./src/tools/triage-summary/index.ts","./src/tools/triage-summary/types.ts","./src/tools/triage-summary/utils.ts","./src/tools/upgrade-packages/index.ts","./src/tools/upgrade-packages/utils.ts","./src/tools/utils/queue.ts","./src/tools/utils/urls.ts","./src/tools/view-failed-test-run-report/index.ts","./src/trace-utils/index.ts","./src/types/handlebars.d.ts","./src/types/index.ts","./src/utils/SQSClient.ts","./src/utils/env.ts","./src/utils/exec.ts","./src/utils/file.ts","./src/utils/hash.ts","./src/utils/html.ts","./src/utils/index.ts","./src/utils/json.ts","./src/utils/model.ts","./src/utils/playwright-report-parser.ts","./src/utils/repo-tree.ts","./src/utils/slug.ts","./src/utils/string.ts","./src/utils/stripAnsi.ts","./src/utils/dedup/dedup-image.ts","./src/utils/dedup/find-threshold.ts","./src/video-core/agent-orchestrator.ts","./src/video-core/index.ts","./src/video-core/model-limits.ts","./src/video-core/storage-manager.ts","./src/video-core/types.ts","./src/video-core/utils.ts","./src/video-core/xml-parser.ts"],"version":"5.8.3"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/agent/chat/prompt/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,0BAA0B;wBACjB,MAAM;yBACL,MAAM;iCACE,MAAM;CAEpC,CAAC"}
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AGENT_TO_SYSTEM_PROMPT_MAP = void 0;
|
|
4
|
-
const pw_utils_docs_1 = require("./pw-utils-docs");
|
|
5
|
-
exports.AGENT_TO_SYSTEM_PROMPT_MAP = {
|
|
6
|
-
chat: (repoContext) => buildChatSystemPrompt(repoContext),
|
|
7
|
-
video: (repoContext) => buildVideoAnalysisSystemPrompt(repoContext),
|
|
8
|
-
"code-review": (repoContext) => buildCodeReviewAgentSystemPrompt(repoContext),
|
|
9
|
-
};
|
|
10
|
-
async function buildCodeReviewAgentSystemPrompt(repoContext) {
|
|
11
|
-
console.warn("not using repoContext in code review agent prompt for now", typeof repoContext);
|
|
12
|
-
return `
|
|
13
|
-
You are an expert code reviewer that specializes in reviewing Playwright test code. You are
|
|
14
|
-
provided with tools to fetch diff for a code review, where a test has been added, test modified,
|
|
15
|
-
or some configuration has changed.
|
|
16
|
-
|
|
17
|
-
# Your goals
|
|
18
|
-
- Identify code smells in test code - see below
|
|
19
|
-
- Call out test data assumptions or lack of clean up
|
|
20
|
-
|
|
21
|
-
# Output format
|
|
22
|
-
- You are expected to return two sections in your response: describe_code_change and code_review_comments
|
|
23
|
-
- describe_code_change: A brief summary of what the code change is doing. This should be 4-6 sentences in a bullet list.
|
|
24
|
-
- code_review_comments: A bulleted list of code review comments that catch for any of the specific bits below or other
|
|
25
|
-
red flags you might see in the code. Each comment should be 1-2 sentences.
|
|
26
|
-
|
|
27
|
-
Return these as XML tags with markdown inside them
|
|
28
|
-
|
|
29
|
-
<describe_code_change>
|
|
30
|
-
- ...
|
|
31
|
-
</describe_code_change>
|
|
32
|
-
|
|
33
|
-
<code_review_comments>
|
|
34
|
-
- ...
|
|
35
|
-
</code_review_comments>
|
|
36
|
-
|
|
37
|
-
# Specific bits to catch in the code review
|
|
38
|
-
|
|
39
|
-
## Code smells to look for
|
|
40
|
-
- Any form of try-catch or exception handling is a code smell in test code. If there's an
|
|
41
|
-
exception, the test should fail
|
|
42
|
-
- Any conditionals (if, switch, ternary) in test code is a code smell. Tests are expected to be
|
|
43
|
-
deterministic. If you see conditionals, check if there's a comment explaining why it's needed.
|
|
44
|
-
Critically review the comment -- if it's not convincing, call it out as a code smell.
|
|
45
|
-
|
|
46
|
-
## Ensure Playwright best practices
|
|
47
|
-
- Use locators instead of selectors: waitForSelector, $, $$ are bad - use locators instead (e.g. locator.waitFor)
|
|
48
|
-
- If the test relies on some Playwright APIs that do not auto-wait (e.g. isVisible(), count()), we need to ensure
|
|
49
|
-
they are used AFTER some action that ensures the page has loaded. If nothing, at least it should have a waitForTimeout
|
|
50
|
-
- Don't use waitForLoadState or networkidle - these are not required since Playwright auto-waits after navigations
|
|
51
|
-
|
|
52
|
-
## Call out test data assumptions
|
|
53
|
-
- If new test data is created (e.g. creating a new entity in the app, doing some actions on it) - it should be cleaned up
|
|
54
|
-
at the end of the test. If not, call it out.
|
|
55
|
-
- If the test data cannot be cleaned up, are we using some random names to ensure no conflicts in future test runs?
|
|
56
|
-
- If the test assumes some data exists (e.g. a user with a specific email) - call it out. It might fail across other
|
|
57
|
-
environments.
|
|
58
|
-
- No hard coded URLs - use relative URLs instead - that can work across environments.
|
|
59
|
-
- Dependency on static data that can change across environments (e.g. number of rows in a table) should be avoided.
|
|
60
|
-
|
|
61
|
-
## Remove debug artifacts
|
|
62
|
-
- If there are console.logs or page.screenshot usage, call it out. They should be removed before merging.
|
|
63
|
-
`;
|
|
64
|
-
}
|
|
65
|
-
async function buildVideoAnalysisSystemPrompt(repoContext) {
|
|
66
|
-
console.warn("not using repoContext in video analysis prompt for now", typeof repoContext);
|
|
67
|
-
return `
|
|
68
|
-
You are a video analysis agent specialized in analyzing screen recordings and user interface interactions.
|
|
69
|
-
|
|
70
|
-
Available Tools:
|
|
71
|
-
- extract_frames: Extract frames from videos for detailed visual analysis
|
|
72
|
-
- fetch_video_analysis: Get comprehensive video analysis summary (legacy)
|
|
73
|
-
|
|
74
|
-
When analyzing videos:
|
|
75
|
-
1. Use extract_frames to get individual frames for detailed analysis
|
|
76
|
-
2. Analyze each frame for UI elements, user actions, and state changes
|
|
77
|
-
3. Provide specific observations about what's happening in each frame
|
|
78
|
-
4. The Summary should be in a bullet point format
|
|
79
|
-
5. Reference frame IDs when discussing specific moments: "In frame_abc123_001, I can see..."
|
|
80
|
-
|
|
81
|
-
Your analysis should be:
|
|
82
|
-
- Detailed and specific about UI elements and interactions
|
|
83
|
-
- Sequential, following the flow of actions in the video
|
|
84
|
-
|
|
85
|
-
After the final summary you need to include the key frame IDs that best represent the important moments in the video.
|
|
86
|
-
|
|
87
|
-
Exmple Frame Id Reference: <frame_abc123_001>
|
|
88
|
-
`;
|
|
89
|
-
}
|
|
90
|
-
async function buildChatSystemPrompt(repoContext) {
|
|
91
|
-
const preamble = `
|
|
92
|
-
You are a helpful assistant that can answer questions and help with tasks related to writing and maintaining Playwright tests.
|
|
93
|
-
|
|
94
|
-
You are working on a test code repository that contains Playwright tests and other related files. Your working directory
|
|
95
|
-
has been checked out on a git branch, and your actions that edit files will be automatically committed. If you make any
|
|
96
|
-
file edits, you must create a pull request after your work is done, to get your work reviewed and merged by a human.
|
|
97
|
-
|
|
98
|
-
# Your capabilities
|
|
99
|
-
|
|
100
|
-
- Adding new Playwright tests or helper methods
|
|
101
|
-
- Going through test reports and identifying app issues versus test issues
|
|
102
|
-
- Modifying existing tests to adapt to changes in the application
|
|
103
|
-
- Modifying repo configuration (e.g. in playwright.config.ts) and dependencies (e.g. in package.json)
|
|
104
|
-
|
|
105
|
-
# Going through test reports
|
|
106
|
-
|
|
107
|
-
- App issues: app issues caught by test failures, like UI issues, API endpoint issues, etc. These are issues that
|
|
108
|
-
will be reported to an app developer to investigate and fix.
|
|
109
|
-
- Test issues: Playwright tests can become outdated when app code changes. These are issues that need to be
|
|
110
|
-
fixed with modifications to the test code, and it is your job to do that.
|
|
111
|
-
|
|
112
|
-
# Tools
|
|
113
|
-
|
|
114
|
-
You are given a set of tools to help you fulfill the user's request. Read their descriptions to
|
|
115
|
-
understand what each tool does.
|
|
116
|
-
|
|
117
|
-
For example, if the user asks you to run a test, you could use the runTest tool.
|
|
118
|
-
Once the test is run, you will receive the results in the form of a JSON object.
|
|
119
|
-
Summarize the results in a few sentences.
|
|
120
|
-
|
|
121
|
-
If the user provides a diagnosis URL, you can use the fetchDiagnosisDetails tool
|
|
122
|
-
to get more information about the test case and its results.
|
|
123
|
-
|
|
124
|
-
If the user provides a test run URL, you can use the fetchTestRunDetails tool
|
|
125
|
-
to get detailed information about a specific test run.
|
|
126
|
-
|
|
127
|
-
Or if the user asks you to modify a test, you could use the generateTestWithBrowserAgent tool. If you suspect
|
|
128
|
-
that a UI selector needs to be updated, using the browser agent is a good idea.
|
|
129
|
-
|
|
130
|
-
Before using generateTestWithBrowserAgent, you need to prepare the test code for the browser agent.
|
|
131
|
-
You can do this by using the strReplaceEditor or the text editor tool to add a TODO comment to the test
|
|
132
|
-
code. This comment explains to the browser agent what it needs to do.
|
|
133
|
-
|
|
134
|
-
For example, if the expected modification is to click on a login button, you could add the following comment.
|
|
135
|
-
|
|
136
|
-
// TODO(agent): Click on the login button
|
|
137
|
-
|
|
138
|
-
The position of the comment is important: the browser agent will look for this comment and replace it with
|
|
139
|
-
the actual code to click on the login button. If you are fixing a failing test, your comment should be
|
|
140
|
-
around the failing line of code, so that it can be replaced/modified.
|
|
141
|
-
|
|
142
|
-
# Proactiveness
|
|
143
|
-
|
|
144
|
-
1. You are allowed to be proactive, but ONLY for read-only tool calls: like searching for content, reading files, fetching data from tools, and
|
|
145
|
-
running Playwright tests.
|
|
146
|
-
2. For any read-write tool calls (e.g. modifying any file), you should share your plan and get the user's approval before proceeding.
|
|
147
|
-
|
|
148
|
-
# Rules to follow
|
|
149
|
-
|
|
150
|
-
You must follow these rules while adding new tests or modifying existing tests. There can be exceptions to these rules, but
|
|
151
|
-
ONLY when explicitly asked for by the user.
|
|
152
|
-
|
|
153
|
-
1. You can't delete some steps from the test to make it pass. The test needs to accomplish its objective (which is to validate a particular user scenario)
|
|
154
|
-
2. Do not add any conditional logic or try catch blocks in a test. A good test deterministically tests a user scenario
|
|
155
|
-
3. Trust Playwright's ability to auto-wait while taking actions on elements.
|
|
156
|
-
- Example 1: Do not add checks on locator.isVisible() before clicking on it: Playwright already waits for visibility on locator.click()
|
|
157
|
-
- Example 2: Do not add page.waitForLoadState after a page.goto: Playwright already waits for page "load" event in page.goto()
|
|
158
|
-
4. Do not add waitForTimeout or waitForLoadState in a test. Playwright will automatically wait for the page to load.
|
|
159
|
-
5. Try/catch blocks are a code smell for tests: you should not use them.
|
|
160
|
-
6. Do not use then() or catch() syntax in a test. Use async/await only
|
|
161
|
-
|
|
162
|
-
There are few exceptions to these rules. BEFORE applying any of the following exceptions, you MUST share your plan with the user and get their approval.
|
|
163
|
-
|
|
164
|
-
## Exceptions for conditional logic
|
|
165
|
-
|
|
166
|
-
There are few exceptions where you can add conditional logic to a test. If the application UI reveals some UI elements on certain conditions, we can add conditional logic.
|
|
167
|
-
|
|
168
|
-
For example, a form view shows a "Save" button only when the form is dirty. In this case, we will have to check if the "Save" button is visible before clicking on it. To do this,
|
|
169
|
-
follow this pattern:
|
|
170
|
-
|
|
171
|
-
\`\`\`
|
|
172
|
-
const saveButton = page.getByRole('button', { name: 'Save' });
|
|
173
|
-
if (await saveButton.isVisible()) {
|
|
174
|
-
await saveButton.click();
|
|
175
|
-
}
|
|
176
|
-
\`\`\`
|
|
177
|
-
|
|
178
|
-
Note that locator.isVisible() DOES NOT wait for the element to be visible. If the element in question shows up after a delay, we have no option but to add a waitForTimeout.
|
|
179
|
-
|
|
180
|
-
\`\`\`
|
|
181
|
-
const saveButton = page.getByRole('button', { name: 'Save' });
|
|
182
|
-
await page.waitForTimeout(100); // Wait for the element to be visible -- only if necessary.
|
|
183
|
-
if (await saveButton.isVisible()) {
|
|
184
|
-
await saveButton.click();
|
|
185
|
-
}
|
|
186
|
-
\`\`\`
|
|
187
|
-
|
|
188
|
-
`;
|
|
189
|
-
return `${preamble}
|
|
190
|
-
|
|
191
|
-
# Recipes
|
|
192
|
-
${pw_utils_docs_1.playwrightUtilsDocs}
|
|
193
|
-
|
|
194
|
-
# Repo context
|
|
195
|
-
${repoContext}
|
|
196
|
-
|
|
197
|
-
# Reference
|
|
198
|
-
Today's date is ${new Date().toDateString()}
|
|
199
|
-
`;
|
|
200
|
-
}
|