@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.
Files changed (237) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/dist/agent/base/index.d.ts +25 -21
  3. package/dist/agent/base/index.d.ts.map +1 -1
  4. package/dist/agent/base/index.js +50 -37
  5. package/dist/agent/browsing/run.d.ts +1 -2
  6. package/dist/agent/browsing/run.d.ts.map +1 -1
  7. package/dist/agent/browsing/run.js +3 -9
  8. package/dist/agent/browsing/utils.d.ts +2 -9
  9. package/dist/agent/browsing/utils.d.ts.map +1 -1
  10. package/dist/agent/browsing/utils.js +5 -109
  11. package/dist/agent/chat/agent-loop.d.ts +5 -5
  12. package/dist/agent/chat/agent-loop.d.ts.map +1 -1
  13. package/dist/agent/chat/agent-loop.js +3 -8
  14. package/dist/agent/chat/exports.d.ts +6 -5
  15. package/dist/agent/chat/exports.d.ts.map +1 -1
  16. package/dist/agent/chat/exports.js +4 -9
  17. package/dist/agent/chat/index.d.ts +2 -2
  18. package/dist/agent/chat/index.d.ts.map +1 -1
  19. package/dist/agent/chat/index.js +23 -35
  20. package/dist/agent/chat/models.d.ts +0 -2
  21. package/dist/agent/chat/models.d.ts.map +1 -1
  22. package/dist/agent/chat/models.js +12 -26
  23. package/dist/agent/chat/prompt/pw-utils-docs.d.ts +1 -1
  24. package/dist/agent/chat/prompt/pw-utils-docs.d.ts.map +1 -1
  25. package/dist/agent/chat/prompt/pw-utils-docs.js +52 -0
  26. package/dist/agent/chat/prompt/repo.d.ts.map +1 -1
  27. package/dist/agent/chat/prompt/repo.js +11 -22
  28. package/dist/agent/chat/prompt/test-case-def.d.ts +2 -0
  29. package/dist/agent/chat/prompt/test-case-def.d.ts.map +1 -0
  30. package/dist/agent/chat/prompt/test-case-def.js +44 -0
  31. package/dist/agent/chat/state.d.ts +8 -14
  32. package/dist/agent/chat/state.d.ts.map +1 -1
  33. package/dist/agent/chat/state.js +15 -60
  34. package/dist/agent/chat/utils.d.ts +2 -2
  35. package/dist/agent/chat/utils.d.ts.map +1 -1
  36. package/dist/agent/chat/utils.js +14 -7
  37. package/dist/agent/cli.d.ts.map +1 -1
  38. package/dist/agent/cli.js +49 -58
  39. package/dist/agent/code-review/executor/index.d.ts +5 -0
  40. package/dist/agent/code-review/executor/index.d.ts.map +1 -0
  41. package/dist/agent/code-review/executor/index.js +13 -0
  42. package/dist/agent/code-review/index.d.ts +8 -3
  43. package/dist/agent/code-review/index.d.ts.map +1 -1
  44. package/dist/agent/code-review/index.js +118 -21
  45. package/dist/agent/code-review/parser.d.ts +5 -0
  46. package/dist/agent/code-review/parser.d.ts.map +1 -0
  47. package/dist/agent/code-review/parser.js +70 -0
  48. package/dist/agent/code-review/types.d.ts +36 -0
  49. package/dist/agent/code-review/types.d.ts.map +1 -0
  50. package/dist/agent/code-review/types.js +13 -0
  51. package/dist/agent/cua/index.d.ts.map +1 -1
  52. package/dist/agent/cua/index.js +18 -2
  53. package/dist/agent/cua/model.d.ts.map +1 -1
  54. package/dist/agent/cua/model.js +4 -1
  55. package/dist/agent/cua/pw-codegen/pw-pause/index.d.ts.map +1 -1
  56. package/dist/agent/triage/index.d.ts +3 -3
  57. package/dist/agent/triage/index.d.ts.map +1 -1
  58. package/dist/agent/triage/index.js +16 -20
  59. package/dist/agent/video-analysis/executor/index.d.ts +5 -0
  60. package/dist/agent/video-analysis/executor/index.d.ts.map +1 -0
  61. package/dist/agent/video-analysis/executor/index.js +10 -0
  62. package/dist/agent/video-analysis/index.d.ts +2 -2
  63. package/dist/agent/video-analysis/index.d.ts.map +1 -1
  64. package/dist/agent/video-analysis/index.js +38 -13
  65. package/dist/artifacts/index.d.ts +1 -1
  66. package/dist/artifacts/index.d.ts.map +1 -1
  67. package/dist/artifacts/index.js +3 -1
  68. package/dist/artifacts/utils.d.ts.map +1 -1
  69. package/dist/bin/index.js +11 -21
  70. package/dist/constants/index.d.ts +14 -0
  71. package/dist/constants/index.d.ts.map +1 -1
  72. package/dist/constants/index.js +33 -1
  73. package/dist/file/server.d.ts +1 -3
  74. package/dist/file/server.d.ts.map +1 -1
  75. package/dist/file/server.js +0 -13
  76. package/dist/file-info/adapters/file-system/index.d.ts.map +1 -1
  77. package/dist/file-info/adapters/file-system/reader.d.ts.map +1 -1
  78. package/dist/file-info/adapters/file-system/reader.js +8 -1
  79. package/dist/file-info/adapters/github/index.d.ts.map +1 -1
  80. package/dist/file-info/adapters/github/reader.d.ts +1 -1
  81. package/dist/file-info/adapters/github/reader.d.ts.map +1 -1
  82. package/dist/file-info/adapters/github/reader.js +8 -5
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/tools/analyse-video/index.d.ts +5 -0
  85. package/dist/tools/analyse-video/index.d.ts.map +1 -0
  86. package/dist/tools/analyse-video/index.js +56 -0
  87. package/dist/tools/create-pull-request/index.js +4 -6
  88. package/dist/tools/create-pull-request/utils.d.ts +1 -1
  89. package/dist/tools/definitions/{fetch-video-analysis.d.ts → analyse-video.d.ts} +17 -12
  90. package/dist/tools/definitions/analyse-video.d.ts.map +1 -0
  91. package/dist/tools/definitions/analyse-video.js +60 -0
  92. package/dist/tools/definitions/review-pull-request.d.ts +3 -0
  93. package/dist/tools/definitions/review-pull-request.d.ts.map +1 -0
  94. package/dist/tools/definitions/review-pull-request.js +16 -0
  95. package/dist/tools/definitions/str_replace_editor.d.ts +1 -0
  96. package/dist/tools/definitions/str_replace_editor.d.ts.map +1 -1
  97. package/dist/tools/definitions/str_replace_editor.js +4 -1
  98. package/dist/tools/definitions/test-gen-browser.d.ts +0 -3
  99. package/dist/tools/definitions/test-gen-browser.d.ts.map +1 -1
  100. package/dist/tools/definitions/test-gen-browser.js +33 -8
  101. package/dist/tools/delete-file/index.d.ts.map +1 -1
  102. package/dist/tools/delete-file/index.js +1 -19
  103. package/dist/tools/executor/base.d.ts +32 -0
  104. package/dist/tools/executor/base.d.ts.map +1 -0
  105. package/dist/tools/executor/base.js +131 -0
  106. package/dist/tools/executor/index.d.ts +3 -22
  107. package/dist/tools/executor/index.d.ts.map +1 -1
  108. package/dist/tools/executor/index.js +7 -100
  109. package/dist/tools/executor/utils/checkpoint.d.ts +1 -1
  110. package/dist/tools/executor/utils/checkpoint.d.ts.map +1 -1
  111. package/dist/tools/executor/utils/checkpoint.js +6 -2
  112. package/dist/tools/executor/utils/git.d.ts +2 -2
  113. package/dist/tools/executor/utils/git.d.ts.map +1 -1
  114. package/dist/tools/executor/utils/git.js +7 -3
  115. package/dist/tools/executor/utils/index.d.ts +5 -3
  116. package/dist/tools/executor/utils/index.d.ts.map +1 -1
  117. package/dist/tools/executor/utils/index.js +23 -2
  118. package/dist/tools/fetch-session-diff/index.js +2 -2
  119. package/dist/tools/file-operations/create.d.ts.map +1 -1
  120. package/dist/tools/file-operations/create.js +1 -4
  121. package/dist/tools/file-operations/index.d.ts +2 -1
  122. package/dist/tools/file-operations/index.d.ts.map +1 -1
  123. package/dist/tools/file-operations/index.js +4 -1
  124. package/dist/tools/file-operations/insert.d.ts +1 -2
  125. package/dist/tools/file-operations/insert.d.ts.map +1 -1
  126. package/dist/tools/file-operations/insert.js +1 -4
  127. package/dist/tools/file-operations/replace.d.ts.map +1 -1
  128. package/dist/tools/file-operations/replace.js +21 -25
  129. package/dist/tools/file-operations/shared/helpers.d.ts +3 -5
  130. package/dist/tools/file-operations/shared/helpers.d.ts.map +1 -1
  131. package/dist/tools/file-operations/shared/helpers.js +1 -5
  132. package/dist/tools/grep/index.d.ts.map +1 -1
  133. package/dist/tools/grep/index.js +18 -11
  134. package/dist/tools/index.d.ts +5 -5
  135. package/dist/tools/index.d.ts.map +1 -1
  136. package/dist/tools/index.js +17 -16
  137. package/dist/tools/merge-conflicts/index.d.ts.map +1 -1
  138. package/dist/tools/merge-conflicts/index.js +1 -1
  139. package/dist/tools/rename-file/index.js +1 -1
  140. package/dist/tools/review-pull-request/index.d.ts.map +1 -1
  141. package/dist/tools/review-pull-request/index.js +44 -65
  142. package/dist/tools/run-test.d.ts.map +1 -1
  143. package/dist/tools/run-test.js +25 -3
  144. package/dist/tools/test-gen-browser.d.ts.map +1 -1
  145. package/dist/tools/test-gen-browser.js +51 -47
  146. package/dist/tools/upgrade-packages/index.d.ts.map +1 -1
  147. package/dist/tools/upgrade-packages/index.js +4 -0
  148. package/dist/tools/upgrade-packages/utils.d.ts +1 -0
  149. package/dist/tools/upgrade-packages/utils.d.ts.map +1 -1
  150. package/dist/tools/upgrade-packages/utils.js +1 -0
  151. package/dist/trace-utils/index.d.ts +1 -1
  152. package/dist/trace-utils/index.d.ts.map +1 -1
  153. package/dist/trace-utils/index.js +1 -1
  154. package/dist/utils/dedup/dedup-image.d.ts +22 -0
  155. package/dist/utils/dedup/dedup-image.d.ts.map +1 -0
  156. package/dist/utils/dedup/dedup-image.js +26 -0
  157. package/dist/utils/dedup/find-threshold.d.ts +2 -0
  158. package/dist/utils/dedup/find-threshold.d.ts.map +1 -0
  159. package/dist/utils/dedup/find-threshold.js +42 -0
  160. package/dist/utils/hash.d.ts +2 -0
  161. package/dist/utils/hash.d.ts.map +1 -0
  162. package/dist/utils/hash.js +24 -0
  163. package/dist/utils/model.d.ts +1 -1
  164. package/dist/utils/model.d.ts.map +1 -1
  165. package/dist/utils/model.js +7 -5
  166. package/dist/utils/repo-tree.d.ts +0 -1
  167. package/dist/utils/repo-tree.d.ts.map +1 -1
  168. package/dist/utils/repo-tree.js +2 -14
  169. package/dist/utils/slug.js +1 -1
  170. package/dist/video-core/agent-orchestrator.d.ts +13 -0
  171. package/dist/video-core/agent-orchestrator.d.ts.map +1 -0
  172. package/dist/video-core/agent-orchestrator.js +59 -0
  173. package/dist/video-core/index.d.ts +39 -0
  174. package/dist/video-core/index.d.ts.map +1 -0
  175. package/dist/video-core/index.js +134 -0
  176. package/dist/video-core/model-limits.d.ts +4 -0
  177. package/dist/video-core/model-limits.d.ts.map +1 -0
  178. package/dist/video-core/model-limits.js +73 -0
  179. package/dist/video-core/storage-manager.d.ts +5 -0
  180. package/dist/video-core/storage-manager.d.ts.map +1 -0
  181. package/dist/video-core/storage-manager.js +62 -0
  182. package/dist/video-core/types.d.ts +13 -0
  183. package/dist/video-core/types.d.ts.map +1 -0
  184. package/dist/video-core/types.js +2 -0
  185. package/dist/video-core/utils.d.ts +15 -0
  186. package/dist/video-core/utils.d.ts.map +1 -0
  187. package/dist/video-core/utils.js +194 -0
  188. package/dist/video-core/xml-parser.d.ts +3 -0
  189. package/dist/video-core/xml-parser.d.ts.map +1 -0
  190. package/dist/video-core/xml-parser.js +27 -0
  191. package/package.json +6 -6
  192. package/tsconfig.tsbuildinfo +1 -1
  193. package/dist/agent/chat/prompt/index.d.ts +0 -6
  194. package/dist/agent/chat/prompt/index.d.ts.map +0 -1
  195. package/dist/agent/chat/prompt/index.js +0 -200
  196. package/dist/agent/code-review/prompt.d.ts +0 -2
  197. package/dist/agent/code-review/prompt.d.ts.map +0 -1
  198. package/dist/agent/code-review/prompt.js +0 -55
  199. package/dist/agent/diagnosis-agent/index.d.ts +0 -11
  200. package/dist/agent/diagnosis-agent/index.d.ts.map +0 -1
  201. package/dist/agent/diagnosis-agent/index.js +0 -88
  202. package/dist/agent/diagnosis-agent/strict-mode-violation.d.ts +0 -10
  203. package/dist/agent/diagnosis-agent/strict-mode-violation.d.ts.map +0 -1
  204. package/dist/agent/diagnosis-agent/strict-mode-violation.js +0 -30
  205. package/dist/tools/definitions/extract-frames-from-video.d.ts +0 -39
  206. package/dist/tools/definitions/extract-frames-from-video.d.ts.map +0 -1
  207. package/dist/tools/definitions/extract-frames-from-video.js +0 -60
  208. package/dist/tools/definitions/fetch-video-analysis.d.ts.map +0 -1
  209. package/dist/tools/definitions/fetch-video-analysis.js +0 -61
  210. package/dist/tools/extract-frames-from-video/index.d.ts +0 -7
  211. package/dist/tools/extract-frames-from-video/index.d.ts.map +0 -1
  212. package/dist/tools/extract-frames-from-video/index.js +0 -145
  213. package/dist/tools/fetch-video-analysis/index.d.ts +0 -5
  214. package/dist/tools/fetch-video-analysis/index.d.ts.map +0 -1
  215. package/dist/tools/fetch-video-analysis/index.js +0 -149
  216. package/dist/tools/fetch-video-analysis/open-ai.d.ts +0 -6
  217. package/dist/tools/fetch-video-analysis/open-ai.d.ts.map +0 -1
  218. package/dist/tools/fetch-video-analysis/open-ai.js +0 -37
  219. package/dist/tools/fetch-video-analysis/utils.d.ts +0 -16
  220. package/dist/tools/fetch-video-analysis/utils.d.ts.map +0 -1
  221. package/dist/tools/fetch-video-analysis/utils.js +0 -121
  222. package/dist/tools/fetch-video-analysis/video-analysis.d.ts +0 -7
  223. package/dist/tools/fetch-video-analysis/video-analysis.d.ts.map +0 -1
  224. package/dist/tools/fetch-video-analysis/video-analysis.js +0 -70
  225. package/dist/tools/file-operations/shared/git-helper.d.ts +0 -4
  226. package/dist/tools/file-operations/shared/git-helper.d.ts.map +0 -1
  227. package/dist/tools/file-operations/shared/git-helper.js +0 -29
  228. package/dist/utils/dedup-image-fs.d.ts +0 -27
  229. package/dist/utils/dedup-image-fs.d.ts.map +0 -1
  230. package/dist/utils/dedup-image-fs.js +0 -88
  231. package/dist/utils/dedup-image.d.ts +0 -25
  232. package/dist/utils/dedup-image.d.ts.map +0 -1
  233. package/dist/utils/dedup-image.js +0 -80
  234. package/dist/utils/local-ffmpeg-client.d.ts +0 -27
  235. package/dist/utils/local-ffmpeg-client.d.ts.map +0 -1
  236. package/dist/utils/local-ffmpeg-client.js +0 -299
  237. package/eslint.config.mjs +0 -43
@@ -1,149 +0,0 @@
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.fetchVideoAnalysis = void 0;
7
- const node_crypto_1 = __importDefault(require("node:crypto"));
8
- const node_path_1 = __importDefault(require("node:path"));
9
- const file_1 = require("../../utils/file");
10
- const local_ffmpeg_client_1 = require("../../utils/local-ffmpeg-client");
11
- const fetch_video_analysis_1 = require("../definitions/fetch-video-analysis");
12
- const utils_1 = require("./utils");
13
- const video_analysis_1 = require("./video-analysis");
14
- function getVideoAnalysisParams(params) {
15
- return {
16
- model: params?.model || "gemini-2.5-pro",
17
- fps: params?.fps ?? 30,
18
- threshold: params?.threshold ?? 0.001,
19
- featureFlag: params?.featureFlag ?? "send-all-frames",
20
- };
21
- }
22
- function hashObject(obj) {
23
- const sortedObj = Object.keys(obj)
24
- .sort()
25
- .reduce((acc, key) => {
26
- acc[key] = obj[key];
27
- return acc;
28
- }, {});
29
- const json = JSON.stringify(sortedObj);
30
- return node_crypto_1.default
31
- .createHash("sha256")
32
- .update(json)
33
- .digest("hex")
34
- .substring(0, 16);
35
- }
36
- exports.fetchVideoAnalysis = {
37
- ...fetch_video_analysis_1.fetchVideoAnalysis,
38
- execute: async ({ input, trace, featureFlags, }) => {
39
- const { videoUrl } = input;
40
- const params = getVideoAnalysisParams(input.params);
41
- const videoUrlHash = hashObject({
42
- videoUrl,
43
- ...params,
44
- });
45
- const { model: selectedModel, fps: effectiveFps, threshold: effectiveThreshold, featureFlag: effectiveFeatureFlag, } = params;
46
- const WORKING_DIR = `./video-analysis-artifacts/${videoUrlHash}`;
47
- const R2_BASE_URL = `https://video-analysis.empirical.run/${videoUrlHash}/`;
48
- const videoAnalysisSpan = trace?.span({
49
- name: "video-analysis",
50
- input: { videoUrl },
51
- });
52
- try {
53
- const ffmpegClient = new local_ffmpeg_client_1.LocalFFmpegClient();
54
- const response = await fetch(videoUrl, { method: "HEAD" });
55
- if (!response.ok) {
56
- return {
57
- result: `Failed to access video at ${videoUrl}: ${response.statusText}`,
58
- isError: true,
59
- };
60
- }
61
- const processingSpan = videoAnalysisSpan?.span({
62
- name: "ffmpeg-processing",
63
- input: {
64
- videoUrl,
65
- fps: effectiveFps,
66
- threshold: effectiveThreshold,
67
- },
68
- });
69
- try {
70
- const extractionResult = await ffmpegClient.extractVideoFrames(videoUrl, WORKING_DIR, {
71
- fps: effectiveFps,
72
- threshold: effectiveThreshold,
73
- });
74
- const { totalFramesCount, uniqueFrames } = extractionResult;
75
- processingSpan?.end({
76
- output: {
77
- totalFramesCount,
78
- uniqueFramesCount: uniqueFrames.length,
79
- },
80
- });
81
- console.log(`[video-analysis] Analyzing ${uniqueFrames.length} frames with LLM`);
82
- const outputZipPath = node_path_1.default.join(WORKING_DIR, "frames.zip");
83
- const zipUploadPromise = (0, utils_1.zipAndUploadFramesToR2)(uniqueFrames, outputZipPath, videoUrlHash).catch((error) => {
84
- throw error; // Re-throw to maintain error in Promise.all
85
- });
86
- const { analysis: llmAnalysis, usage } = await (0, video_analysis_1.analyzeFramesWithLLM)(uniqueFrames, videoAnalysisSpan, selectedModel);
87
- console.log(`[video-analysis] Finished Analyzing ${uniqueFrames.length} frames with LLM`);
88
- let finalAnalysis = llmAnalysis;
89
- let finalKeyFramesData = [];
90
- if (featureFlags.includes("enableFetchVideoAnalysisToolMultiModal")) {
91
- const { updatedAnalysis, keyFramesData } = await (0, utils_1.getUpdatedAnalysisAndToolResultImagePart)(llmAnalysis, uniqueFrames);
92
- finalAnalysis = updatedAnalysis;
93
- finalKeyFramesData = [...keyFramesData];
94
- }
95
- const videoInfo = {
96
- total_frames_count: totalFramesCount,
97
- unique_frames_count: uniqueFrames.length,
98
- video_url: videoUrl,
99
- analysis_id: videoUrlHash,
100
- created_at: new Date().toISOString(),
101
- params: {
102
- fps: effectiveFps,
103
- threshold: effectiveThreshold,
104
- model: selectedModel,
105
- featureFlag: effectiveFeatureFlag,
106
- },
107
- usage,
108
- langfuse_trace_id: trace?.id || undefined,
109
- frames_zip_url: `${R2_BASE_URL}frames.zip`,
110
- analysis: finalAnalysis,
111
- };
112
- await Promise.all([
113
- zipUploadPromise,
114
- (0, utils_1.uploadSummaryToR2)(videoInfo, R2_BASE_URL),
115
- ]);
116
- await (0, file_1.safeCleanupDirectory)(WORKING_DIR, "video-analysis-cleanup");
117
- const toolResult = {
118
- video_url: videoUrl,
119
- analysis_id: videoUrlHash,
120
- analysis: finalAnalysis,
121
- };
122
- return {
123
- result: [
124
- { type: "text", text: JSON.stringify(toolResult, null, 2) },
125
- ...finalKeyFramesData,
126
- ],
127
- isError: false,
128
- usage,
129
- };
130
- }
131
- catch (ffmpegError) {
132
- processingSpan?.end();
133
- throw ffmpegError;
134
- }
135
- }
136
- catch (error) {
137
- console.error("Error in video analysis", error);
138
- videoAnalysisSpan?.end();
139
- const message = error instanceof Error ? error.message : String(error);
140
- return {
141
- result: `Error analyzing video: ${message}`,
142
- isError: true,
143
- };
144
- }
145
- finally {
146
- videoAnalysisSpan?.end();
147
- }
148
- },
149
- };
@@ -1,6 +0,0 @@
1
- export declare function analyzeImages({ systemPrompt, imageBase64Array, userPrompt, }: {
2
- systemPrompt: string;
3
- imageBase64Array: string[];
4
- userPrompt: string;
5
- }): Promise<string>;
6
- //# sourceMappingURL=open-ai.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"open-ai.d.ts","sourceRoot":"","sources":["../../../src/tools/fetch-video-analysis/open-ai.ts"],"names":[],"mappings":"AAOA,wBAAsB,aAAa,CAAC,EAClC,YAAY,EACZ,gBAAgB,EAChB,UAAU,GACX,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB,mBA+BA"}
@@ -1,37 +0,0 @@
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.analyzeImages = analyzeImages;
7
- const openai_1 = __importDefault(require("openai"));
8
- const openai = new openai_1.default({
9
- apiKey: ``,
10
- });
11
- async function analyzeImages({ systemPrompt, imageBase64Array, userPrompt, }) {
12
- const response = await openai.responses.create({
13
- model: "gpt-4.1-2025-04-14",
14
- input: [
15
- {
16
- role: "system",
17
- content: systemPrompt,
18
- },
19
- {
20
- role: "user",
21
- content: [
22
- {
23
- type: "input_text",
24
- text: userPrompt,
25
- },
26
- ...imageBase64Array.map((base64) => ({
27
- detail: "auto",
28
- type: "input_image",
29
- image_url: `data:image/png;base64,${base64}`,
30
- })),
31
- ],
32
- },
33
- ],
34
- });
35
- console.log(response.output_text);
36
- return response.output_text;
37
- }
@@ -1,16 +0,0 @@
1
- import { type FileMap } from "@empiricalrun/r2-uploader";
2
- import { ToolResultImagePart, UniqueFrameInfo, UniqueFrameWithMetadata, VideoAnalysisSummary } from "@empiricalrun/shared-types";
3
- export declare const uploadFramesToR2: (videoInfo: Omit<VideoAnalysisSummary, "analysis">, frames: {
4
- metadata: {
5
- index: number;
6
- path: string;
7
- };
8
- image: string;
9
- }[], r2BaseUrl: string) => Promise<UniqueFrameInfo[]>;
10
- export declare const uploadSummaryToR2: (videoInfo: VideoAnalysisSummary, r2BaseUrl: string) => Promise<string>;
11
- export declare const zipAndUploadFramesToR2: (uniqueFrames: UniqueFrameWithMetadata[], outputZipPath: string, videoUrlHash: string) => Promise<FileMap>;
12
- export declare const getUpdatedAnalysisAndToolResultImagePart: (llmAnalysis: string, uniqueFrames: UniqueFrameWithMetadata[]) => Promise<{
13
- updatedAnalysis: string;
14
- keyFramesData: ToolResultImagePart[];
15
- }>;
16
- //# sourceMappingURL=utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/tools/fetch-video-analysis/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EAGb,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,4BAA4B,CAAC;AAuCpC,eAAO,MAAM,gBAAgB,GAC3B,WAAW,IAAI,CAAC,oBAAoB,EAAE,UAAU,CAAC,EACjD,QAAQ;IACN,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;CACf,EAAE,EACH,WAAW,MAAM,KAChB,OAAO,CAAC,eAAe,EAAE,CAqB3B,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,WAAW,oBAAoB,EAC/B,WAAW,MAAM,KAChB,OAAO,CAAC,MAAM,CAsBhB,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,cAAc,uBAAuB,EAAE,EACvC,eAAe,MAAM,EACrB,cAAc,MAAM,KACnB,OAAO,CAAC,OAAO,CAsBjB,CAAC;AAEF,eAAO,MAAM,wCAAwC,GACnD,aAAa,MAAM,EACnB,cAAc,uBAAuB,EAAE,KACtC,OAAO,CAAC;IACT,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,mBAAmB,EAAE,CAAC;CACtC,CA2CA,CAAC"}
@@ -1,121 +0,0 @@
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.getUpdatedAnalysisAndToolResultImagePart = exports.zipAndUploadFramesToR2 = exports.uploadSummaryToR2 = exports.uploadFramesToR2 = void 0;
7
- const r2_uploader_1 = require("@empiricalrun/r2-uploader");
8
- const child_process_1 = require("child_process");
9
- const fs_1 = require("fs");
10
- const path_1 = __importDefault(require("path"));
11
- const uploadFilesToR2 = async (files, videoUrlHash) => {
12
- const label = `video-analysis-upload:${videoUrlHash}`;
13
- const start = Date.now();
14
- console.log(`[${label}] preparing ${files.length} files for upload...`);
15
- console.log(`[${label}] starting upload of ${files.length} files to video-analysis/${videoUrlHash}/...`);
16
- const interval = setInterval(() => {
17
- const secs = Math.round((Date.now() - start) / 1000);
18
- console.log(`[${label}] uploading... ${secs}s elapsed`);
19
- }, 1000);
20
- try {
21
- await (0, r2_uploader_1.uploadInMemoryFiles)({
22
- files,
23
- destinationDir: videoUrlHash,
24
- uploadBucket: "video-analysis",
25
- });
26
- }
27
- finally {
28
- clearInterval(interval);
29
- const secs = Math.round((Date.now() - start) / 1000);
30
- console.log(`[${label}] upload complete in ${secs}s`);
31
- }
32
- };
33
- const uploadFramesToR2 = async (videoInfo, frames, r2BaseUrl) => {
34
- const { analysis_id: videoUrlHash } = videoInfo;
35
- const frameFiles = frames.map((f) => {
36
- const fileName = `frame_${f.metadata.index}_${videoUrlHash}.png`;
37
- const buffer = Buffer.from(f.image, "base64");
38
- return { buffer, fileName, mimeType: "image/png" };
39
- });
40
- console.log(`[video-analysis-upload] uploading ${frameFiles.length} frames to video-analysis/${videoUrlHash}/...`);
41
- await uploadFilesToR2(frameFiles, videoUrlHash);
42
- return frames.map((f) => ({
43
- index: f.metadata.index,
44
- path: f.metadata.path,
45
- fileName: `frame_${f.metadata.index}_${videoUrlHash}.png`,
46
- url: `${r2BaseUrl}frame_${f.metadata.index}_${videoUrlHash}.png`,
47
- }));
48
- };
49
- exports.uploadFramesToR2 = uploadFramesToR2;
50
- const uploadSummaryToR2 = async (videoInfo, r2BaseUrl) => {
51
- try {
52
- const { analysis_id: videoUrlHash } = videoInfo;
53
- const filesToUpload = [
54
- {
55
- buffer: Buffer.from(JSON.stringify(videoInfo, null, 2)),
56
- fileName: "summary.json",
57
- mimeType: "application/json",
58
- },
59
- ];
60
- console.log(`[video-analysis-upload] uploading ${filesToUpload.length} files to video-analysis/${videoUrlHash}/...`);
61
- await uploadFilesToR2(filesToUpload, videoUrlHash);
62
- return r2BaseUrl;
63
- }
64
- catch (error) {
65
- console.error("Error uploading video analysis to R2:", error);
66
- throw error;
67
- }
68
- };
69
- exports.uploadSummaryToR2 = uploadSummaryToR2;
70
- const zipAndUploadFramesToR2 = async (uniqueFrames, outputZipPath, videoUrlHash) => {
71
- const filePaths = uniqueFrames.map((u) => u.metadata.path);
72
- await new Promise((resolve, reject) => {
73
- (0, child_process_1.execFile)("zip", ["-0", "-j", outputZipPath, ...filePaths], (err) => {
74
- if (err)
75
- return reject(err);
76
- resolve();
77
- });
78
- });
79
- const tempUploadDir = path_1.default.dirname(outputZipPath);
80
- console.log(`[zip-upload] Uploading zip file: ${outputZipPath} to video-analysis/${videoUrlHash}/`);
81
- return await (0, r2_uploader_1.uploadDirectory)({
82
- sourceDir: tempUploadDir,
83
- fileList: [outputZipPath],
84
- destinationDir: videoUrlHash,
85
- uploadBucket: "video-analysis",
86
- });
87
- };
88
- exports.zipAndUploadFramesToR2 = zipAndUploadFramesToR2;
89
- const getUpdatedAnalysisAndToolResultImagePart = async (llmAnalysis, uniqueFrames) => {
90
- const keyFramesMatch = llmAnalysis.match(/KEY FRAMES:\s*(.+)$/);
91
- const updatedAnalysis = keyFramesMatch
92
- ? llmAnalysis.replace(/\n\nKEY FRAMES:\s*(.+)$/, "")
93
- : llmAnalysis;
94
- const keyFrameIndices = keyFramesMatch?.[1]
95
- ?.match(/<frame_(\d+)>/g)
96
- ?.map((match) => parseInt(match.match(/<frame_(\d+)>/)?.[1] || "0", 10)) || [];
97
- const frameDataMap = new Map();
98
- await Promise.all(uniqueFrames.map(async (frame) => {
99
- try {
100
- const fileBuffer = await fs_1.promises.readFile(frame.metadata.path);
101
- const base64Data = fileBuffer.toString("base64");
102
- frameDataMap.set(frame.metadata.index, base64Data);
103
- }
104
- catch (error) {
105
- console.error(`Failed to read frame file ${frame.metadata.path}:`, error);
106
- }
107
- }));
108
- const keyFramesData = keyFrameIndices
109
- .map((frameIndex) => {
110
- const base64Data = frameDataMap.get(frameIndex);
111
- return base64Data
112
- ? {
113
- type: "image/png",
114
- base64Data: base64Data,
115
- }
116
- : null;
117
- })
118
- .filter(Boolean);
119
- return { updatedAnalysis, keyFramesData };
120
- };
121
- exports.getUpdatedAnalysisAndToolResultImagePart = getUpdatedAnalysisAndToolResultImagePart;
@@ -1,7 +0,0 @@
1
- import { TraceClient } from "@empiricalrun/llm";
2
- import { SupportedChatModels, UniqueFrameWithMetadata, Usage } from "@empiricalrun/shared-types";
3
- export declare function analyzeFramesWithLLM(uniqueFrames: UniqueFrameWithMetadata[], trace?: TraceClient, selectedModel?: SupportedChatModels, apiKey?: string): Promise<{
4
- analysis: string;
5
- usage: Usage;
6
- }>;
7
- //# sourceMappingURL=video-analysis.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"video-analysis.d.ts","sourceRoot":"","sources":["../../../src/tools/fetch-video-analysis/video-analysis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAEL,mBAAmB,EACnB,uBAAuB,EACvB,KAAK,EACN,MAAM,4BAA4B,CAAC;AAIpC,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,uBAAuB,EAAE,EACvC,KAAK,CAAC,EAAE,WAAW,EACnB,aAAa,CAAC,EAAE,mBAAmB,EACnC,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC,CA8E7C"}
@@ -1,70 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.analyzeFramesWithLLM = analyzeFramesWithLLM;
4
- const chat_1 = require("@empiricalrun/llm/chat");
5
- const models_1 = require("../../agent/chat/models");
6
- async function analyzeFramesWithLLM(uniqueFrames, trace, selectedModel, apiKey) {
7
- const llmSpan = trace?.span({
8
- name: "llm-frame-analysis",
9
- input: { frameCount: uniqueFrames.length },
10
- });
11
- const selectedChatModel = selectedModel || (0, models_1.getDefaultChatModelId)();
12
- try {
13
- // TODO: Move to canonical chat model
14
- let chatModel = new chat_1.GeminiChatModel(selectedChatModel, [], apiKey || process.env.GOOGLE_API_KEY);
15
- chatModel.validateEnvVarsForAuth();
16
- const frameAttachments = uniqueFrames.map((data) => ({
17
- url: data.image,
18
- contentType: "image/png",
19
- name: `frame_${data.metadata.index}.png`,
20
- }));
21
- const userMessage = `
22
- Analyze the ${uniqueFrames.length} frames that are extracted from a screen recording.`;
23
- chatModel.pushUserMessage(userMessage, frameAttachments);
24
- const systemPrompt = `
25
- You are given a set of unique frames from a screen recording. Your job is to provide a comprehensive analysis of the video content.
26
-
27
- REQUIREMENTS:
28
- 1. Provide a detailed verbose bullet list of everything happening in the video
29
- 2. Analyze each frame thoroughly - do not skip any important details
30
- 3. Include UI elements, text content, user interactions, state changes, and visual elements
31
- 4. Be extremely thorough and capture every significant action or change
32
-
33
- OUTPUT FORMAT:
34
- - Start with detailed bullet points of your analysis
35
- - End your response with a dedicated "KEY FRAMES:" section
36
- - List the most important frame IDs in this exact format: KEY FRAMES: <frame_0>, <frame_5>, <frame_12>
37
- - The key frames section MUST be the last part of your response
38
-
39
- STRICT FORMATTING:
40
- - Use bullet points for the analysis
41
- - Key frames must be listed at the very end using the exact format specified above
42
- - Do not include any text after the key frames list
43
- `;
44
- // Get LLM response
45
- const response = await chatModel.getLLMResponse({
46
- systemPrompt,
47
- tools: [], // No tools needed for this analysis
48
- trace: llmSpan,
49
- hasThinkingEnabled: false,
50
- hasInterleavedThinkingEnabled: false,
51
- });
52
- if (!response) {
53
- throw new Error("No response from LLM");
54
- }
55
- chatModel.pushMessage(response);
56
- const usage = chatModel.getUsage();
57
- const analysisResult = chatModel.getHumanReadableLatestMessage();
58
- llmSpan?.end({ output: { analysis: analysisResult?.textMessage } });
59
- return {
60
- analysis: analysisResult?.textMessage || "No analysis generated",
61
- usage,
62
- };
63
- }
64
- catch (error) {
65
- console.error("Error in LLM frame analysis", error);
66
- llmSpan?.end();
67
- const message = error instanceof Error ? error.message : String(error);
68
- throw new Error(`Error analyzing frames with AI: ${message}`);
69
- }
70
- }
@@ -1,4 +0,0 @@
1
- import { CollectArtifacts } from "@empiricalrun/shared-types";
2
- declare function collectGitPatchArtifact(filePath: string, repoDir: string, operation: "create" | "replace" | "insert", collectArtifacts?: CollectArtifacts): Promise<void>;
3
- export { collectGitPatchArtifact };
4
- //# sourceMappingURL=git-helper.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"git-helper.d.ts","sourceRoot":"","sources":["../../../../src/tools/file-operations/shared/git-helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,gBAAgB,EACjB,MAAM,4BAA4B,CAAC;AAQpC,iBAAe,uBAAuB,CACpC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,EAC1C,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
@@ -1,29 +0,0 @@
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.collectGitPatchArtifact = collectGitPatchArtifact;
7
- const path_1 = __importDefault(require("path"));
8
- const git_1 = require("../../executor/utils/git");
9
- async function collectGitPatchArtifact(filePath, repoDir, operation, collectArtifacts) {
10
- if (!collectArtifacts)
11
- return;
12
- try {
13
- const gitPatch = operation === "create"
14
- ? (0, git_1.getGitDiffForNewFile)(filePath, repoDir)
15
- : (0, git_1.getGitDiffStaged)(filePath, repoDir);
16
- if (gitPatch.trim()) {
17
- const patchArtifact = {
18
- name: `${path_1.default.basename(filePath, path_1.default.extname(filePath))}_${operation}.patch`,
19
- contentType: "text/plain",
20
- data: Buffer.from(gitPatch, "utf-8"),
21
- };
22
- collectArtifacts([patchArtifact]);
23
- }
24
- }
25
- catch (error) {
26
- // Ignore git diff errors, don't fail the operation
27
- console.warn(`Failed to generate git patch for ${filePath}:`, error);
28
- }
29
- }
@@ -1,27 +0,0 @@
1
- /**
2
- * Processes an array of image file paths and returns only unique images as base64 strings.
3
- * This is a file system wrapper around the deduplicateImages function that processes
4
- * images in batches to avoid memory overflow.
5
- *
6
- * @param options - Configuration options
7
- * @param options.imagePaths - An array of file paths to image files.
8
- * @param options.batchSize - Number of images to process at a time (default: 50)
9
- * @param options.threshold - The maximum fraction of pixels allowed to differ to consider two images similar.
10
- * For example, 0.01 means that if less than 1% of the pixels differ, the images are considered duplicates.
11
- * Default is 0.001 (0.1%).
12
- * @param options.logPrefix - The ID of the test run, used for logging purposes.
13
- * @returns A promise that resolves to an array of unique image objects with base64 data.
14
- */
15
- export declare function deduplicateImageFiles({ imagePaths, batchSize, threshold, logPrefix, }: {
16
- imagePaths: string[];
17
- batchSize?: number;
18
- threshold?: number;
19
- logPrefix?: string;
20
- }): Promise<{
21
- metadata: {
22
- index: number;
23
- path: string;
24
- };
25
- image: string;
26
- }[]>;
27
- //# sourceMappingURL=dedup-image-fs.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dedup-image-fs.d.ts","sourceRoot":"","sources":["../../src/utils/dedup-image-fs.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AACH,wBAAsB,qBAAqB,CAAC,EAC1C,UAAU,EACV,SAAc,EACd,SAAiB,EACjB,SAA4B,GAC7B,EAAE;IACD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAmG1E"}
@@ -1,88 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.deduplicateImageFiles = deduplicateImageFiles;
4
- const fs_1 = require("fs");
5
- const dedup_image_1 = require("./dedup-image");
6
- /**
7
- * Processes an array of image file paths and returns only unique images as base64 strings.
8
- * This is a file system wrapper around the deduplicateImages function that processes
9
- * images in batches to avoid memory overflow.
10
- *
11
- * @param options - Configuration options
12
- * @param options.imagePaths - An array of file paths to image files.
13
- * @param options.batchSize - Number of images to process at a time (default: 50)
14
- * @param options.threshold - The maximum fraction of pixels allowed to differ to consider two images similar.
15
- * For example, 0.01 means that if less than 1% of the pixels differ, the images are considered duplicates.
16
- * Default is 0.001 (0.1%).
17
- * @param options.logPrefix - The ID of the test run, used for logging purposes.
18
- * @returns A promise that resolves to an array of unique image objects with base64 data.
19
- */
20
- async function deduplicateImageFiles({ imagePaths, batchSize = 50, threshold = 0.001, logPrefix = "dedup-image-fs", }) {
21
- const uniqueImages = [];
22
- console.log(`[${logPrefix}] Processing ${imagePaths.length} images in batches of ${batchSize}`);
23
- for (let i = 0; i < imagePaths.length; i += batchSize) {
24
- const batch = imagePaths.slice(i, i + batchSize);
25
- console.log(`[${logPrefix}] Processing batch ${Math.floor(i / batchSize) + 1}/${Math.ceil(imagePaths.length / batchSize)}`);
26
- const batchBase64Images = [];
27
- for (let j = 0; j < batch.length; j++) {
28
- const imagePath = batch[j];
29
- if (!imagePath) {
30
- console.error(`[${logPrefix}] Error: imagePath is undefined for batch ${Math.floor(i / batchSize) + 1}/${Math.ceil(imagePaths.length / batchSize)}`);
31
- continue;
32
- }
33
- try {
34
- const buffer = await fs_1.promises.readFile(imagePath);
35
- const base64 = buffer.toString("base64");
36
- batchBase64Images.push({
37
- metadata: {
38
- index: i + j,
39
- path: imagePath,
40
- },
41
- image: base64,
42
- });
43
- }
44
- catch (error) {
45
- console.error(`[${logPrefix}] Error reading image ${imagePath}:`, error);
46
- continue;
47
- }
48
- }
49
- // If this is the first batch, just deduplicate within the batch
50
- if (uniqueImages.length === 0) {
51
- const batchUniqueImages = await (0, dedup_image_1.deduplicateImages)({
52
- base64Images: batchBase64Images,
53
- threshold,
54
- logPrefix: `${logPrefix}-batch-${Math.floor(i / batchSize) + 1}`,
55
- });
56
- uniqueImages.push(...batchUniqueImages);
57
- }
58
- else {
59
- // For subsequent batches, compare against the last unique image and then deduplicate within batch
60
- const lastUniqueImage = uniqueImages[uniqueImages.length - 1];
61
- if (!lastUniqueImage) {
62
- console.error(`[${logPrefix}] Error: lastUniqueImage is undefined for batch ${Math.floor(i / batchSize) + 1}/${Math.ceil(imagePaths.length / batchSize)}`);
63
- continue;
64
- }
65
- const batchWithPrevious = [lastUniqueImage, ...batchBase64Images];
66
- const batchUniqueImages = await (0, dedup_image_1.deduplicateImages)({
67
- base64Images: batchWithPrevious,
68
- threshold,
69
- logPrefix: `${logPrefix}-batch-${Math.floor(i / batchSize) + 1}`,
70
- });
71
- // Remove the first image if it's the same as the last unique image (it was a duplicate)
72
- // and add the rest to unique images
73
- if (batchUniqueImages.length > 0) {
74
- // Skip the first image if it has the same path as the last unique image
75
- const startIndex = batchUniqueImages[0]?.metadata.path === lastUniqueImage.metadata.path
76
- ? 1
77
- : 0;
78
- uniqueImages.push(...batchUniqueImages.slice(startIndex));
79
- }
80
- }
81
- // Force garbage collection after each batch
82
- if (global.gc) {
83
- global.gc();
84
- }
85
- }
86
- console.log(`[${logPrefix}] Filtered to ${uniqueImages.length} unique images from ${imagePaths.length} total images`);
87
- return uniqueImages;
88
- }
@@ -1,25 +0,0 @@
1
- /**
2
- * Processes an array of base64 image objects and returns only unique images.
3
- * Two images are considered "similar" if the fraction of differing pixels (when resized)
4
- * is below the provided threshold.
5
- *
6
- * @param options - Configuration options
7
- * @param options.base64Images - An array of objects, each with a metadata field and a base64-encoded image string.
8
- * @param options.threshold - The maximum fraction of pixels allowed to differ to consider two images similar.
9
- * For example, 0.01 means that if less than 1% of the pixels differ, the images are considered duplicates.
10
- * Default is 0.001 (0.1%).
11
- * @param options.logPrefix - The ID of the test run, used for logging purposes.
12
- * @returns A promise that resolves to an array of unique image objects.
13
- */
14
- export declare function deduplicateImages({ base64Images, threshold, logPrefix, }: {
15
- base64Images: {
16
- metadata: any;
17
- image: string;
18
- }[];
19
- threshold?: number;
20
- logPrefix?: string;
21
- }): Promise<{
22
- metadata: any;
23
- image: string;
24
- }[]>;
25
- //# sourceMappingURL=dedup-image.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dedup-image.d.ts","sourceRoot":"","sources":["../../src/utils/dedup-image.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,YAAY,EACZ,SAAiB,EACjB,SAAyB,GAC1B,EAAE;IACD,YAAY,EAAE;QAAE,QAAQ,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,GAAG,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAsE9C"}