@xrkseek/harness 0.4.6 → 0.4.8
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/node_modules/@xrkseek/a2a/README.md +3 -3
- package/node_modules/@xrkseek/a2a/dist/inbound-frame.d.ts +13 -0
- package/node_modules/@xrkseek/a2a/dist/inbound-frame.d.ts.map +1 -0
- package/node_modules/@xrkseek/a2a/dist/inbound-frame.js +32 -0
- package/node_modules/@xrkseek/a2a/dist/inbound-frame.js.map +1 -0
- package/node_modules/@xrkseek/a2a/dist/inbound.d.ts +2 -2
- package/node_modules/@xrkseek/a2a/dist/index.d.ts +1 -0
- package/node_modules/@xrkseek/a2a/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/a2a/dist/index.js +1 -0
- package/node_modules/@xrkseek/a2a/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/attachment/dist/error.d.ts +1 -1
- package/node_modules/@xrkseek/attachment/dist/error.d.ts.map +1 -1
- package/node_modules/@xrkseek/attachment/dist/error.js.map +1 -1
- package/node_modules/@xrkseek/attachment/dist/image-region.d.ts +45 -0
- package/node_modules/@xrkseek/attachment/dist/image-region.d.ts.map +1 -0
- package/node_modules/@xrkseek/attachment/dist/image-region.js +64 -0
- package/node_modules/@xrkseek/attachment/dist/image-region.js.map +1 -0
- package/node_modules/@xrkseek/attachment/dist/index.d.ts +1 -0
- package/node_modules/@xrkseek/attachment/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/attachment/dist/index.js +1 -0
- package/node_modules/@xrkseek/attachment/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/attachment/dist/store.d.ts +7 -0
- package/node_modules/@xrkseek/attachment/dist/store.d.ts.map +1 -1
- package/node_modules/@xrkseek/attachment-local/dist/crop-region.d.ts +10 -0
- package/node_modules/@xrkseek/attachment-local/dist/crop-region.d.ts.map +1 -0
- package/node_modules/@xrkseek/attachment-local/dist/crop-region.js +53 -0
- package/node_modules/@xrkseek/attachment-local/dist/crop-region.js.map +1 -0
- package/node_modules/@xrkseek/attachment-local/dist/index.d.ts +1 -0
- package/node_modules/@xrkseek/attachment-local/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/attachment-local/dist/index.js +3 -0
- package/node_modules/@xrkseek/attachment-local/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/core-agent-loop/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/core-agent-loop/dist/index.js +13 -5
- package/node_modules/@xrkseek/core-agent-loop/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/exec-fs/dist/index.d.ts +1 -0
- package/node_modules/@xrkseek/exec-fs/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/exec-fs/dist/index.js +3 -0
- package/node_modules/@xrkseek/exec-fs/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/exec-fs/dist/present-deliverable.d.ts +25 -0
- package/node_modules/@xrkseek/exec-fs/dist/present-deliverable.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-fs/dist/present-deliverable.js +107 -0
- package/node_modules/@xrkseek/exec-fs/dist/present-deliverable.js.map +1 -0
- package/node_modules/@xrkseek/exec-fs/dist/read-image.d.ts +5 -0
- package/node_modules/@xrkseek/exec-fs/dist/read-image.d.ts.map +1 -1
- package/node_modules/@xrkseek/exec-fs/dist/read-image.js +55 -7
- package/node_modules/@xrkseek/exec-fs/dist/read-image.js.map +1 -1
- package/node_modules/@xrkseek/exec-image-gen/README.md +3 -3
- package/node_modules/@xrkseek/exec-memory/dist/http.d.ts +4 -4
- package/node_modules/@xrkseek/exec-memory/dist/http.d.ts.map +1 -1
- package/node_modules/@xrkseek/exec-memory/dist/http.js +9 -10
- package/node_modules/@xrkseek/exec-memory/dist/http.js.map +1 -1
- package/node_modules/@xrkseek/exec-memory/dist/resolve.d.ts +2 -10
- package/node_modules/@xrkseek/exec-memory/dist/resolve.d.ts.map +1 -1
- package/node_modules/@xrkseek/exec-memory/dist/resolve.js +2 -7
- package/node_modules/@xrkseek/exec-memory/dist/resolve.js.map +1 -1
- package/node_modules/@xrkseek/exec-ssh/README.md +3 -0
- package/node_modules/@xrkseek/exec-ssh/dist/index.d.ts +2 -1
- package/node_modules/@xrkseek/exec-ssh/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/exec-ssh/dist/index.js +2 -1
- package/node_modules/@xrkseek/exec-ssh/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/exec-ssh/dist/probe.d.ts +26 -0
- package/node_modules/@xrkseek/exec-ssh/dist/probe.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-ssh/dist/probe.js +50 -0
- package/node_modules/@xrkseek/exec-ssh/dist/probe.js.map +1 -0
- package/node_modules/@xrkseek/exec-ssh/dist/providers.d.ts +8 -0
- package/node_modules/@xrkseek/exec-ssh/dist/providers.d.ts.map +1 -1
- package/node_modules/@xrkseek/exec-ssh/dist/providers.js +25 -0
- package/node_modules/@xrkseek/exec-ssh/dist/providers.js.map +1 -1
- package/node_modules/@xrkseek/exec-video-analyze/README.md +11 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/format.d.ts +3 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/format.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/format.js +10 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/format.js.map +1 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/index.d.ts +39 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/index.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/index.js +64 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/index.js.map +1 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/materialize.d.ts +22 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/materialize.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/materialize.js +70 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/materialize.js.map +1 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/memory.d.ts +8 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/memory.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/memory.js +21 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/memory.js.map +1 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/mime.d.ts +13 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/mime.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/mime.js +44 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/mime.js.map +1 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/openai-http.d.ts +15 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/openai-http.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/openai-http.js +102 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/openai-http.js.map +1 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/tools.d.ts +24 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/tools.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/tools.js +120 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/tools.js.map +1 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/types.d.ts +30 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/types.d.ts.map +1 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/types.js +16 -0
- package/node_modules/@xrkseek/exec-video-analyze/dist/types.js.map +1 -0
- package/node_modules/@xrkseek/exec-video-analyze/package.json +26 -0
- package/node_modules/@xrkseek/exec-video-gen/README.md +3 -4
- package/node_modules/@xrkseek/im-gateway-contract/dist/index.d.ts +7 -0
- package/node_modules/@xrkseek/im-gateway-contract/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/im-gateway-contract/dist/index.js +29 -0
- package/node_modules/@xrkseek/im-gateway-contract/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/preset-harness/dist/preset.d.ts +14 -0
- package/node_modules/@xrkseek/preset-harness/dist/preset.d.ts.map +1 -1
- package/node_modules/@xrkseek/preset-harness/dist/preset.js +38 -2
- package/node_modules/@xrkseek/preset-harness/dist/preset.js.map +1 -1
- package/node_modules/@xrkseek/preset-harness/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@xrkseek/preset-harness/package.json +1 -0
- package/node_modules/@xrkseek/preset-minimal/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@xrkseek/preset-server/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@xrkseek/protocol/dist/index.d.ts +1 -1
- package/node_modules/@xrkseek/protocol/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/protocol/dist/index.js +1 -1
- package/node_modules/@xrkseek/protocol/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/protocol/dist/json-schema.d.ts +12 -0
- package/node_modules/@xrkseek/protocol/dist/json-schema.d.ts.map +1 -1
- package/node_modules/@xrkseek/protocol/dist/json-schema.js +23 -0
- package/node_modules/@xrkseek/protocol/dist/json-schema.js.map +1 -1
- package/node_modules/@xrkseek/protocol/dist/session-events.d.ts +24 -1
- package/node_modules/@xrkseek/protocol/dist/session-events.d.ts.map +1 -1
- package/node_modules/@xrkseek/protocol/dist/session-events.js +12 -0
- package/node_modules/@xrkseek/protocol/dist/session-events.js.map +1 -1
- package/node_modules/@xrkseek/protocol/dist/validate.d.ts.map +1 -1
- package/node_modules/@xrkseek/protocol/dist/validate.js +32 -0
- package/node_modules/@xrkseek/protocol/dist/validate.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/adapt/tool-view.d.ts +6 -0
- package/node_modules/@xrkseek/server-face/dist/adapt/tool-view.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/adapt/tool-view.js +8 -0
- package/node_modules/@xrkseek/server-face/dist/adapt/tool-view.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/adapt/wire-event.d.ts +1 -0
- package/node_modules/@xrkseek/server-face/dist/adapt/wire-event.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/adapt/wire-event.js +15 -0
- package/node_modules/@xrkseek/server-face/dist/adapt/wire-event.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/adapt/wire-ids.d.ts +6 -0
- package/node_modules/@xrkseek/server-face/dist/adapt/wire-ids.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/adapt/wire-ids.js +16 -0
- package/node_modules/@xrkseek/server-face/dist/adapt/wire-ids.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/approval-category.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/approval-category.js +2 -1
- package/node_modules/@xrkseek/server-face/dist/approval-category.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/cost-meter-store.d.ts +2 -0
- package/node_modules/@xrkseek/server-face/dist/cost-meter-store.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/cost-meter-store.js +4 -0
- package/node_modules/@xrkseek/server-face/dist/cost-meter-store.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/index.d.ts +2 -2
- package/node_modules/@xrkseek/server-face/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/index.js +2 -2
- package/node_modules/@xrkseek/server-face/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/process-channels.d.ts +10 -2
- package/node_modules/@xrkseek/server-face/dist/process-channels.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/process-channels.js +14 -9
- package/node_modules/@xrkseek/server-face/dist/process-channels.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/runtime.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/runtime.js +7 -2
- package/node_modules/@xrkseek/server-face/dist/runtime.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/session-export.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/session-export.js +12 -0
- package/node_modules/@xrkseek/server-face/dist/session-export.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/session-status.d.ts +30 -2
- package/node_modules/@xrkseek/server-face/dist/session-status.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/session-status.js +82 -24
- package/node_modules/@xrkseek/server-face/dist/session-status.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-credentials.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-credentials.js +5 -0
- package/node_modules/@xrkseek/server-face/dist/settings-credentials.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-document.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-document.js +4 -0
- package/node_modules/@xrkseek/server-face/dist/settings-document.js.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-schemas.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-face/dist/settings-schemas.js +35 -0
- package/node_modules/@xrkseek/server-face/dist/settings-schemas.js.map +1 -1
- package/node_modules/@xrkseek/server-host/dist/a2a-inbound-public.d.ts +38 -1
- package/node_modules/@xrkseek/server-host/dist/a2a-inbound-public.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-host/dist/a2a-inbound-public.js +121 -9
- package/node_modules/@xrkseek/server-host/dist/a2a-inbound-public.js.map +1 -1
- package/node_modules/@xrkseek/server-host/dist/index.d.ts +12 -2
- package/node_modules/@xrkseek/server-host/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-host/dist/index.js +75 -5
- package/node_modules/@xrkseek/server-host/dist/index.js.map +1 -1
- package/node_modules/@xrkseek/server-host/package.json +1 -0
- package/node_modules/@xrkseek/server-http/dist/dsh-compat/auto-review-classifier.d.ts +21 -0
- package/node_modules/@xrkseek/server-http/dist/dsh-compat/auto-review-classifier.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-http/dist/dsh-compat/auto-review-classifier.js +44 -0
- package/node_modules/@xrkseek/server-http/dist/dsh-compat/auto-review-classifier.js.map +1 -1
- package/node_modules/@xrkseek/server-http/dist/dsh-compat/im-gateway-sidecar.d.ts +2 -3
- package/node_modules/@xrkseek/server-http/dist/dsh-compat/im-gateway-sidecar.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-http/dist/dsh-compat/im-gateway-sidecar.js +2 -28
- package/node_modules/@xrkseek/server-http/dist/dsh-compat/im-gateway-sidecar.js.map +1 -1
- package/node_modules/@xrkseek/server-http/dist/dsh-compat/index.d.ts +2 -2
- package/node_modules/@xrkseek/server-http/dist/dsh-compat/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-http/dist/dsh-compat/index.js +1 -1
- package/node_modules/@xrkseek/server-http/dist/dsh-compat/index.js.map +1 -1
- package/node_modules/@xrkseek/server-http/dist/index.d.ts +1 -1
- package/node_modules/@xrkseek/server-http/dist/index.d.ts.map +1 -1
- package/node_modules/@xrkseek/server-http/dist/index.js +1 -1
- package/node_modules/@xrkseek/server-http/dist/index.js.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Materialize a video from http(s) URL or local workspace path.
|
|
3
|
+
*/
|
|
4
|
+
import { extname } from "node:path";
|
|
5
|
+
import { assertVideoByteBudget, MAX_VIDEO_BYTES, unsupportedVideoFormatMessage, videoMimeForPath, } from "./mime.js";
|
|
6
|
+
import { VideoAnalyzeError } from "./types.js";
|
|
7
|
+
function isHttpUrl(raw) {
|
|
8
|
+
const lower = raw.trim().toLowerCase();
|
|
9
|
+
return lower.startsWith("http://") || lower.startsWith("https://");
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Load video bytes for analysis.
|
|
13
|
+
* - http(s): download with Accept video/*, capped at MAX_VIDEO_BYTES
|
|
14
|
+
* - else: workspace path via injected Fs (same world as read_image)
|
|
15
|
+
*/
|
|
16
|
+
export async function materializeVideo(videoUrl, options = {}) {
|
|
17
|
+
const source = videoUrl.trim();
|
|
18
|
+
if (!source) {
|
|
19
|
+
throw new VideoAnalyzeError("video_url must be a non-empty string", "VIDEO_ANALYZE_BAD_ARGS");
|
|
20
|
+
}
|
|
21
|
+
if (isHttpUrl(source)) {
|
|
22
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
23
|
+
let res;
|
|
24
|
+
try {
|
|
25
|
+
res = await fetchImpl(source, {
|
|
26
|
+
method: "GET",
|
|
27
|
+
headers: { Accept: "video/*,*/*;q=0.8" },
|
|
28
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
29
|
+
redirect: "follow",
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
throw new VideoAnalyzeError(`Failed to download video: ${err instanceof Error ? err.message : String(err)}`, "VIDEO_ANALYZE_FETCH", { cause: err });
|
|
34
|
+
}
|
|
35
|
+
if (!res.ok) {
|
|
36
|
+
throw new VideoAnalyzeError(`Video download HTTP ${res.status}`, "VIDEO_ANALYZE_FETCH");
|
|
37
|
+
}
|
|
38
|
+
const contentLength = Number(res.headers.get("content-length") ?? "");
|
|
39
|
+
if (Number.isFinite(contentLength) && contentLength > MAX_VIDEO_BYTES) {
|
|
40
|
+
assertVideoByteBudget(contentLength);
|
|
41
|
+
}
|
|
42
|
+
const ab = await res.arrayBuffer();
|
|
43
|
+
const data = new Uint8Array(ab);
|
|
44
|
+
assertVideoByteBudget(data.byteLength);
|
|
45
|
+
const headerType = (res.headers.get("content-type") ?? "")
|
|
46
|
+
.split(";")[0]
|
|
47
|
+
?.trim()
|
|
48
|
+
.toLowerCase();
|
|
49
|
+
const fromUrl = videoMimeForPath(new URL(source).pathname);
|
|
50
|
+
const mediaType = (headerType && headerType.startsWith("video/") ? headerType : undefined) ??
|
|
51
|
+
fromUrl ??
|
|
52
|
+
"video/mp4";
|
|
53
|
+
return { data, mediaType, source: "url" };
|
|
54
|
+
}
|
|
55
|
+
const mime = videoMimeForPath(source);
|
|
56
|
+
if (!mime) {
|
|
57
|
+
throw new VideoAnalyzeError(unsupportedVideoFormatMessage(extname(source).toLowerCase() || "(none)"), "VIDEO_ANALYZE_UNSUPPORTED");
|
|
58
|
+
}
|
|
59
|
+
if (!options.fs) {
|
|
60
|
+
throw new VideoAnalyzeError("Local video paths require a workspace filesystem (Host harness fs).", "VIDEO_ANALYZE_BAD_ARGS");
|
|
61
|
+
}
|
|
62
|
+
const st = await options.fs.stat(source);
|
|
63
|
+
if (!st.isFile) {
|
|
64
|
+
throw new VideoAnalyzeError(`cannot read "${source}": not a regular file`, "VIDEO_ANALYZE_BAD_ARGS");
|
|
65
|
+
}
|
|
66
|
+
const data = await options.fs.readBytes(source, MAX_VIDEO_BYTES + 1);
|
|
67
|
+
assertVideoByteBudget(data.byteLength);
|
|
68
|
+
return { data, mediaType: mime, source: "path" };
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=materialize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"materialize.js","sourceRoot":"","sources":["../src/materialize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** In-memory Provider for CI / unit tests (no network). */
|
|
2
|
+
import type { VideoAnalyzeService } from "./types.js";
|
|
3
|
+
export interface MemoryVideoAnalyzeOptions {
|
|
4
|
+
/** Fixed analysis text; default summarizes byte length + prompt head. */
|
|
5
|
+
readonly analysis?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function createMemoryVideoAnalyzeProvider(options?: MemoryVideoAnalyzeOptions): VideoAnalyzeService;
|
|
8
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAE3D,OAAO,KAAK,EAGV,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,yBAAyB;IACxC,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,gCAAgC,CAC9C,OAAO,GAAE,yBAA8B,GACtC,mBAAmB,CAqBrB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** In-memory Provider for CI / unit tests (no network). */
|
|
2
|
+
import { VideoAnalyzeError } from "./types.js";
|
|
3
|
+
export function createMemoryVideoAnalyzeProvider(options = {}) {
|
|
4
|
+
return {
|
|
5
|
+
async analyze(req) {
|
|
6
|
+
if (!req.data.byteLength) {
|
|
7
|
+
throw new VideoAnalyzeError("Video bytes must be non-empty.", "VIDEO_ANALYZE_BAD_ARGS");
|
|
8
|
+
}
|
|
9
|
+
const promptHead = req.prompt.slice(0, 80).replace(/\s+/g, " ");
|
|
10
|
+
const analysis = options.analysis ??
|
|
11
|
+
`[memory-video-analyze] bytes=${req.data.byteLength} mime=${req.mediaType} prompt=${promptHead}`;
|
|
12
|
+
return {
|
|
13
|
+
analysis,
|
|
14
|
+
provider: "memory",
|
|
15
|
+
model: req.model ?? "memory",
|
|
16
|
+
note: "deterministic stub — not a real multimodal model",
|
|
17
|
+
};
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAO3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAO/C,MAAM,UAAU,gCAAgC,CAC9C,UAAqC,EAAE;IAEvC,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,GAAwB;YACpC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;gBACzB,MAAM,IAAI,iBAAiB,CACzB,gCAAgC,EAChC,wBAAwB,CACzB,CAAC;YACJ,CAAC;YACD,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAChE,MAAM,QAAQ,GACZ,OAAO,CAAC,QAAQ;gBAChB,gCAAgC,GAAG,CAAC,IAAI,CAAC,UAAU,SAAS,GAAG,CAAC,SAAS,WAAW,UAAU,EAAE,CAAC;YACnG,OAAO;gBACL,QAAQ;gBACR,QAAQ,EAAE,QAAQ;gBAClB,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,QAAQ;gBAC5B,IAAI,EAAE,kDAAkD;aACzD,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Hermes-aligned video MIME map and size caps. */
|
|
2
|
+
/** Extension → MIME. avi/mkv fall back to mp4 (Hermes). */
|
|
3
|
+
export declare const VIDEO_MIME_BY_EXT: Readonly<Record<string, string>>;
|
|
4
|
+
/** Soft warn threshold (Hermes logs above this). */
|
|
5
|
+
export declare const VIDEO_SIZE_WARN_BYTES: number;
|
|
6
|
+
/** Hard cap for download / base64 payload (Hermes 50 MB). */
|
|
7
|
+
export declare const MAX_VIDEO_BYTES: number;
|
|
8
|
+
export declare function videoMimeForPath(filePath: string): string | undefined;
|
|
9
|
+
export declare function unsupportedVideoFormatMessage(suffix: string): string;
|
|
10
|
+
export declare function assertVideoByteBudget(byteLength: number): void;
|
|
11
|
+
/** Hermes prompt wrap: full description first, then the caller's question. */
|
|
12
|
+
export declare function wrapVideoAnalyzePrompt(question: string): string;
|
|
13
|
+
//# sourceMappingURL=mime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mime.d.ts","sourceRoot":"","sources":["../src/mime.ts"],"names":[],"mappings":"AAAA,mDAAmD;AAInD,2DAA2D;AAC3D,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQ9D,CAAC;AAEF,oDAAoD;AACpD,eAAO,MAAM,qBAAqB,QAAmB,CAAC;AAEtD,6DAA6D;AAC7D,eAAO,MAAM,eAAe,QAAmB,CAAC;AAEhD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKrE;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKpE;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAc9D;AAED,8EAA8E;AAC9E,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAO/D"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Hermes-aligned video MIME map and size caps. */
|
|
2
|
+
import { VideoAnalyzeError } from "./types.js";
|
|
3
|
+
/** Extension → MIME. avi/mkv fall back to mp4 (Hermes). */
|
|
4
|
+
export const VIDEO_MIME_BY_EXT = {
|
|
5
|
+
".mp4": "video/mp4",
|
|
6
|
+
".webm": "video/webm",
|
|
7
|
+
".mov": "video/quicktime",
|
|
8
|
+
".avi": "video/mp4",
|
|
9
|
+
".mkv": "video/mp4",
|
|
10
|
+
".mpeg": "video/mpeg",
|
|
11
|
+
".mpg": "video/mpeg",
|
|
12
|
+
};
|
|
13
|
+
/** Soft warn threshold (Hermes logs above this). */
|
|
14
|
+
export const VIDEO_SIZE_WARN_BYTES = 20 * 1024 * 1024;
|
|
15
|
+
/** Hard cap for download / base64 payload (Hermes 50 MB). */
|
|
16
|
+
export const MAX_VIDEO_BYTES = 50 * 1024 * 1024;
|
|
17
|
+
export function videoMimeForPath(filePath) {
|
|
18
|
+
const lower = filePath.toLowerCase();
|
|
19
|
+
const dot = lower.lastIndexOf(".");
|
|
20
|
+
if (dot < 0)
|
|
21
|
+
return undefined;
|
|
22
|
+
return VIDEO_MIME_BY_EXT[lower.slice(dot)];
|
|
23
|
+
}
|
|
24
|
+
export function unsupportedVideoFormatMessage(suffix) {
|
|
25
|
+
return (`Unsupported video format: '${suffix}'. Supported: ` +
|
|
26
|
+
`${Object.keys(VIDEO_MIME_BY_EXT).sort().join(", ")}`);
|
|
27
|
+
}
|
|
28
|
+
export function assertVideoByteBudget(byteLength) {
|
|
29
|
+
if (byteLength <= 0) {
|
|
30
|
+
throw new VideoAnalyzeError("Video bytes must be non-empty.", "VIDEO_ANALYZE_BAD_ARGS");
|
|
31
|
+
}
|
|
32
|
+
if (byteLength > MAX_VIDEO_BYTES) {
|
|
33
|
+
throw new VideoAnalyzeError(`Video too large: ${(byteLength / (1024 * 1024)).toFixed(1)} MB ` +
|
|
34
|
+
`(limit ${MAX_VIDEO_BYTES / (1024 * 1024)} MB). Compress or trim and retry.`, "VIDEO_ANALYZE_TOO_LARGE");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** Hermes prompt wrap: full description first, then the caller's question. */
|
|
38
|
+
export function wrapVideoAnalyzePrompt(question) {
|
|
39
|
+
const q = question.trim();
|
|
40
|
+
return ("Fully describe and explain everything happening in this video, " +
|
|
41
|
+
"including visual content, motion, audio cues, text overlays, and scene " +
|
|
42
|
+
`transitions. Then answer the following question:\n\n${q}`);
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=mime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mime.js","sourceRoot":"","sources":["../src/mime.ts"],"names":[],"mappings":"AAAA,mDAAmD;AAEnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,2DAA2D;AAC3D,MAAM,CAAC,MAAM,iBAAiB,GAAqC;IACjE,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,iBAAiB;IACzB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,YAAY;CACrB,CAAC;AAEF,oDAAoD;AACpD,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAEtD,6DAA6D;AAC7D,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAEhD,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,GAAG,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9B,OAAO,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,MAAc;IAC1D,OAAO,CACL,8BAA8B,MAAM,gBAAgB;QACpD,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,UAAkB;IACtD,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,iBAAiB,CACzB,gCAAgC,EAChC,wBAAwB,CACzB,CAAC;IACJ,CAAC;IACD,IAAI,UAAU,GAAG,eAAe,EAAE,CAAC;QACjC,MAAM,IAAI,iBAAiB,CACzB,oBAAoB,CAAC,UAAU,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;YAC/D,UAAU,eAAe,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,mCAAmC,EAC9E,yBAAyB,CAC1B,CAAC;IACJ,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,sBAAsB,CAAC,QAAgB;IACrD,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC1B,OAAO,CACL,iEAAiE;QACjE,yEAAyE;QACzE,uDAAuD,CAAC,EAAE,CAC3D,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI-compatible chat completions with a Hermes-style `video_url` part.
|
|
3
|
+
* Needs a video-capable model (e.g. Gemini via a compatible gateway).
|
|
4
|
+
*/
|
|
5
|
+
import type { VideoAnalyzeService } from "./types.js";
|
|
6
|
+
export interface OpenAiVideoAnalyzeOptions {
|
|
7
|
+
readonly apiKey: string;
|
|
8
|
+
readonly baseUrl?: string;
|
|
9
|
+
readonly model?: string;
|
|
10
|
+
readonly fetchImpl?: typeof fetch;
|
|
11
|
+
/** Request timeout hint for AbortSignal when caller omits one (ms). */
|
|
12
|
+
readonly timeoutMs?: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function createOpenAiVideoAnalyzeProvider(options: OpenAiVideoAnalyzeOptions): VideoAnalyzeService;
|
|
15
|
+
//# sourceMappingURL=openai-http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-http.d.ts","sourceRoot":"","sources":["../src/openai-http.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAGV,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IAClC,uEAAuE;IACvE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AA8BD,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,yBAAyB,GACjC,mBAAmB,CAwFrB"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { VideoAnalyzeError } from "./types.js";
|
|
2
|
+
function joinUrl(base, path) {
|
|
3
|
+
return `${base.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
|
|
4
|
+
}
|
|
5
|
+
function bytesToDataUrl(data, mediaType) {
|
|
6
|
+
return `data:${mediaType};base64,${Buffer.from(data).toString("base64")}`;
|
|
7
|
+
}
|
|
8
|
+
function extractAssistantText(body) {
|
|
9
|
+
if (!body || typeof body !== "object")
|
|
10
|
+
return undefined;
|
|
11
|
+
const choices = body.choices;
|
|
12
|
+
if (!Array.isArray(choices) || choices.length === 0)
|
|
13
|
+
return undefined;
|
|
14
|
+
const message = choices[0].message;
|
|
15
|
+
const content = message?.content;
|
|
16
|
+
if (typeof content === "string" && content.trim())
|
|
17
|
+
return content.trim();
|
|
18
|
+
if (Array.isArray(content)) {
|
|
19
|
+
const texts = content
|
|
20
|
+
.filter((part) => typeof part === "object" && part !== null)
|
|
21
|
+
.map((part) => (typeof part.text === "string" ? part.text : ""))
|
|
22
|
+
.filter(Boolean);
|
|
23
|
+
if (texts.length)
|
|
24
|
+
return texts.join("\n").trim();
|
|
25
|
+
}
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
export function createOpenAiVideoAnalyzeProvider(options) {
|
|
29
|
+
const baseUrl = (options.baseUrl ?? "https://api.openai.com/v1").replace(/\/+$/, "");
|
|
30
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
31
|
+
const defaultModel = options.model?.trim() || "gemini-2.0-flash";
|
|
32
|
+
const timeoutMs = options.timeoutMs ?? 180_000;
|
|
33
|
+
return {
|
|
34
|
+
async analyze(req) {
|
|
35
|
+
if (!req.data.byteLength) {
|
|
36
|
+
throw new VideoAnalyzeError("Video bytes must be non-empty.", "VIDEO_ANALYZE_BAD_ARGS");
|
|
37
|
+
}
|
|
38
|
+
const model = req.model?.trim() || defaultModel;
|
|
39
|
+
const dataUrl = bytesToDataUrl(req.data, req.mediaType);
|
|
40
|
+
// Hermes hard-caps the base64 *string* length at 50MB; we already capped raw bytes.
|
|
41
|
+
const controller = new AbortController();
|
|
42
|
+
const onAbort = () => {
|
|
43
|
+
controller.abort(req.signal?.reason);
|
|
44
|
+
};
|
|
45
|
+
req.signal?.addEventListener("abort", onAbort, { once: true });
|
|
46
|
+
const timer = setTimeout(() => {
|
|
47
|
+
controller.abort(new Error(`video_analyze timed out after ${timeoutMs}ms`));
|
|
48
|
+
}, timeoutMs);
|
|
49
|
+
try {
|
|
50
|
+
const res = await fetchImpl(joinUrl(baseUrl, "chat/completions"), {
|
|
51
|
+
method: "POST",
|
|
52
|
+
headers: {
|
|
53
|
+
Authorization: `Bearer ${options.apiKey}`,
|
|
54
|
+
"Content-Type": "application/json",
|
|
55
|
+
},
|
|
56
|
+
signal: controller.signal,
|
|
57
|
+
body: JSON.stringify({
|
|
58
|
+
model,
|
|
59
|
+
messages: [
|
|
60
|
+
{
|
|
61
|
+
role: "user",
|
|
62
|
+
content: [
|
|
63
|
+
{ type: "text", text: req.prompt },
|
|
64
|
+
{
|
|
65
|
+
type: "video_url",
|
|
66
|
+
video_url: { url: dataUrl },
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
}),
|
|
72
|
+
});
|
|
73
|
+
const rawText = await res.text().catch(() => "");
|
|
74
|
+
if (!res.ok) {
|
|
75
|
+
throw new VideoAnalyzeError(`Video analyze HTTP ${res.status}: ${rawText.slice(0, 240)}`, "VIDEO_ANALYZE_BACKEND");
|
|
76
|
+
}
|
|
77
|
+
let parsed;
|
|
78
|
+
try {
|
|
79
|
+
parsed = JSON.parse(rawText);
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
throw new VideoAnalyzeError("Video analyze response was not JSON", "VIDEO_ANALYZE_BACKEND", { cause: err });
|
|
83
|
+
}
|
|
84
|
+
const analysis = extractAssistantText(parsed);
|
|
85
|
+
if (!analysis) {
|
|
86
|
+
throw new VideoAnalyzeError("Empty video analysis response", "VIDEO_ANALYZE_EMPTY");
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
analysis,
|
|
90
|
+
provider: "openai",
|
|
91
|
+
model,
|
|
92
|
+
note: `bytes=${req.data.byteLength}`,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
clearTimeout(timer);
|
|
97
|
+
req.signal?.removeEventListener("abort", onAbort);
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=openai-http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-http.js","sourceRoot":"","sources":["../src/openai-http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ToolDefinition } from "@xrkseek/core-tools";
|
|
2
|
+
import { VIDEO_ANALYZE_PROMPT_TEXT } from "./format.js";
|
|
3
|
+
import { type VideoAnalyzeFs } from "./materialize.js";
|
|
4
|
+
import { type VideoAnalyzeService } from "./types.js";
|
|
5
|
+
export { VIDEO_ANALYZE_PROMPT_TEXT };
|
|
6
|
+
export declare function videoAnalyzeUnavailableMessage(env?: NodeJS.ProcessEnv, product?: {
|
|
7
|
+
readonly mode?: string;
|
|
8
|
+
}): string;
|
|
9
|
+
export interface CreateVideoAnalyzeToolsOptions {
|
|
10
|
+
readonly service?: VideoAnalyzeService;
|
|
11
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
12
|
+
readonly product?: {
|
|
13
|
+
readonly mode?: string;
|
|
14
|
+
};
|
|
15
|
+
/** Workspace fs for local video paths (same world as read_image). */
|
|
16
|
+
readonly fs?: VideoAnalyzeFs;
|
|
17
|
+
readonly fetchImpl?: typeof fetch;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Hermes-style `video_analyze` — whole-video multimodal LLM → text JSON.
|
|
21
|
+
* Boundary: not browser_vision (page shot), not video_generate (creation).
|
|
22
|
+
*/
|
|
23
|
+
export declare function createVideoAnalyzeTools(options?: CreateVideoAnalyzeToolsOptions): ToolDefinition[];
|
|
24
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAqB,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAoB,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEzE,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,yBAAyB,EAAE,CAAC;AAErC,wBAAgB,8BAA8B,CAC5C,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACnC,MAAM,CAyBR;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,OAAO,CAAC,EAAE,mBAAmB,CAAC;IACvC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACjC,QAAQ,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,qEAAqE;IACrE,QAAQ,CAAC,EAAE,CAAC,EAAE,cAAc,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CACnC;AAYD;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,GAAE,8BAAmC,GAC3C,cAAc,EAAE,CAoGlB"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { VIDEO_ANALYZE_PROMPT_TEXT } from "./format.js";
|
|
2
|
+
import { materializeVideo } from "./materialize.js";
|
|
3
|
+
import { wrapVideoAnalyzePrompt } from "./mime.js";
|
|
4
|
+
import { isVideoAnalyzeError, } from "./types.js";
|
|
5
|
+
export { VIDEO_ANALYZE_PROMPT_TEXT };
|
|
6
|
+
export function videoAnalyzeUnavailableMessage(env = process.env, product) {
|
|
7
|
+
const envRaw = String(env.XRK_VIDEO_ANALYZE ?? "").trim();
|
|
8
|
+
const flag = envRaw !== ""
|
|
9
|
+
? envRaw.toLowerCase()
|
|
10
|
+
: product?.mode === "openai"
|
|
11
|
+
? "1"
|
|
12
|
+
: "";
|
|
13
|
+
if (!flag) {
|
|
14
|
+
return ("Error: video analysis is not enabled. Use Settings → Plugins → Video analyze, or set " +
|
|
15
|
+
"XRK_VIDEO_ANALYZE=memory (CI/demo) / XRK_VIDEO_ANALYZE=1 with OPENAI_API_KEY / " +
|
|
16
|
+
"XRK_VIDEO_ANALYZE_OPENAI_KEY. Needs a video-capable multimodal model (e.g. Gemini). " +
|
|
17
|
+
"See docs/video-analyze.md. Not for browser pages — use browser_vision.");
|
|
18
|
+
}
|
|
19
|
+
if (flag === "1" || flag === "openai") {
|
|
20
|
+
return ("Error: video analyze is enabled but no API key. Set Credentials XRK_VIDEO_ANALYZE_OPENAI_KEY " +
|
|
21
|
+
"(or OPENAI_API_KEY); optional base URL / model via Settings or env.");
|
|
22
|
+
}
|
|
23
|
+
return ("Error: no VideoAnalyzeService Provider is configured. Inject a service or set XRK_VIDEO_ANALYZE.");
|
|
24
|
+
}
|
|
25
|
+
function fail(err) {
|
|
26
|
+
const message = isVideoAnalyzeError(err)
|
|
27
|
+
? `Error: ${err.message}`
|
|
28
|
+
: `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
29
|
+
return {
|
|
30
|
+
content: JSON.stringify({ success: false, analysis: message }, null, 2),
|
|
31
|
+
isError: true,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Hermes-style `video_analyze` — whole-video multimodal LLM → text JSON.
|
|
36
|
+
* Boundary: not browser_vision (page shot), not video_generate (creation).
|
|
37
|
+
*/
|
|
38
|
+
export function createVideoAnalyzeTools(options = {}) {
|
|
39
|
+
const missing = videoAnalyzeUnavailableMessage(options.env ?? process.env, options.product);
|
|
40
|
+
const service = options.service;
|
|
41
|
+
const tool = {
|
|
42
|
+
name: "video_analyze",
|
|
43
|
+
description: "Analyze a video from a URL or local workspace path using a multimodal AI model. " +
|
|
44
|
+
"Sends the whole video (not individual frames) to a video-capable model for understanding — " +
|
|
45
|
+
"captions, scenes, motion, overlays. Use for video files; for images use read_image; " +
|
|
46
|
+
"for live browser pages use browser_vision; for creating videos use video_generate. " +
|
|
47
|
+
"Supports mp4, webm, mov, avi, mkv, mpeg. Large videos (>20 MB) may be slow; max ~50 MB.",
|
|
48
|
+
parameters: {
|
|
49
|
+
type: "object",
|
|
50
|
+
properties: {
|
|
51
|
+
video_url: {
|
|
52
|
+
type: "string",
|
|
53
|
+
description: "Video URL (http/https) or workspace-relative local file path to analyze.",
|
|
54
|
+
},
|
|
55
|
+
question: {
|
|
56
|
+
type: "string",
|
|
57
|
+
description: "Your specific question about the video. The model describes what happens and answers.",
|
|
58
|
+
},
|
|
59
|
+
model: {
|
|
60
|
+
type: "string",
|
|
61
|
+
description: "Optional override model id (video-capable multimodal).",
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
required: ["video_url", "question"],
|
|
65
|
+
},
|
|
66
|
+
isConcurrencySafe: () => true,
|
|
67
|
+
presentCall: (args) => ({
|
|
68
|
+
card: "generic",
|
|
69
|
+
title: "Video analyze",
|
|
70
|
+
kind: "execute",
|
|
71
|
+
rawInput: args,
|
|
72
|
+
}),
|
|
73
|
+
async execute(args) {
|
|
74
|
+
if (!service) {
|
|
75
|
+
return {
|
|
76
|
+
content: JSON.stringify({ success: false, analysis: missing }, null, 2),
|
|
77
|
+
isError: true,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
const videoUrl = String(args.video_url ?? "").trim();
|
|
82
|
+
const question = String(args.question ?? "").trim();
|
|
83
|
+
if (!videoUrl) {
|
|
84
|
+
return fail(new Error("video_url must be a non-empty string"));
|
|
85
|
+
}
|
|
86
|
+
if (!question) {
|
|
87
|
+
return fail(new Error("question must be a non-empty string"));
|
|
88
|
+
}
|
|
89
|
+
const materialized = await materializeVideo(videoUrl, {
|
|
90
|
+
...(options.fs ? { fs: options.fs } : {}),
|
|
91
|
+
...(options.fetchImpl ? { fetchImpl: options.fetchImpl } : {}),
|
|
92
|
+
});
|
|
93
|
+
const prompt = wrapVideoAnalyzePrompt(question);
|
|
94
|
+
const result = await service.analyze({
|
|
95
|
+
data: materialized.data,
|
|
96
|
+
mediaType: materialized.mediaType,
|
|
97
|
+
prompt,
|
|
98
|
+
...(args.model ? { model: String(args.model).trim() } : {}),
|
|
99
|
+
});
|
|
100
|
+
return {
|
|
101
|
+
content: JSON.stringify({
|
|
102
|
+
success: true,
|
|
103
|
+
analysis: result.analysis,
|
|
104
|
+
provider: result.provider,
|
|
105
|
+
model: result.model,
|
|
106
|
+
...(result.note ? { note: result.note } : {}),
|
|
107
|
+
source: materialized.source,
|
|
108
|
+
bytes: materialized.data.byteLength,
|
|
109
|
+
mediaType: materialized.mediaType,
|
|
110
|
+
}, null, 2),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
return fail(err);
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
return [tool];
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAuB,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EACL,mBAAmB,GAEpB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,yBAAyB,EAAE,CAAC;AAErC,MAAM,UAAU,8BAA8B,CAC5C,MAAyB,OAAO,CAAC,GAAG,EACpC,OAAoC;IAEpC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1D,MAAM,IAAI,GACR,MAAM,KAAK,EAAE;QACX,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE;QACtB,CAAC,CAAC,OAAO,EAAE,IAAI,KAAK,QAAQ;YAC1B,CAAC,CAAC,GAAG;YACL,CAAC,CAAC,EAAE,CAAC;IACX,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CACL,uFAAuF;YACvF,iFAAiF;YACjF,sFAAsF;YACtF,wEAAwE,CACzE,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,OAAO,CACL,+FAA+F;YAC/F,qEAAqE,CACtE,CAAC;IACJ,CAAC;IACD,OAAO,CACL,kGAAkG,CACnG,CAAC;AACJ,CAAC;AAWD,SAAS,IAAI,CAAC,GAAY;IACxB,MAAM,OAAO,GAAG,mBAAmB,CAAC,GAAG,CAAC;QACtC,CAAC,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE;QACzB,CAAC,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IACjE,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACvE,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,UAA0C,EAAE;IAE5C,MAAM,OAAO,GAAG,8BAA8B,CAC5C,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAC1B,OAAO,CAAC,OAAO,CAChB,CAAC;IACF,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAEhC,MAAM,IAAI,GAIL;QACH,IAAI,EAAE,eAAe;QACrB,WAAW,EACT,kFAAkF;YAClF,6FAA6F;YAC7F,sFAAsF;YACtF,qFAAqF;YACrF,yFAAyF;QAC3F,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,SAAS,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,WAAW,EACT,0EAA0E;iBAC7E;gBACD,QAAQ,EAAE;oBACR,IAAI,EAAE,QAAQ;oBACd,WAAW,EACT,uFAAuF;iBAC1F;gBACD,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,wDAAwD;iBACtE;aACF;YACD,QAAQ,EAAE,CAAC,WAAW,EAAE,UAAU,CAAC;SACpC;QACD,iBAAiB,EAAE,GAAG,EAAE,CAAC,IAAI;QAC7B,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACtB,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,eAAe;YACtB,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,IAAI;SACf,CAAC;QACF,KAAK,CAAC,OAAO,CAAC,IAAI;YAChB,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO;oBACL,OAAO,EAAE,IAAI,CAAC,SAAS,CACrB,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EACrC,IAAI,EACJ,CAAC,CACF;oBACD,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBACrD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBACpD,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,OAAO,IAAI,CAAC,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC,CAAC;gBACjE,CAAC;gBACD,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,OAAO,IAAI,CAAC,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC,CAAC;gBAChE,CAAC;gBACD,MAAM,YAAY,GAAG,MAAM,gBAAgB,CAAC,QAAQ,EAAE;oBACpD,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACzC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC/D,CAAC,CAAC;gBACH,MAAM,MAAM,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;gBAChD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC;oBACnC,IAAI,EAAE,YAAY,CAAC,IAAI;oBACvB,SAAS,EAAE,YAAY,CAAC,SAAS;oBACjC,MAAM;oBACN,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC5D,CAAC,CAAC;gBACH,OAAO;oBACL,OAAO,EAAE,IAAI,CAAC,SAAS,CACrB;wBACE,OAAO,EAAE,IAAI;wBACb,QAAQ,EAAE,MAAM,CAAC,QAAQ;wBACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;wBACzB,KAAK,EAAE,MAAM,CAAC,KAAK;wBACnB,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC7C,MAAM,EAAE,YAAY,CAAC,MAAM;wBAC3B,KAAK,EAAE,YAAY,CAAC,IAAI,CAAC,UAAU;wBACnC,SAAS,EAAE,YAAY,CAAC,SAAS;qBAClC,EACD,IAAI,EACJ,CAAC,CACF;iBACF,CAAC;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;KACF,CAAC;IAEF,OAAO,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Video understanding Provider seam (Hermes `video_analyze`).
|
|
3
|
+
* Distinct from browser_vision (page screenshot) and video_generate (async render).
|
|
4
|
+
*/
|
|
5
|
+
export type VideoAnalyzeErrorCode = "VIDEO_ANALYZE_BAD_ARGS" | "VIDEO_ANALYZE_TOO_LARGE" | "VIDEO_ANALYZE_UNSUPPORTED" | "VIDEO_ANALYZE_FETCH" | "VIDEO_ANALYZE_BACKEND" | "VIDEO_ANALYZE_EMPTY";
|
|
6
|
+
export declare class VideoAnalyzeError extends Error {
|
|
7
|
+
readonly code: VideoAnalyzeErrorCode;
|
|
8
|
+
constructor(message: string, code: VideoAnalyzeErrorCode, options?: ErrorOptions);
|
|
9
|
+
}
|
|
10
|
+
export declare function isVideoAnalyzeError(err: unknown): err is VideoAnalyzeError;
|
|
11
|
+
export type VideoMediaType = "video/mp4" | "video/webm" | "video/quicktime" | "video/mpeg" | "video/x-msvideo" | "video/x-matroska";
|
|
12
|
+
export interface VideoAnalyzeRequest {
|
|
13
|
+
readonly data: Uint8Array;
|
|
14
|
+
readonly mediaType: string;
|
|
15
|
+
/** Fully expanded analysis prompt (Hermes wraps the user question). */
|
|
16
|
+
readonly prompt: string;
|
|
17
|
+
readonly model?: string;
|
|
18
|
+
readonly signal?: AbortSignal;
|
|
19
|
+
}
|
|
20
|
+
export interface VideoAnalyzeResult {
|
|
21
|
+
readonly analysis: string;
|
|
22
|
+
readonly provider: string;
|
|
23
|
+
readonly model: string;
|
|
24
|
+
readonly note?: string;
|
|
25
|
+
}
|
|
26
|
+
/** Swappable backend — OpenAI-compatible chat with video_url, or memory. */
|
|
27
|
+
export interface VideoAnalyzeService {
|
|
28
|
+
analyze(req: VideoAnalyzeRequest): Promise<VideoAnalyzeResult>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,qBAAqB,GAC7B,wBAAwB,GACxB,yBAAyB,GACzB,2BAA2B,GAC3B,qBAAqB,GACrB,uBAAuB,GACvB,qBAAqB,CAAC;AAE1B,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;gBAEnC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,qBAAqB,EAC3B,OAAO,CAAC,EAAE,YAAY;CAMzB;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,iBAAiB,CAE1E;AAED,MAAM,MAAM,cAAc,GACtB,WAAW,GACX,YAAY,GACZ,iBAAiB,GACjB,YAAY,GACZ,iBAAiB,GACjB,kBAAkB,CAAC;AAEvB,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,uEAAuE;IACvE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,4EAA4E;AAC5E,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAChE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Video understanding Provider seam (Hermes `video_analyze`).
|
|
3
|
+
* Distinct from browser_vision (page screenshot) and video_generate (async render).
|
|
4
|
+
*/
|
|
5
|
+
export class VideoAnalyzeError extends Error {
|
|
6
|
+
code;
|
|
7
|
+
constructor(message, code, options) {
|
|
8
|
+
super(message, options);
|
|
9
|
+
this.name = "VideoAnalyzeError";
|
|
10
|
+
this.code = code;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export function isVideoAnalyzeError(err) {
|
|
14
|
+
return err instanceof VideoAnalyzeError;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IACjC,IAAI,CAAwB;IACrC,YACE,OAAe,EACf,IAA2B,EAC3B,OAAsB;QAEtB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,MAAM,UAAU,mBAAmB,CAAC,GAAY;IAC9C,OAAO,GAAG,YAAY,iBAAiB,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@xrkseek/exec-video-analyze",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"import": "./dist/index.js",
|
|
9
|
+
"default": "./dist/index.js"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@xrkseek/core-tools": "workspace:*"
|
|
18
|
+
},
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/xrkseek/XRK-harness.git",
|
|
23
|
+
"directory": "packages/exec/video-analyze"
|
|
24
|
+
},
|
|
25
|
+
"private": true
|
|
26
|
+
}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Text-to-video / image-to-video Provider seam for the model tool surface.
|
|
4
4
|
|
|
5
|
+
**Product path**: Settings → Plugins → Video generation (Face ns `video-gen`). Credentials hold `XRK_VIDEO_GEN_OPENAI_KEY`. Env (`XRK_VIDEO_GEN=memory` / `=1`) is CI / headless bypass only — see [docs/video-gen.md](../../../docs/video-gen.md).
|
|
6
|
+
|
|
5
7
|
- **Definition**: `VideoGenService` — `create` · `get` · `content` (+ optional `capabilities`)
|
|
6
8
|
- **Provider**: `createMemoryVideoGenProvider` · `createOpenAiVideoGenProvider` · Host-injected
|
|
7
9
|
- **Consumer**: `createVideoGenTools` → `video_generate` (schema rebuilt from `capabilities()`)
|
|
@@ -18,10 +20,7 @@ Renders are asynchronous, so the seam exposes job semantics instead of one-shot
|
|
|
18
20
|
|
|
19
21
|
**Family catalog**: `capabilities().families` (Hermes fal-style; OpenAI lists sora-2 / sora-2-pro).
|
|
20
22
|
|
|
21
|
-
Env: `XRK_VIDEO_GEN=memory` | `XRK_VIDEO_GEN=1` + `OPENAI_API_KEY` / `XRK_VIDEO_GEN_OPENAI_KEY`
|
|
22
|
-
(optional `XRK_VIDEO_GEN_BASE_URL` · `XRK_VIDEO_GEN_MODEL`).
|
|
23
|
-
|
|
24
23
|
Video bytes are never inlined into tool text; with an `AttachmentStore` the finished MP4 is
|
|
25
24
|
persisted via `saveFile` and returned as an attachment id.
|
|
26
25
|
|
|
27
|
-
See
|
|
26
|
+
See also [docs/seams.md](../../../docs/seams.md).
|
|
@@ -72,6 +72,13 @@ export declare function parseRelayBody(raw: unknown): ImGatewayRelayParseResult;
|
|
|
72
72
|
export declare function interpretSidecarHealthBody(body: unknown, httpOk: boolean): ImGatewayProbeResult;
|
|
73
73
|
/** Derive Face/status `state` from config + optional probe. */
|
|
74
74
|
export declare function imGatewayStateFromProbe(config: ImGatewaySidecarConfig | undefined, probe?: ImGatewayProbeResult): ImGatewayState;
|
|
75
|
+
/** Host-local push path (no external sidecar required). */
|
|
76
|
+
export declare const IM_GATEWAY_HOST_LOCAL_WS_PATH = "/api/im/gateway/ws";
|
|
75
77
|
/** Build the canonical sidecar `/health` response body. */
|
|
76
78
|
export declare function sidecarHealthResponse(status?: string): ImGatewayHealthBody;
|
|
79
|
+
/**
|
|
80
|
+
* GET `{url}/health` on an external sidecar (doctor / Host boot).
|
|
81
|
+
* Does not embed vendor SDKs — only the ADR-0006 health probe.
|
|
82
|
+
*/
|
|
83
|
+
export declare function probeImGatewaySidecar(config: ImGatewaySidecarConfig, timeoutMs?: number): Promise<ImGatewayProbeResult>;
|
|
77
84
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|