@minicor/mcp-server 4.0.0 → 4.2.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/README.md +6 -0
- package/dist/__tests__/dev-mode-draft.test.js +27 -19
- package/dist/__tests__/dev-mode-draft.test.js.map +1 -1
- package/dist/__tests__/jobs-tools.test.js +1 -0
- package/dist/__tests__/jobs-tools.test.js.map +1 -1
- package/dist/__tests__/laminar-client.test.js +31 -31
- package/dist/__tests__/laminar-client.test.js.map +1 -1
- package/dist/__tests__/lib-dev-mode.test.js +2 -2
- package/dist/__tests__/lib-dev-mode.test.js.map +1 -1
- package/dist/__tests__/recording-frames.test.js +42 -1
- package/dist/__tests__/recording-frames.test.js.map +1 -1
- package/dist/__tests__/server-surface.test.js +11 -9
- package/dist/__tests__/server-surface.test.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/laminar-client.d.ts +11 -14
- package/dist/laminar-client.d.ts.map +1 -1
- package/dist/laminar-client.js +25 -25
- package/dist/laminar-client.js.map +1 -1
- package/dist/lib.js +1 -1
- package/dist/recording-frames.d.ts +82 -9
- package/dist/recording-frames.d.ts.map +1 -1
- package/dist/recording-frames.js +254 -32
- package/dist/recording-frames.js.map +1 -1
- package/dist/seeer-client.d.ts +153 -0
- package/dist/seeer-client.d.ts.map +1 -0
- package/dist/seeer-client.js +146 -0
- package/dist/seeer-client.js.map +1 -0
- package/dist/server-surface.d.ts.map +1 -1
- package/dist/server-surface.js +12 -7
- package/dist/server-surface.js.map +1 -1
- package/dist/sync.js +3 -2
- package/dist/sync.js.map +1 -1
- package/dist/tools/core.d.ts.map +1 -1
- package/dist/tools/core.js +188 -22
- package/dist/tools/core.js.map +1 -1
- package/dist/tools/dev-mode-draft.d.ts.map +1 -1
- package/dist/tools/dev-mode-draft.js +63 -49
- package/dist/tools/dev-mode-draft.js.map +1 -1
- package/dist/tools/jobs.js +1 -1
- package/dist/tools/jobs.js.map +1 -1
- package/dist/tools/recording-common.d.ts +11 -0
- package/dist/tools/recording-common.d.ts.map +1 -0
- package/dist/tools/recording-common.js +15 -0
- package/dist/tools/recording-common.js.map +1 -0
- package/dist/tools/recording.d.ts +3 -0
- package/dist/tools/recording.d.ts.map +1 -0
- package/dist/tools/recording.js +235 -0
- package/dist/tools/recording.js.map +1 -0
- package/dist/tools/workflow-ops.d.ts.map +1 -1
- package/dist/tools/workflow-ops.js +79 -5
- package/dist/tools/workflow-ops.js.map +1 -1
- package/package.json +1 -1
- package/skills/general/job-build-loop.md +10 -7
package/dist/recording-frames.js
CHANGED
|
@@ -1,25 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Extracts
|
|
3
|
-
*
|
|
2
|
+
* Extracts still frames from a recording (MP4) so that a vision-capable model
|
|
3
|
+
* can visually verify or debug an execution.
|
|
4
4
|
*
|
|
5
5
|
* The recording endpoints return a signed URL to an MP4. A model cannot "watch"
|
|
6
|
-
* a video URL, so this module downloads the video and uses ffmpeg to
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* a video URL, so this module downloads the video and uses ffmpeg to extract
|
|
7
|
+
* frames, returned as base64 JPEGs. Supports:
|
|
8
|
+
* - evenly-spaced sampling across the whole video (default)
|
|
9
|
+
* - exact timestamps ("show me t=41.5s")
|
|
10
|
+
* - dense sampling of a time range ("what happened between t=30s and t=45s")
|
|
11
|
+
* - region cropping at the recording's native resolution ("zoom in here")
|
|
12
|
+
*
|
|
13
|
+
* Downloads are cached under ~/.minicor/cache/recordings keyed on the blob
|
|
14
|
+
* identity (URL minus the SAS query), so successive calls against the same
|
|
15
|
+
* recording skip the download entirely.
|
|
16
|
+
*
|
|
17
|
+
* ffmpeg (and ideally ffprobe) must be available on the MCP host; when they are
|
|
18
|
+
* missing we throw a clear error so the caller can fall back to handing the raw
|
|
19
|
+
* URL to a human.
|
|
10
20
|
*/
|
|
11
21
|
import { spawn } from "node:child_process";
|
|
12
|
-
import {
|
|
22
|
+
import { createHash } from "node:crypto";
|
|
23
|
+
import { mkdtemp, mkdir, open, readFile, readdir, rename, rm, stat, utimes, } from "node:fs/promises";
|
|
13
24
|
import { tmpdir } from "node:os";
|
|
14
25
|
import path from "node:path";
|
|
26
|
+
import { MINICOR_DIR } from "./paths.js";
|
|
15
27
|
const DEFAULTS = {
|
|
16
28
|
count: 4,
|
|
29
|
+
maxFrames: 16,
|
|
30
|
+
cache: true,
|
|
17
31
|
maxBytes: 200 * 1024 * 1024,
|
|
18
32
|
downloadTimeoutMs: 60_000,
|
|
19
33
|
commandTimeoutMs: 30_000,
|
|
20
34
|
ffmpegPath: "ffmpeg",
|
|
21
35
|
ffprobePath: "ffprobe",
|
|
22
36
|
};
|
|
37
|
+
// ── Sampling math ────────────────────────────────────────────
|
|
23
38
|
/**
|
|
24
39
|
* Computes evenly-spaced sample timestamps centered within the duration, so we
|
|
25
40
|
* avoid black/blank frames at the very start and end.
|
|
@@ -34,6 +49,29 @@ export function computeSampleTimestamps(durationSeconds, count) {
|
|
|
34
49
|
return Number((durationSeconds * fraction).toFixed(3));
|
|
35
50
|
});
|
|
36
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Computes timestamps for dense sampling of a [start, end] window at `fps`,
|
|
54
|
+
* capped at `maxFrames` (falling back to even spacing across the window when
|
|
55
|
+
* the requested rate would exceed the cap).
|
|
56
|
+
*/
|
|
57
|
+
export function computeRangeTimestamps(start, end, fps, maxFrames) {
|
|
58
|
+
if (!Number.isFinite(start) ||
|
|
59
|
+
!Number.isFinite(end) ||
|
|
60
|
+
end <= start ||
|
|
61
|
+
!Number.isFinite(fps) ||
|
|
62
|
+
fps <= 0 ||
|
|
63
|
+
maxFrames <= 0) {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
const span = end - start;
|
|
67
|
+
const requested = Math.floor(span * fps) + 1;
|
|
68
|
+
const n = Math.min(requested, maxFrames);
|
|
69
|
+
if (n === 1)
|
|
70
|
+
return [Number(start.toFixed(3))];
|
|
71
|
+
const step = span / (n - 1);
|
|
72
|
+
return Array.from({ length: n }, (_, i) => Number((start + i * step).toFixed(3)));
|
|
73
|
+
}
|
|
74
|
+
// ── ffmpeg filters ───────────────────────────────────────────
|
|
37
75
|
/**
|
|
38
76
|
* Builds an ffmpeg scale filter that caps width while preserving aspect ratio.
|
|
39
77
|
* Returns null when no cap is requested, so frames keep their original resolution.
|
|
@@ -44,6 +82,43 @@ export function buildScaleFilter(maxWidth) {
|
|
|
44
82
|
}
|
|
45
83
|
return `scale='min(${maxWidth},iw)':-2`;
|
|
46
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Builds an ffmpeg crop filter for a region (with optional padding), clamped to
|
|
87
|
+
* the video bounds when they are known. Returns null for degenerate regions.
|
|
88
|
+
*/
|
|
89
|
+
export function buildCropFilter(region, videoWidth, videoHeight) {
|
|
90
|
+
const pad = region.pad ?? 0;
|
|
91
|
+
let x0 = Math.floor(region.x - pad);
|
|
92
|
+
let y0 = Math.floor(region.y - pad);
|
|
93
|
+
let x1 = Math.ceil(region.x + region.width + pad);
|
|
94
|
+
let y1 = Math.ceil(region.y + region.height + pad);
|
|
95
|
+
x0 = Math.max(x0, 0);
|
|
96
|
+
y0 = Math.max(y0, 0);
|
|
97
|
+
if (videoWidth != null && Number.isFinite(videoWidth))
|
|
98
|
+
x1 = Math.min(x1, videoWidth);
|
|
99
|
+
if (videoHeight != null && Number.isFinite(videoHeight))
|
|
100
|
+
y1 = Math.min(y1, videoHeight);
|
|
101
|
+
const w = x1 - x0;
|
|
102
|
+
const h = y1 - y0;
|
|
103
|
+
if (w <= 0 || h <= 0)
|
|
104
|
+
return null;
|
|
105
|
+
return `crop=${w}:${h}:${x0}:${y0}`;
|
|
106
|
+
}
|
|
107
|
+
function buildVideoFilter(region, maxWidth, videoWidth, videoHeight) {
|
|
108
|
+
const parts = [];
|
|
109
|
+
if (region) {
|
|
110
|
+
const crop = buildCropFilter(region, videoWidth, videoHeight);
|
|
111
|
+
if (!crop) {
|
|
112
|
+
throw new Error("the requested region falls entirely outside the video bounds");
|
|
113
|
+
}
|
|
114
|
+
parts.push(crop);
|
|
115
|
+
}
|
|
116
|
+
const scale = buildScaleFilter(maxWidth);
|
|
117
|
+
if (scale)
|
|
118
|
+
parts.push(scale);
|
|
119
|
+
return parts.length > 0 ? parts.join(",") : null;
|
|
120
|
+
}
|
|
121
|
+
// ── Command execution ────────────────────────────────────────
|
|
47
122
|
class CommandNotFoundError extends Error {
|
|
48
123
|
}
|
|
49
124
|
export function runCommand(command, args, timeoutMs) {
|
|
@@ -87,6 +162,98 @@ export function runCommand(command, args, timeoutMs) {
|
|
|
87
162
|
});
|
|
88
163
|
});
|
|
89
164
|
}
|
|
165
|
+
// ── Download cache ───────────────────────────────────────────
|
|
166
|
+
const CACHE_DIR = path.join(MINICOR_DIR, "cache", "recordings");
|
|
167
|
+
const CACHE_TTL_MS = 30 * 60 * 1000; // 30 min — SAS URLs are short-lived anyway
|
|
168
|
+
const CACHE_MAX_BYTES = 2 * 1024 * 1024 * 1024; // 2 GB
|
|
169
|
+
/**
|
|
170
|
+
* Stable cache key for a recording URL: the blob identity without the SAS
|
|
171
|
+
* query, so re-minted signed URLs for the same blob hit the same cache entry.
|
|
172
|
+
*/
|
|
173
|
+
export function cacheKeyForUrl(url) {
|
|
174
|
+
let identity = url;
|
|
175
|
+
try {
|
|
176
|
+
const parsed = new URL(url);
|
|
177
|
+
identity = `${parsed.origin}${parsed.pathname}`;
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
// Not a parseable URL — hash the raw string.
|
|
181
|
+
}
|
|
182
|
+
return createHash("sha1").update(identity).digest("hex");
|
|
183
|
+
}
|
|
184
|
+
async function evictCache() {
|
|
185
|
+
let entries = [];
|
|
186
|
+
try {
|
|
187
|
+
const files = await readdir(CACHE_DIR);
|
|
188
|
+
for (const f of files) {
|
|
189
|
+
if (!f.endsWith(".mp4"))
|
|
190
|
+
continue;
|
|
191
|
+
const full = path.join(CACHE_DIR, f);
|
|
192
|
+
try {
|
|
193
|
+
const s = await stat(full);
|
|
194
|
+
entries.push({ file: full, mtimeMs: s.mtimeMs, size: s.size });
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
/* raced with another eviction */
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const now = Date.now();
|
|
205
|
+
const fresh = [];
|
|
206
|
+
for (const e of entries) {
|
|
207
|
+
if (now - e.mtimeMs > CACHE_TTL_MS) {
|
|
208
|
+
await rm(e.file, { force: true }).catch(() => { });
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
fresh.push(e);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
let total = fresh.reduce((sum, e) => sum + e.size, 0);
|
|
215
|
+
if (total <= CACHE_MAX_BYTES)
|
|
216
|
+
return;
|
|
217
|
+
fresh.sort((a, b) => a.mtimeMs - b.mtimeMs); // oldest first
|
|
218
|
+
for (const e of fresh) {
|
|
219
|
+
if (total <= CACHE_MAX_BYTES)
|
|
220
|
+
break;
|
|
221
|
+
await rm(e.file, { force: true }).catch(() => { });
|
|
222
|
+
total -= e.size;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Returns a local path to the recording, downloading it if not already cached.
|
|
227
|
+
* The returned file must NOT be deleted by the caller (it is shared).
|
|
228
|
+
*/
|
|
229
|
+
export async function getCachedRecording(url, opts) {
|
|
230
|
+
// Private permissions: recordings can contain sensitive screen content.
|
|
231
|
+
await mkdir(CACHE_DIR, { recursive: true, mode: 0o700 });
|
|
232
|
+
const dest = path.join(CACHE_DIR, `${cacheKeyForUrl(url)}.mp4`);
|
|
233
|
+
try {
|
|
234
|
+
const s = await stat(dest);
|
|
235
|
+
if (s.size > 0 && Date.now() - s.mtimeMs <= CACHE_TTL_MS) {
|
|
236
|
+
// Touch for LRU so hot recordings survive eviction.
|
|
237
|
+
const now = new Date();
|
|
238
|
+
await utimes(dest, now, now).catch(() => { });
|
|
239
|
+
return dest;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
/* not cached yet */
|
|
244
|
+
}
|
|
245
|
+
const partial = `${dest}.${process.pid}.${Date.now()}.part`;
|
|
246
|
+
try {
|
|
247
|
+
await downloadToFile(url, partial, opts.maxBytes, opts.downloadTimeoutMs);
|
|
248
|
+
await rename(partial, dest);
|
|
249
|
+
}
|
|
250
|
+
finally {
|
|
251
|
+
// A failed/aborted download must not leave partial bytes accumulating.
|
|
252
|
+
await rm(partial, { force: true }).catch(() => { });
|
|
253
|
+
}
|
|
254
|
+
await evictCache();
|
|
255
|
+
return dest;
|
|
256
|
+
}
|
|
90
257
|
async function downloadToFile(url, dest, maxBytes, timeoutMs) {
|
|
91
258
|
const controller = new AbortController();
|
|
92
259
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -102,7 +269,7 @@ async function downloadToFile(url, dest, maxBytes, timeoutMs) {
|
|
|
102
269
|
if (!res.body) {
|
|
103
270
|
throw new Error("recording download returned an empty body");
|
|
104
271
|
}
|
|
105
|
-
const handle = await open(dest, "w");
|
|
272
|
+
const handle = await open(dest, "w", 0o600);
|
|
106
273
|
try {
|
|
107
274
|
let total = 0;
|
|
108
275
|
for await (const chunk of res.body) {
|
|
@@ -121,30 +288,46 @@ async function downloadToFile(url, dest, maxBytes, timeoutMs) {
|
|
|
121
288
|
clearTimeout(timer);
|
|
122
289
|
}
|
|
123
290
|
}
|
|
124
|
-
async function
|
|
291
|
+
async function probeVideo(file, ffprobePath, timeoutMs) {
|
|
125
292
|
try {
|
|
126
|
-
const { stdout } = await runCommand(ffprobePath, [
|
|
127
|
-
|
|
128
|
-
|
|
293
|
+
const { stdout } = await runCommand(ffprobePath, [
|
|
294
|
+
"-v",
|
|
295
|
+
"error",
|
|
296
|
+
"-select_streams",
|
|
297
|
+
"v:0",
|
|
298
|
+
"-show_entries",
|
|
299
|
+
"stream=width,height:format=duration",
|
|
300
|
+
"-of",
|
|
301
|
+
"json",
|
|
302
|
+
file,
|
|
303
|
+
], timeoutMs);
|
|
304
|
+
const parsed = JSON.parse(stdout);
|
|
305
|
+
const duration = parseFloat(parsed?.format?.duration);
|
|
306
|
+
const width = Number(parsed?.streams?.[0]?.width);
|
|
307
|
+
const height = Number(parsed?.streams?.[0]?.height);
|
|
308
|
+
return {
|
|
309
|
+
durationSeconds: Number.isFinite(duration) && duration > 0 ? duration : null,
|
|
310
|
+
width: Number.isFinite(width) && width > 0 ? width : null,
|
|
311
|
+
height: Number.isFinite(height) && height > 0 ? height : null,
|
|
312
|
+
};
|
|
129
313
|
}
|
|
130
|
-
catch
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
return null;
|
|
314
|
+
catch {
|
|
315
|
+
// ffprobe missing or unparseable; caller falls back to thumbnail sampling.
|
|
316
|
+
return { durationSeconds: null, width: null, height: null };
|
|
135
317
|
}
|
|
136
318
|
}
|
|
137
|
-
|
|
319
|
+
// ── Frame extraction ─────────────────────────────────────────
|
|
320
|
+
async function extractFrameAt(file, timestampSeconds, outPath, videoFilter, ffmpegPath, timeoutMs) {
|
|
138
321
|
const args = ["-ss", String(timestampSeconds), "-i", file, "-frames:v", "1"];
|
|
139
|
-
if (
|
|
140
|
-
args.push("-vf",
|
|
322
|
+
if (videoFilter) {
|
|
323
|
+
args.push("-vf", videoFilter);
|
|
141
324
|
}
|
|
142
325
|
// -q:v 2 = highest-quality JPEG, so the original resolution is preserved with minimal artifacts.
|
|
143
326
|
args.push("-q:v", "2", "-y", outPath);
|
|
144
327
|
await runCommand(ffmpegPath, args, timeoutMs);
|
|
145
328
|
}
|
|
146
|
-
async function extractThumbnails(file, count, outPattern,
|
|
147
|
-
const vf =
|
|
329
|
+
async function extractThumbnails(file, count, outPattern, videoFilter, ffmpegPath, timeoutMs) {
|
|
330
|
+
const vf = videoFilter ? `thumbnail,${videoFilter}` : "thumbnail";
|
|
148
331
|
await runCommand(ffmpegPath, [
|
|
149
332
|
"-i",
|
|
150
333
|
file,
|
|
@@ -169,27 +352,66 @@ async function readJpegBase64(file) {
|
|
|
169
352
|
return null;
|
|
170
353
|
}
|
|
171
354
|
}
|
|
355
|
+
function resolveTimestamps(opts, durationSeconds) {
|
|
356
|
+
if (opts.timestamps && opts.timestamps.length > 0) {
|
|
357
|
+
// Sorted copy: callers are promised chronological frames.
|
|
358
|
+
const valid = [...opts.timestamps]
|
|
359
|
+
.filter((t) => Number.isFinite(t) && t >= 0)
|
|
360
|
+
.sort((a, b) => a - b)
|
|
361
|
+
.slice(0, opts.maxFrames);
|
|
362
|
+
return valid.map((t) => {
|
|
363
|
+
// Clamp seeks slightly inside the end so they land on a frame.
|
|
364
|
+
if (durationSeconds != null && t >= durationSeconds) {
|
|
365
|
+
return Number(Math.max(durationSeconds - 0.05, 0).toFixed(3));
|
|
366
|
+
}
|
|
367
|
+
return Number(t.toFixed(3));
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
if (opts.range) {
|
|
371
|
+
const end = durationSeconds != null
|
|
372
|
+
? Math.min(opts.range.end, durationSeconds - 0.01)
|
|
373
|
+
: opts.range.end;
|
|
374
|
+
return computeRangeTimestamps(opts.range.start, end, opts.range.fps ?? 1, opts.maxFrames);
|
|
375
|
+
}
|
|
376
|
+
if (durationSeconds != null) {
|
|
377
|
+
return computeSampleTimestamps(durationSeconds, opts.count);
|
|
378
|
+
}
|
|
379
|
+
return null; // no duration and no explicit targets: thumbnail fallback
|
|
380
|
+
}
|
|
172
381
|
/**
|
|
173
|
-
* Downloads the recording at `url` and returns
|
|
174
|
-
* Throws with a clear message when ffmpeg is unavailable.
|
|
382
|
+
* Downloads the recording at `url` (via the shared cache) and returns extracted
|
|
383
|
+
* JPEG frames. Throws with a clear message when ffmpeg is unavailable.
|
|
175
384
|
*/
|
|
176
385
|
export async function extractFramesFromUrl(url, options = {}) {
|
|
177
386
|
const opts = { ...DEFAULTS, ...options };
|
|
178
|
-
const scaleFilter = buildScaleFilter(opts.maxWidth);
|
|
179
387
|
const workDir = await mkdtemp(path.join(tmpdir(), "laminar-frames-"));
|
|
180
|
-
|
|
388
|
+
let videoPath;
|
|
181
389
|
try {
|
|
182
|
-
|
|
183
|
-
|
|
390
|
+
if (opts.cache) {
|
|
391
|
+
try {
|
|
392
|
+
videoPath = await getCachedRecording(url, opts);
|
|
393
|
+
}
|
|
394
|
+
catch {
|
|
395
|
+
// Cache dir unusable (permissions, disk) — fall back to a temp download.
|
|
396
|
+
videoPath = path.join(workDir, "recording.mp4");
|
|
397
|
+
await downloadToFile(url, videoPath, opts.maxBytes, opts.downloadTimeoutMs);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
videoPath = path.join(workDir, "recording.mp4");
|
|
402
|
+
await downloadToFile(url, videoPath, opts.maxBytes, opts.downloadTimeoutMs);
|
|
403
|
+
}
|
|
404
|
+
const info = await probeVideo(videoPath, opts.ffprobePath, opts.commandTimeoutMs);
|
|
405
|
+
const videoFilter = buildVideoFilter(opts.region, opts.maxWidth, info.width, info.height);
|
|
406
|
+
const timestamps = resolveTimestamps(opts, info.durationSeconds);
|
|
184
407
|
const frames = [];
|
|
185
408
|
try {
|
|
186
|
-
if (
|
|
187
|
-
const timestamps = computeSampleTimestamps(duration, opts.count);
|
|
409
|
+
if (timestamps != null) {
|
|
188
410
|
let lastError = null;
|
|
189
411
|
for (let i = 0; i < timestamps.length; i++) {
|
|
190
412
|
const outPath = path.join(workDir, `frame-${i}.jpg`);
|
|
191
413
|
try {
|
|
192
|
-
await extractFrameAt(videoPath, timestamps[i], outPath,
|
|
414
|
+
await extractFrameAt(videoPath, timestamps[i], outPath, videoFilter, opts.ffmpegPath, opts.commandTimeoutMs);
|
|
193
415
|
}
|
|
194
416
|
catch (e) {
|
|
195
417
|
// ffmpeg missing is fatal; a single bad frame (e.g. a seek that lands
|
|
@@ -216,7 +438,7 @@ export async function extractFramesFromUrl(url, options = {}) {
|
|
|
216
438
|
else {
|
|
217
439
|
// No duration (ffprobe missing) — fall back to thumbnail sampling.
|
|
218
440
|
const outPattern = path.join(workDir, "thumb-%03d.jpg");
|
|
219
|
-
await extractThumbnails(videoPath, opts.count, outPattern,
|
|
441
|
+
await extractThumbnails(videoPath, opts.count, outPattern, videoFilter, opts.ffmpegPath, opts.commandTimeoutMs);
|
|
220
442
|
const files = (await readdir(workDir))
|
|
221
443
|
.filter((f) => f.startsWith("thumb-") && f.endsWith(".jpg"))
|
|
222
444
|
.sort();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recording-frames.js","sourceRoot":"","sources":["../src/recording-frames.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"recording-frames.js","sourceRoot":"","sources":["../src/recording-frames.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client for the seeer (video_tool) video-understanding service.
|
|
3
|
+
*
|
|
4
|
+
* seeer runs the CV analysis (UI events, click inference, segments, step
|
|
5
|
+
* timeline) and heavy frame extraction server-side, with derived results
|
|
6
|
+
* cached as blobs next to the recording.
|
|
7
|
+
*
|
|
8
|
+
* BASE-URL SELECTION (mirrors middleware-service-client.ts):
|
|
9
|
+
*
|
|
10
|
+
* 1. PROXY mode — set `SEEER_SERVICE_PROXY_BASE` (the deployed frontend
|
|
11
|
+
* origin, e.g. https://app.laminar.run). Requests go to
|
|
12
|
+
* `${proxyBase}${prefix}/<path>` where `prefix` defaults to
|
|
13
|
+
* `/api/video-tool` (override with SEEER_SERVICE_PROXY_PREFIX) and the
|
|
14
|
+
* leading `/v1/` is stripped. Auth is the USER's Laminar bearer token —
|
|
15
|
+
* the frontend validates it and forwards with the service's API key,
|
|
16
|
+
* the same pattern as the agents / stitchy / cron proxies.
|
|
17
|
+
*
|
|
18
|
+
* 2. DIRECT — set `SEEER_SERVICE_URL` (e.g. the Cloud Run URL). Auth is the
|
|
19
|
+
* shared app token via `SEEER_SERVICE_TOKEN` (sent as X-API-Key). The
|
|
20
|
+
* service runs IAM-gated on Cloud Run (org policy forbids public access),
|
|
21
|
+
* so requests also need a Google identity token in Authorization:
|
|
22
|
+
* SEEER_SERVICE_ID_TOKEN static token (local testing:
|
|
23
|
+
* `gcloud auth print-identity-token`)
|
|
24
|
+
* SEEER_SERVICE_USE_GCP_IDENTITY set to 1 when the MCP itself runs on
|
|
25
|
+
* GCP; tokens come from the metadata
|
|
26
|
+
* server with the service URL audience
|
|
27
|
+
*
|
|
28
|
+
* Precedence: PROXY (1) > DIRECT (2) > disabled. When disabled, the
|
|
29
|
+
* frame/zoom/clip tools fall back to local ffmpeg (recording-frames.ts);
|
|
30
|
+
* analysis/annotation tools require the service.
|
|
31
|
+
*/
|
|
32
|
+
export interface SeeerRegion {
|
|
33
|
+
x: number;
|
|
34
|
+
y: number;
|
|
35
|
+
width: number;
|
|
36
|
+
height: number;
|
|
37
|
+
pad?: number;
|
|
38
|
+
}
|
|
39
|
+
export interface SeeerEvent {
|
|
40
|
+
id: number;
|
|
41
|
+
t: number;
|
|
42
|
+
tEnd: number;
|
|
43
|
+
type: "ui_change" | "screen_transition" | "activity";
|
|
44
|
+
changeRegion: [number, number, number, number];
|
|
45
|
+
areaFraction: number;
|
|
46
|
+
click: [number, number] | null;
|
|
47
|
+
clickSource: "recorded" | "inferred" | null;
|
|
48
|
+
tBefore: number;
|
|
49
|
+
tAfter: number;
|
|
50
|
+
}
|
|
51
|
+
export interface SeeerAnalysis {
|
|
52
|
+
version: number;
|
|
53
|
+
duration: number;
|
|
54
|
+
resolution: [number, number];
|
|
55
|
+
segments: {
|
|
56
|
+
id: number;
|
|
57
|
+
start: number;
|
|
58
|
+
end: number;
|
|
59
|
+
eventIds: number[];
|
|
60
|
+
}[];
|
|
61
|
+
events: SeeerEvent[];
|
|
62
|
+
cursorTrail: [number, number, number][];
|
|
63
|
+
clicks?: {
|
|
64
|
+
t: number;
|
|
65
|
+
x: number;
|
|
66
|
+
y: number;
|
|
67
|
+
button: string;
|
|
68
|
+
}[];
|
|
69
|
+
stepTimeline?: {
|
|
70
|
+
flowRunId: number;
|
|
71
|
+
flowName: string | null;
|
|
72
|
+
videoStart: number;
|
|
73
|
+
videoEnd: number | null;
|
|
74
|
+
}[];
|
|
75
|
+
videoKey: string;
|
|
76
|
+
}
|
|
77
|
+
export interface SeeerStepRef {
|
|
78
|
+
flowRunId: number;
|
|
79
|
+
flowName?: string;
|
|
80
|
+
videoUrl: string;
|
|
81
|
+
}
|
|
82
|
+
export interface SeeerFrame {
|
|
83
|
+
t: number;
|
|
84
|
+
jpegBase64: string;
|
|
85
|
+
}
|
|
86
|
+
export interface SeeerCallOptions {
|
|
87
|
+
/** The user's Laminar bearer token — required in proxy mode. */
|
|
88
|
+
userToken?: string;
|
|
89
|
+
}
|
|
90
|
+
export declare function seeerServiceUrl(): string | undefined;
|
|
91
|
+
export declare function seeerProxyBase(): string | undefined;
|
|
92
|
+
export declare function seeerAvailable(): boolean;
|
|
93
|
+
export declare function seeerAnalyze(params: {
|
|
94
|
+
videoUrl: string;
|
|
95
|
+
steps?: SeeerStepRef[];
|
|
96
|
+
force?: boolean;
|
|
97
|
+
}, opts?: SeeerCallOptions): Promise<SeeerAnalysis>;
|
|
98
|
+
export declare function seeerFrames(params: {
|
|
99
|
+
videoUrl: string;
|
|
100
|
+
timestamps?: number[];
|
|
101
|
+
range?: {
|
|
102
|
+
start: number;
|
|
103
|
+
end: number;
|
|
104
|
+
fps?: number;
|
|
105
|
+
};
|
|
106
|
+
count?: number;
|
|
107
|
+
width?: number;
|
|
108
|
+
region?: SeeerRegion;
|
|
109
|
+
}, opts?: SeeerCallOptions): Promise<{
|
|
110
|
+
duration: number;
|
|
111
|
+
resolution: [number, number];
|
|
112
|
+
frames: SeeerFrame[];
|
|
113
|
+
}>;
|
|
114
|
+
export declare function seeerZoom(params: {
|
|
115
|
+
videoUrl: string;
|
|
116
|
+
t: number;
|
|
117
|
+
region?: SeeerRegion;
|
|
118
|
+
eventId?: number;
|
|
119
|
+
pad?: number;
|
|
120
|
+
}, opts?: SeeerCallOptions): Promise<{
|
|
121
|
+
t: number;
|
|
122
|
+
region: SeeerRegion;
|
|
123
|
+
jpegBase64: string;
|
|
124
|
+
}>;
|
|
125
|
+
export declare function seeerClip(params: {
|
|
126
|
+
videoUrl: string;
|
|
127
|
+
start: number;
|
|
128
|
+
end: number;
|
|
129
|
+
}, opts?: SeeerCallOptions): Promise<{
|
|
130
|
+
url: string;
|
|
131
|
+
start: number;
|
|
132
|
+
end: number;
|
|
133
|
+
blob: string;
|
|
134
|
+
}>;
|
|
135
|
+
export declare function seeerAnnotate(params: {
|
|
136
|
+
videoUrl: string;
|
|
137
|
+
t?: number;
|
|
138
|
+
eventId?: number;
|
|
139
|
+
annotations?: boolean;
|
|
140
|
+
showEvents?: boolean;
|
|
141
|
+
showClicks?: boolean;
|
|
142
|
+
showTrail?: boolean;
|
|
143
|
+
allEvents?: boolean;
|
|
144
|
+
includeClean?: boolean;
|
|
145
|
+
width?: number;
|
|
146
|
+
}, opts?: SeeerCallOptions): Promise<{
|
|
147
|
+
t: number;
|
|
148
|
+
resolution: [number, number];
|
|
149
|
+
annotated?: string;
|
|
150
|
+
clean?: string;
|
|
151
|
+
events: SeeerEvent[];
|
|
152
|
+
}>;
|
|
153
|
+
//# sourceMappingURL=seeer-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seeer-client.d.ts","sourceRoot":"","sources":["../src/seeer-client.ts"],"names":[],"mappings":"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"}
|