dsh-pf-stream 0.0.0-stage → 0.1.2
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/LICENSE +201 -0
- package/README.en.md +110 -0
- package/README.md +109 -2
- package/cordis.patch.yml +2 -0
- package/lib/entry/adapter.d.ts +21 -0
- package/lib/entry/adapter.js +112 -0
- package/lib/entry/adapter.js.map +1 -0
- package/lib/entry/legacyNormalizer.d.ts +16 -0
- package/lib/entry/legacyNormalizer.js +86 -0
- package/lib/entry/legacyNormalizer.js.map +1 -0
- package/lib/errors.d.ts +7 -0
- package/lib/errors.js +12 -0
- package/lib/errors.js.map +1 -0
- package/lib/index.d.ts +108 -0
- package/lib/index.js +109 -0
- package/lib/index.js.map +1 -0
- package/lib/session/state.d.ts +25 -0
- package/lib/session/state.js +255 -0
- package/lib/session/state.js.map +1 -0
- package/lib/stage0/decoder.d.ts +57 -0
- package/lib/stage0/decoder.js +229 -0
- package/lib/stage0/decoder.js.map +1 -0
- package/lib/stage0/ffmpeg.d.ts +34 -0
- package/lib/stage0/ffmpeg.js +90 -0
- package/lib/stage0/ffmpeg.js.map +1 -0
- package/lib/stage0/probe.d.ts +47 -0
- package/lib/stage0/probe.js +150 -0
- package/lib/stage0/probe.js.map +1 -0
- package/lib/stage1/gradient.d.ts +27 -0
- package/lib/stage1/gradient.js +85 -0
- package/lib/stage1/gradient.js.map +1 -0
- package/lib/stage1/perceive.d.ts +66 -0
- package/lib/stage1/perceive.js +233 -0
- package/lib/stage1/perceive.js.map +1 -0
- package/lib/stage2/stateMachine.d.ts +70 -0
- package/lib/stage2/stateMachine.js +180 -0
- package/lib/stage2/stateMachine.js.map +1 -0
- package/lib/stage2/switchDetector.d.ts +18 -0
- package/lib/stage2/switchDetector.js +34 -0
- package/lib/stage2/switchDetector.js.map +1 -0
- package/lib/stage3/deterministicRouter.d.ts +44 -0
- package/lib/stage3/deterministicRouter.js +203 -0
- package/lib/stage3/deterministicRouter.js.map +1 -0
- package/lib/stage3/streamSampler.d.ts +74 -0
- package/lib/stage3/streamSampler.js +497 -0
- package/lib/stage3/streamSampler.js.map +1 -0
- package/lib/stage4/canvasPacker.d.ts +60 -0
- package/lib/stage4/canvasPacker.js +161 -0
- package/lib/stage4/canvasPacker.js.map +1 -0
- package/lib/stage4/markers.d.ts +19 -0
- package/lib/stage4/markers.js +98 -0
- package/lib/stage4/markers.js.map +1 -0
- package/lib/stage4/viewport.d.ts +61 -0
- package/lib/stage4/viewport.js +151 -0
- package/lib/stage4/viewport.js.map +1 -0
- package/lib/stage5/controller.d.ts +61 -0
- package/lib/stage5/controller.js +260 -0
- package/lib/stage5/controller.js.map +1 -0
- package/lib/stage5/intent.d.ts +27 -0
- package/lib/stage5/intent.js +87 -0
- package/lib/stage5/intent.js.map +1 -0
- package/lib/stage6/history.d.ts +52 -0
- package/lib/stage6/history.js +155 -0
- package/lib/stage6/history.js.map +1 -0
- package/lib/stage6/precheck.d.ts +56 -0
- package/lib/stage6/precheck.js +86 -0
- package/lib/stage6/precheck.js.map +1 -0
- package/lib/tool/handler.d.ts +35 -0
- package/lib/tool/handler.js +56 -0
- package/lib/tool/handler.js.map +1 -0
- package/lib/tool/schema.d.ts +29 -0
- package/lib/tool/schema.js +59 -0
- package/lib/tool/schema.js.map +1 -0
- package/lib/tool/streamCall.d.ts +41 -0
- package/lib/tool/streamCall.js +105 -0
- package/lib/tool/streamCall.js.map +1 -0
- package/lib/types.d.ts +355 -0
- package/lib/types.js +11 -0
- package/lib/types.js.map +1 -0
- package/lib/utils/ffmpegBin.d.ts +20 -0
- package/lib/utils/ffmpegBin.js +62 -0
- package/lib/utils/ffmpegBin.js.map +1 -0
- package/lib/utils/hash.d.ts +13 -0
- package/lib/utils/hash.js +24 -0
- package/lib/utils/hash.js.map +1 -0
- package/lib/utils/image.d.ts +32 -0
- package/lib/utils/image.js +135 -0
- package/lib/utils/image.js.map +1 -0
- package/lib/utils/pts.d.ts +15 -0
- package/lib/utils/pts.js +50 -0
- package/lib/utils/pts.js.map +1 -0
- package/package.json +55 -4
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 历史便捷字段归一化(《五、双层自适应调节与统一参数映射》§1.1)。
|
|
3
|
+
*
|
|
4
|
+
* 输入便利层:start_time/end_time/time_range/timestamps/fps/interval/num_frames/
|
|
5
|
+
* frame_count/crop/bbox/roi/probe_only → 标准 IntentDirective 字段。
|
|
6
|
+
* 判秒规则:数值 ≤ 时长(秒)×1.5 判秒,超过判毫秒;归一化来源记入 normalizedFrom。
|
|
7
|
+
*/
|
|
8
|
+
/** 数值或字符串时间 → 毫秒(判秒规则见模块注释)。 */
|
|
9
|
+
export function toMs(value, durationMs) {
|
|
10
|
+
const n = typeof value === 'string' ? Number.parseFloat(value) : value;
|
|
11
|
+
if (!Number.isFinite(n))
|
|
12
|
+
throw new Error(`时间值无法解析:${String(value)}`);
|
|
13
|
+
const secThreshold = (durationMs / 1000) * 1.5;
|
|
14
|
+
const ms = n <= secThreshold ? n * 1000 : n;
|
|
15
|
+
return Math.round(ms);
|
|
16
|
+
}
|
|
17
|
+
function normalizeRoi(raw) {
|
|
18
|
+
const clamp01 = (v) => Math.min(Math.max(v, 0), 1);
|
|
19
|
+
return {
|
|
20
|
+
x: clamp01(raw.x),
|
|
21
|
+
y: clamp01(raw.y),
|
|
22
|
+
w: Math.min(Math.max(raw.w, 0), 1 - clamp01(raw.x)),
|
|
23
|
+
h: Math.min(Math.max(raw.h, 0), 1 - clamp01(raw.y)),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export function normalizeLegacyArgs(args, durationMs) {
|
|
27
|
+
const intent = {};
|
|
28
|
+
const normalizedFrom = [];
|
|
29
|
+
const has = (k) => Object.prototype.hasOwnProperty.call(args, k) && args[k] !== undefined;
|
|
30
|
+
if (has('start_time') || has('end_time') || has('time_range')) {
|
|
31
|
+
const start = has('start_time') ? toMs(args['start_time'], durationMs) : 0;
|
|
32
|
+
const end = has('end_time')
|
|
33
|
+
? toMs(args['end_time'], durationMs)
|
|
34
|
+
: Math.max(start, durationMs);
|
|
35
|
+
intent.pts_window = [start, end];
|
|
36
|
+
normalizedFrom.push('start_time/end_time');
|
|
37
|
+
}
|
|
38
|
+
if (has('time_range') && Array.isArray(args['time_range']) && args['time_range'].length === 2) {
|
|
39
|
+
const [a, b] = args['time_range'];
|
|
40
|
+
if (a !== undefined && b !== undefined) {
|
|
41
|
+
intent.pts_window = [toMs(a, durationMs), toMs(b, durationMs)];
|
|
42
|
+
normalizedFrom.push('time_range');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (has('timestamps') && Array.isArray(args['timestamps'])) {
|
|
46
|
+
intent.timestamps_ms = args['timestamps'].map((t) => toMs(t, durationMs));
|
|
47
|
+
intent.action = 'timestamps';
|
|
48
|
+
normalizedFrom.push('timestamps');
|
|
49
|
+
}
|
|
50
|
+
if (has('fps')) {
|
|
51
|
+
const fps = Number(args['fps']);
|
|
52
|
+
if (Number.isFinite(fps) && fps > 0) {
|
|
53
|
+
intent.interval_ms = Math.round(1000 / fps);
|
|
54
|
+
intent.action = 'uniform';
|
|
55
|
+
normalizedFrom.push('fps');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (has('interval')) {
|
|
59
|
+
const iv = Number(args['interval']);
|
|
60
|
+
if (Number.isFinite(iv) && iv > 0) {
|
|
61
|
+
intent.interval_ms = toMs(iv, durationMs);
|
|
62
|
+
intent.action = 'uniform';
|
|
63
|
+
normalizedFrom.push('interval');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (has('num_frames') || has('frame_count')) {
|
|
67
|
+
const fc = Number(args['num_frames'] ?? args['frame_count']);
|
|
68
|
+
if (Number.isFinite(fc) && fc >= 1) {
|
|
69
|
+
intent.frame_count = Math.min(Math.round(fc), 128);
|
|
70
|
+
if (intent.action == null)
|
|
71
|
+
intent.action = 'uniform';
|
|
72
|
+
normalizedFrom.push('num_frames/frame_count');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const roiRaw = (args['crop'] ?? args['bbox'] ?? args['roi']);
|
|
76
|
+
if (roiRaw && typeof roiRaw === 'object') {
|
|
77
|
+
intent.roi_hint = normalizeRoi(roiRaw);
|
|
78
|
+
normalizedFrom.push('crop/bbox/roi');
|
|
79
|
+
}
|
|
80
|
+
if (args['probe_only'] === true) {
|
|
81
|
+
intent.action = 'probe';
|
|
82
|
+
normalizedFrom.push('probe_only');
|
|
83
|
+
}
|
|
84
|
+
return { intent, normalizedFrom };
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=legacyNormalizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacyNormalizer.js","sourceRoot":"","sources":["../../src/entry/legacyNormalizer.ts"],"names":[],"mappings":"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"}
|
package/lib/errors.d.ts
ADDED
package/lib/errors.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,OAAO,aAAc,SAAQ,KAAK;IAE3B;IADX,YACW,IAAY,EACrB,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;QAHN,SAAI,GAAJ,IAAI,CAAQ;QAIrB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF"}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-pf-stream — DeepSeek Harness 视频感知插件入口。
|
|
3
|
+
*
|
|
4
|
+
* 统一 action 路由:动态流式采样(pf_stream)与内建确定性检视
|
|
5
|
+
* (probe / timestamps / uniform / RoI)共用主工具 dsh-pf-stream。
|
|
6
|
+
*
|
|
7
|
+
* 工具表稳定性(Prefix KV-Cache):tools.register 在 apply 期一次装齐、
|
|
8
|
+
* dispose 期统一注销,运行中不增删。
|
|
9
|
+
*/
|
|
10
|
+
import Schema from '@deepseek-ai/schemastery';
|
|
11
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
12
|
+
import type { PfStreamPluginConfig } from './types.js';
|
|
13
|
+
import { type ToolCallArgs, type ToolExec, type ToolResult } from './tool/handler.js';
|
|
14
|
+
export declare const name = "dsh-pf-stream";
|
|
15
|
+
export declare const inject: string[];
|
|
16
|
+
/** 56 MiB = 58,720,256 字节(含 8 MiB Base64 编码膨胀与协议结构预留)。 */
|
|
17
|
+
export declare const DEFAULT_MAX_REQUEST_BYTES: number;
|
|
18
|
+
export declare const Config: Schema<Schemastery.ObjectS<NoInfer<{
|
|
19
|
+
renderVisualId: Schema<boolean, boolean, "defined">;
|
|
20
|
+
maxPacketsPerCall: Schema<number, number, "defined">;
|
|
21
|
+
maxTokensBudgetPerCall: Schema<number, number, "defined">;
|
|
22
|
+
maxRequestBytes: Schema<number, number, "defined">;
|
|
23
|
+
maxColdRefs: Schema<number, number, "defined">;
|
|
24
|
+
telemetryEnabled: Schema<boolean, boolean, "defined">;
|
|
25
|
+
ffmpegPath: Schema<string, string, "plain">;
|
|
26
|
+
ffprobePath: Schema<string, string, "plain">;
|
|
27
|
+
tempDir: Schema<string, string, "plain">;
|
|
28
|
+
contentHashFallback: Schema<boolean, boolean, "defined">;
|
|
29
|
+
defaultStreamWindowMs: Schema<number, number, "defined">;
|
|
30
|
+
streamWorkMaxEdge: Schema<number, number, "defined">;
|
|
31
|
+
epochCompactionWindow: Schema<number, number, "defined">;
|
|
32
|
+
meteringProfile: Schema<Schemastery.ObjectS<NoInfer<{
|
|
33
|
+
superpixelPx: Schema<42, 42, "plain">;
|
|
34
|
+
rounding: Schema<"ceil", "ceil", "plain">;
|
|
35
|
+
maxTokensPerImage: Schema<number, number, "defined">;
|
|
36
|
+
maxImagesPerRequest: Schema<number, number, "defined">;
|
|
37
|
+
imageCountTiersEnabled: Schema<boolean, boolean, "defined">;
|
|
38
|
+
legacyModes: Schema<string[], string[], "defined">;
|
|
39
|
+
}>>, Schemastery.ObjectT<NoInfer<{
|
|
40
|
+
superpixelPx: Schema<42, 42, "plain">;
|
|
41
|
+
rounding: Schema<"ceil", "ceil", "plain">;
|
|
42
|
+
maxTokensPerImage: Schema<number, number, "defined">;
|
|
43
|
+
maxImagesPerRequest: Schema<number, number, "defined">;
|
|
44
|
+
imageCountTiersEnabled: Schema<boolean, boolean, "defined">;
|
|
45
|
+
legacyModes: Schema<string[], string[], "defined">;
|
|
46
|
+
}>>, "plain">;
|
|
47
|
+
}>>, Schemastery.ObjectT<NoInfer<{
|
|
48
|
+
renderVisualId: Schema<boolean, boolean, "defined">;
|
|
49
|
+
maxPacketsPerCall: Schema<number, number, "defined">;
|
|
50
|
+
maxTokensBudgetPerCall: Schema<number, number, "defined">;
|
|
51
|
+
maxRequestBytes: Schema<number, number, "defined">;
|
|
52
|
+
maxColdRefs: Schema<number, number, "defined">;
|
|
53
|
+
telemetryEnabled: Schema<boolean, boolean, "defined">;
|
|
54
|
+
ffmpegPath: Schema<string, string, "plain">;
|
|
55
|
+
ffprobePath: Schema<string, string, "plain">;
|
|
56
|
+
tempDir: Schema<string, string, "plain">;
|
|
57
|
+
contentHashFallback: Schema<boolean, boolean, "defined">;
|
|
58
|
+
defaultStreamWindowMs: Schema<number, number, "defined">;
|
|
59
|
+
streamWorkMaxEdge: Schema<number, number, "defined">;
|
|
60
|
+
epochCompactionWindow: Schema<number, number, "defined">;
|
|
61
|
+
meteringProfile: Schema<Schemastery.ObjectS<NoInfer<{
|
|
62
|
+
superpixelPx: Schema<42, 42, "plain">;
|
|
63
|
+
rounding: Schema<"ceil", "ceil", "plain">;
|
|
64
|
+
maxTokensPerImage: Schema<number, number, "defined">;
|
|
65
|
+
maxImagesPerRequest: Schema<number, number, "defined">;
|
|
66
|
+
imageCountTiersEnabled: Schema<boolean, boolean, "defined">;
|
|
67
|
+
legacyModes: Schema<string[], string[], "defined">;
|
|
68
|
+
}>>, Schemastery.ObjectT<NoInfer<{
|
|
69
|
+
superpixelPx: Schema<42, 42, "plain">;
|
|
70
|
+
rounding: Schema<"ceil", "ceil", "plain">;
|
|
71
|
+
maxTokensPerImage: Schema<number, number, "defined">;
|
|
72
|
+
maxImagesPerRequest: Schema<number, number, "defined">;
|
|
73
|
+
imageCountTiersEnabled: Schema<boolean, boolean, "defined">;
|
|
74
|
+
legacyModes: Schema<string[], string[], "defined">;
|
|
75
|
+
}>>, "plain">;
|
|
76
|
+
}>>, "plain">;
|
|
77
|
+
/** 流式单次调用阻塞上限:宿主死线减 40s 余量(超时协作式,signal 绝不硬终止)。 */
|
|
78
|
+
export declare const TOOL_TIMEOUT_MS = 900000;
|
|
79
|
+
export declare const SELF_MANAGED_BLOCK_CEILING_MS: number;
|
|
80
|
+
/** 宿主 tools 服务;运行时由 inject=['tools'] 保证存在(类型未随 cordis 包发布)。 */
|
|
81
|
+
export interface ToolsService {
|
|
82
|
+
register(definition: unknown): () => void;
|
|
83
|
+
}
|
|
84
|
+
/** 结构化宿主上下文:cordis Context 加 tools 服务。 */
|
|
85
|
+
export type HostContext = Context & {
|
|
86
|
+
tools: ToolsService;
|
|
87
|
+
};
|
|
88
|
+
export declare function buildToolDefinition(_deps: {
|
|
89
|
+
ctx: HostContext;
|
|
90
|
+
config: PfStreamPluginConfig;
|
|
91
|
+
}): {
|
|
92
|
+
name: string;
|
|
93
|
+
description: string;
|
|
94
|
+
parameters: Record<string, import("./tool/schema.js").ValueSchema>;
|
|
95
|
+
output: {
|
|
96
|
+
schema: {
|
|
97
|
+
readonly type: "object";
|
|
98
|
+
};
|
|
99
|
+
render: (_args: unknown, value: unknown) => {
|
|
100
|
+
type: "text";
|
|
101
|
+
text: string;
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
timeoutMs: number;
|
|
105
|
+
isConcurrencySafe: () => boolean;
|
|
106
|
+
execute(args: ToolCallArgs, exec: ToolExec | undefined): Promise<ToolResult>;
|
|
107
|
+
};
|
|
108
|
+
export declare function apply(ctx: Context, config: PfStreamPluginConfig): void;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-pf-stream — DeepSeek Harness 视频感知插件入口。
|
|
3
|
+
*
|
|
4
|
+
* 统一 action 路由:动态流式采样(pf_stream)与内建确定性检视
|
|
5
|
+
* (probe / timestamps / uniform / RoI)共用主工具 dsh-pf-stream。
|
|
6
|
+
*
|
|
7
|
+
* 工具表稳定性(Prefix KV-Cache):tools.register 在 apply 期一次装齐、
|
|
8
|
+
* dispose 期统一注销,运行中不增删。
|
|
9
|
+
*/
|
|
10
|
+
import Schema from '@deepseek-ai/schemastery';
|
|
11
|
+
import { handleToolCall, } from './tool/handler.js';
|
|
12
|
+
import { TOOL_NAME, TOOL_DESCRIPTION, toolOutputSchema, toolParameters } from './tool/schema.js';
|
|
13
|
+
import { probeVideo } from './stage0/probe.js';
|
|
14
|
+
import { runDeterministicInspection } from './stage3/deterministicRouter.js';
|
|
15
|
+
import { runStreamCall } from './tool/streamCall.js';
|
|
16
|
+
import { resolveBinPaths } from './utils/ffmpegBin.js';
|
|
17
|
+
export const name = 'dsh-pf-stream';
|
|
18
|
+
export const inject = ['tools', 'subprocess'];
|
|
19
|
+
/** 56 MiB = 58,720,256 字节(含 8 MiB Base64 编码膨胀与协议结构预留)。 */
|
|
20
|
+
export const DEFAULT_MAX_REQUEST_BYTES = 56 * 1024 * 1024;
|
|
21
|
+
export const Config = Schema.object({
|
|
22
|
+
renderVisualId: Schema.boolean().default(true).description('渲染超像素微型反色角标'),
|
|
23
|
+
maxPacketsPerCall: Schema.number().default(64).description('单次调用画布包数上限'),
|
|
24
|
+
maxTokensBudgetPerCall: Schema.number().default(65536).description('单次调用视觉 Token 预算上限(intent.max_tokens_budget 受此钳制)'),
|
|
25
|
+
maxRequestBytes: Schema.number().default(DEFAULT_MAX_REQUEST_BYTES).description('请求字节软水位'),
|
|
26
|
+
maxColdRefs: Schema.number().default(4).description('冷区引用数量上限'),
|
|
27
|
+
telemetryEnabled: Schema.boolean().default(true).description('遥测开关'),
|
|
28
|
+
ffmpegPath: Schema.string().description('ffmpeg 可执行文件路径(缺省自动探测)'),
|
|
29
|
+
ffprobePath: Schema.string().description('ffprobe 可执行文件路径(缺省自动探测)'),
|
|
30
|
+
tempDir: Schema.string().description('临时目录(缺省系统临时目录)'),
|
|
31
|
+
contentHashFallback: Schema.boolean().default(false).description('内容哈希降级轨开关'),
|
|
32
|
+
defaultStreamWindowMs: Schema.number().default(10000).description('流式窗口缺省长度(毫秒)'),
|
|
33
|
+
streamWorkMaxEdge: Schema.number().default(2048).description('流式解码工作分辨率长边上限'),
|
|
34
|
+
epochCompactionWindow: Schema.number().default(6).description('热转冷批量收敛窗口(包数)'),
|
|
35
|
+
meteringProfile: Schema.object({
|
|
36
|
+
superpixelPx: Schema.const(42).description('超像素边长(像素)'),
|
|
37
|
+
rounding: Schema.const('ceil').description('计费序列长度取整方式'),
|
|
38
|
+
maxTokensPerImage: Schema.number().default(1024).description('单图视觉 Token 上限(v4.1 口径 1024;384 为 legacy 枚举位)'),
|
|
39
|
+
maxImagesPerRequest: Schema.number().default(600).description('单次请求图像张数上限(代际参数)'),
|
|
40
|
+
imageCountTiersEnabled: Schema.boolean().default(false).description('≥15 图单边 4096px 规则门控'),
|
|
41
|
+
legacyModes: Schema.array(String).default([]).description('legacy 计量口径枚举位'),
|
|
42
|
+
}),
|
|
43
|
+
});
|
|
44
|
+
/** 流式单次调用阻塞上限:宿主死线减 40s 余量(超时协作式,signal 绝不硬终止)。 */
|
|
45
|
+
export const TOOL_TIMEOUT_MS = 900_000;
|
|
46
|
+
export const SELF_MANAGED_BLOCK_CEILING_MS = TOOL_TIMEOUT_MS - 40_000;
|
|
47
|
+
export function buildToolDefinition(_deps) {
|
|
48
|
+
const { config } = _deps;
|
|
49
|
+
const bins = resolveBinPaths({ ffmpegPath: config.ffmpegPath, ffprobePath: config.ffprobePath });
|
|
50
|
+
const probe = (videoPath, signal) => probeVideo(videoPath, { ffprobePath: bins.ffprobe, signal });
|
|
51
|
+
const inspect = (videoPath, probeResult, intent, signal) => runDeterministicInspection(videoPath, probeResult, intent, {
|
|
52
|
+
ffmpegPath: bins.ffmpeg,
|
|
53
|
+
renderVisualId: config.renderVisualId,
|
|
54
|
+
packetIdStart: 1,
|
|
55
|
+
globalIdStart: 1,
|
|
56
|
+
appliedIntentId: 'intent_1',
|
|
57
|
+
maxRequestBytes: config.maxRequestBytes,
|
|
58
|
+
maxTokensPerImage: config.meteringProfile.maxTokensPerImage,
|
|
59
|
+
signal,
|
|
60
|
+
});
|
|
61
|
+
const stream = (videoPath, probeResult, intent, sessionId, signal) => runStreamCall(videoPath, probeResult, intent, sessionId ?? 'default', {
|
|
62
|
+
ffmpegPath: bins.ffmpeg,
|
|
63
|
+
renderVisualId: config.renderVisualId,
|
|
64
|
+
defaultStreamWindowMs: config.defaultStreamWindowMs,
|
|
65
|
+
streamWorkMaxEdge: config.streamWorkMaxEdge,
|
|
66
|
+
maxPacketsPerCall: config.maxPacketsPerCall,
|
|
67
|
+
maxTokensBudgetPerCall: config.maxTokensBudgetPerCall,
|
|
68
|
+
maxRequestBytes: config.maxRequestBytes,
|
|
69
|
+
maxColdRefs: config.maxColdRefs,
|
|
70
|
+
epochCompactionWindow: config.epochCompactionWindow,
|
|
71
|
+
imageCountTiersEnabled: config.meteringProfile.imageCountTiersEnabled,
|
|
72
|
+
maxTokensPerImage: config.meteringProfile.maxTokensPerImage,
|
|
73
|
+
signal,
|
|
74
|
+
});
|
|
75
|
+
return {
|
|
76
|
+
name: TOOL_NAME,
|
|
77
|
+
description: TOOL_DESCRIPTION,
|
|
78
|
+
parameters: toolParameters,
|
|
79
|
+
output: {
|
|
80
|
+
schema: toolOutputSchema,
|
|
81
|
+
render: (_args, value) => ({
|
|
82
|
+
type: 'text',
|
|
83
|
+
text: JSON.stringify(value, null, 2),
|
|
84
|
+
}),
|
|
85
|
+
},
|
|
86
|
+
timeoutMs: TOOL_TIMEOUT_MS,
|
|
87
|
+
// 同一 (sessionId, videoKey) 的调用经 per-key promise 队列串行化,
|
|
88
|
+
// 会话级状态使并发不安全。
|
|
89
|
+
isConcurrencySafe: () => false,
|
|
90
|
+
async execute(args, exec) {
|
|
91
|
+
return handleToolCall(args, exec, { probe, inspect, stream });
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
export function apply(ctx, config) {
|
|
96
|
+
const host = ctx;
|
|
97
|
+
const dispose = host.tools.register(buildToolDefinition({ ctx: host, config }));
|
|
98
|
+
// register 返回的 disposer 为主注销路径;'dispose' 事件为兜底
|
|
99
|
+
// (经 events 服务注册,事件名不受 keyof Events 约束)。
|
|
100
|
+
ctx.events.on('dispose', () => {
|
|
101
|
+
try {
|
|
102
|
+
dispose();
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// 卸载期清理失败不再抛出
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 会话状态(SessionState / StreamCursor / LRU 管理)。
|
|
3
|
+
*
|
|
4
|
+
* LRU 上限(2 个视频/会话):每视频驻留状态约 1MB 量级
|
|
5
|
+
* (单槽位擂台图 ~450KB + 待发 P 队列),会话内存占用有界。
|
|
6
|
+
* M2 为进程内内存态;持久层(storageDomain)在 M4 接入(ADR-005)。
|
|
7
|
+
*/
|
|
8
|
+
import type { SessionIntent, SessionState, SessionVideoState, VideoFingerprint } from '../types.js';
|
|
9
|
+
/** 视频指纹:规范化路径 + size + mtime 联合哈希前 16 hex。 */
|
|
10
|
+
export declare function fingerprintOf(videoPath: string): VideoFingerprint;
|
|
11
|
+
export declare function defaultSessionIntent(): SessionIntent;
|
|
12
|
+
export declare function createSessionState(sessionId: string): SessionState;
|
|
13
|
+
/** LRU 上限(会话内视频数)。 */
|
|
14
|
+
export declare const VIDEO_LRU_LIMIT = 2;
|
|
15
|
+
/** 取视频槽位(不存在则创建);超过上限淘汰最旧未使用槽位。 */
|
|
16
|
+
export declare function getVideoSlot(state: SessionState, fingerprint: VideoFingerprint): SessionVideoState;
|
|
17
|
+
export declare function getSessionState(sessionId: string): SessionState;
|
|
18
|
+
/** 测试辅助:清空进程内会话存储。 */
|
|
19
|
+
export declare function resetMemorySessions(): void;
|
|
20
|
+
/** 测试辅助:将重建的会话状态放回进程内存储(importSessionSnapshot 配套)。 */
|
|
21
|
+
export declare function setMemorySession(state: SessionState): void;
|
|
22
|
+
/** 导出会话快照(JSON 文本;Buffer 字段 base64 编码)。 */
|
|
23
|
+
export declare function exportSessionSnapshot(state: SessionState): string;
|
|
24
|
+
/** 从快照重建会话状态(exportSessionSnapshot 的逆操作)。 */
|
|
25
|
+
export declare function importSessionSnapshot(json: string): SessionState;
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 会话状态(SessionState / StreamCursor / LRU 管理)。
|
|
3
|
+
*
|
|
4
|
+
* LRU 上限(2 个视频/会话):每视频驻留状态约 1MB 量级
|
|
5
|
+
* (单槽位擂台图 ~450KB + 待发 P 队列),会话内存占用有界。
|
|
6
|
+
* M2 为进程内内存态;持久层(storageDomain)在 M4 接入(ADR-005)。
|
|
7
|
+
*/
|
|
8
|
+
import { createHash } from 'node:crypto';
|
|
9
|
+
import { statSync } from 'node:fs';
|
|
10
|
+
import { resolve } from 'node:path';
|
|
11
|
+
/** 视频指纹:规范化路径 + size + mtime 联合哈希前 16 hex。 */
|
|
12
|
+
export function fingerprintOf(videoPath) {
|
|
13
|
+
const normalizedPath = resolve(videoPath).replaceAll('\\', '/').toLowerCase();
|
|
14
|
+
const st = statSync(normalizedPath);
|
|
15
|
+
const digest = createHash('sha256')
|
|
16
|
+
.update(`${normalizedPath}|${st.size}|${Math.round(st.mtimeMs)}`)
|
|
17
|
+
.digest('hex');
|
|
18
|
+
return {
|
|
19
|
+
normalizedPath,
|
|
20
|
+
sizeBytes: st.size,
|
|
21
|
+
mtimeMs: Math.round(st.mtimeMs),
|
|
22
|
+
sha256Short: digest.slice(0, 16),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export function defaultSessionIntent() {
|
|
26
|
+
return { intentId: 'intent_0', mode: 'standard', focus: 'balanced', fullFrame: false };
|
|
27
|
+
}
|
|
28
|
+
export function createSessionState(sessionId) {
|
|
29
|
+
return {
|
|
30
|
+
sessionId,
|
|
31
|
+
intent: defaultSessionIntent(),
|
|
32
|
+
videos: new Map(),
|
|
33
|
+
fUnitCache: new Map(),
|
|
34
|
+
globalUnitSeq: 0,
|
|
35
|
+
packetSeq: 0,
|
|
36
|
+
intentSeq: 0,
|
|
37
|
+
ctrlSeq: new Map(),
|
|
38
|
+
heartbeatSeq: 0,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/** LRU 上限(会话内视频数)。 */
|
|
42
|
+
export const VIDEO_LRU_LIMIT = 2;
|
|
43
|
+
/** 取视频槽位(不存在则创建);超过上限淘汰最旧未使用槽位。 */
|
|
44
|
+
export function getVideoSlot(state, fingerprint) {
|
|
45
|
+
const key = fingerprint.sha256Short;
|
|
46
|
+
const existing = state.videos.get(key);
|
|
47
|
+
if (existing) {
|
|
48
|
+
// LRU 触达:移到 Map 尾部(最新)
|
|
49
|
+
state.videos.delete(key);
|
|
50
|
+
state.videos.set(key, existing);
|
|
51
|
+
return existing;
|
|
52
|
+
}
|
|
53
|
+
while (state.videos.size >= VIDEO_LRU_LIMIT) {
|
|
54
|
+
const oldest = state.videos.keys().next().value;
|
|
55
|
+
if (oldest == null)
|
|
56
|
+
break;
|
|
57
|
+
state.videos.delete(oldest);
|
|
58
|
+
}
|
|
59
|
+
const slot = {
|
|
60
|
+
cursor: {
|
|
61
|
+
fingerprint,
|
|
62
|
+
lastConsumedPtsMs: 0,
|
|
63
|
+
lastEmittedPacketPtsMs: null,
|
|
64
|
+
snapshot: {
|
|
65
|
+
state: 'STATIC',
|
|
66
|
+
enteredAtPtsMs: 0,
|
|
67
|
+
integratorA: 0,
|
|
68
|
+
gEma: 0,
|
|
69
|
+
emaWarmupLeft: 0,
|
|
70
|
+
settleStartPtsMs: null,
|
|
71
|
+
lastKCandidates: null,
|
|
72
|
+
lastMotionVec: null,
|
|
73
|
+
arena: null,
|
|
74
|
+
},
|
|
75
|
+
pendingPUnits: [],
|
|
76
|
+
lastAnchorF: null,
|
|
77
|
+
},
|
|
78
|
+
history: { packets: [] },
|
|
79
|
+
epoch: { pendingNew: 0, coldRefs: [] },
|
|
80
|
+
};
|
|
81
|
+
state.videos.set(key, slot);
|
|
82
|
+
return slot;
|
|
83
|
+
}
|
|
84
|
+
/** M2 进程内会话存储(key = sessionId);M4 换 storageDomain 持久层。 */
|
|
85
|
+
const memorySessions = new Map();
|
|
86
|
+
export function getSessionState(sessionId) {
|
|
87
|
+
let state = memorySessions.get(sessionId);
|
|
88
|
+
if (!state) {
|
|
89
|
+
state = createSessionState(sessionId);
|
|
90
|
+
memorySessions.set(sessionId, state);
|
|
91
|
+
}
|
|
92
|
+
return state;
|
|
93
|
+
}
|
|
94
|
+
/** 测试辅助:清空进程内会话存储。 */
|
|
95
|
+
export function resetMemorySessions() {
|
|
96
|
+
memorySessions.clear();
|
|
97
|
+
}
|
|
98
|
+
/** 测试辅助:将重建的会话状态放回进程内存储(importSessionSnapshot 配套)。 */
|
|
99
|
+
export function setMemorySession(state) {
|
|
100
|
+
memorySessions.set(state.sessionId, state);
|
|
101
|
+
}
|
|
102
|
+
/** 导出会话快照(JSON 文本;Buffer 字段 base64 编码)。 */
|
|
103
|
+
export function exportSessionSnapshot(state) {
|
|
104
|
+
const videos = [];
|
|
105
|
+
for (const [key, slot] of state.videos) {
|
|
106
|
+
const c = slot.cursor;
|
|
107
|
+
videos.push([
|
|
108
|
+
key,
|
|
109
|
+
{
|
|
110
|
+
fingerprint: c.fingerprint,
|
|
111
|
+
lastConsumedPtsMs: c.lastConsumedPtsMs,
|
|
112
|
+
lastEmittedPacketPtsMs: c.lastEmittedPacketPtsMs,
|
|
113
|
+
snapshot: {
|
|
114
|
+
...c.snapshot,
|
|
115
|
+
arena: c.snapshot.arena == null
|
|
116
|
+
? null
|
|
117
|
+
: {
|
|
118
|
+
ptsMs: c.snapshot.arena.ptsMs,
|
|
119
|
+
rho: c.snapshot.arena.rho,
|
|
120
|
+
g: c.snapshot.arena.g,
|
|
121
|
+
image672: c.snapshot.arena.image672.toString('base64'),
|
|
122
|
+
sourceCropBbox: c.snapshot.arena.sourceCropBbox,
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
pendingPUnits: c.pendingPUnits.map((p) => ({
|
|
126
|
+
ptsMs: p.ptsMs,
|
|
127
|
+
image336: p.image336.toString('base64'),
|
|
128
|
+
sourceCropBbox: p.sourceCropBbox,
|
|
129
|
+
})),
|
|
130
|
+
lastAnchorF: c.lastAnchorF,
|
|
131
|
+
history: {
|
|
132
|
+
packets: slot.history.packets.map((h) => ({
|
|
133
|
+
packet: h.packet,
|
|
134
|
+
imageBytes: h.imageBytes.toString('base64'),
|
|
135
|
+
anchorBytes: h.anchorBytes ? h.anchorBytes.toString('base64') : null,
|
|
136
|
+
anchorFContentHash: h.anchorFContentHash,
|
|
137
|
+
})),
|
|
138
|
+
},
|
|
139
|
+
epoch: {
|
|
140
|
+
pendingNew: slot.epoch.pendingNew,
|
|
141
|
+
coldRefs: slot.epoch.coldRefs.map((r) => ({
|
|
142
|
+
refPacketId: r.refPacketId,
|
|
143
|
+
sourcePacketId: r.sourcePacketId,
|
|
144
|
+
anchorFId: r.anchorFId,
|
|
145
|
+
anchorFSha256: r.anchorFSha256,
|
|
146
|
+
ptsMs: r.ptsMs,
|
|
147
|
+
eventType: r.eventType,
|
|
148
|
+
sourceCropBbox: r.sourceCropBbox,
|
|
149
|
+
bytes: r.bytes.toString('base64'),
|
|
150
|
+
contentHash: r.contentHash,
|
|
151
|
+
})),
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
]);
|
|
155
|
+
}
|
|
156
|
+
const doc = {
|
|
157
|
+
version: 1,
|
|
158
|
+
sessionId: state.sessionId,
|
|
159
|
+
intent: state.intent,
|
|
160
|
+
globalUnitSeq: state.globalUnitSeq,
|
|
161
|
+
packetSeq: state.packetSeq,
|
|
162
|
+
intentSeq: state.intentSeq,
|
|
163
|
+
heartbeatSeq: state.heartbeatSeq,
|
|
164
|
+
ctrlSeq: [...state.ctrlSeq.entries()],
|
|
165
|
+
fUnitCache: [...state.fUnitCache.values()].map((e) => ({
|
|
166
|
+
anchorFId: e.anchorFId,
|
|
167
|
+
packetId: e.packetId,
|
|
168
|
+
ptsMs: e.ptsMs,
|
|
169
|
+
independentBytes: e.independentBytes.toString('base64'),
|
|
170
|
+
anchorFSha256: e.anchorFSha256,
|
|
171
|
+
stripBytes: e.stripBytes?.toString('base64'),
|
|
172
|
+
stripSha256: e.stripSha256,
|
|
173
|
+
contentHash: e.contentHash,
|
|
174
|
+
})),
|
|
175
|
+
videos,
|
|
176
|
+
};
|
|
177
|
+
return JSON.stringify(doc);
|
|
178
|
+
}
|
|
179
|
+
/** 从快照重建会话状态(exportSessionSnapshot 的逆操作)。 */
|
|
180
|
+
export function importSessionSnapshot(json) {
|
|
181
|
+
const doc = JSON.parse(json);
|
|
182
|
+
if (doc.version !== 1)
|
|
183
|
+
throw new Error(`不支持的会话快照版本:${doc.version}`);
|
|
184
|
+
const state = createSessionState(doc.sessionId);
|
|
185
|
+
state.intent = doc.intent;
|
|
186
|
+
state.globalUnitSeq = doc.globalUnitSeq;
|
|
187
|
+
state.packetSeq = doc.packetSeq;
|
|
188
|
+
state.intentSeq = doc.intentSeq;
|
|
189
|
+
state.heartbeatSeq = doc.heartbeatSeq;
|
|
190
|
+
state.ctrlSeq = new Map(doc.ctrlSeq);
|
|
191
|
+
state.fUnitCache = new Map(doc.fUnitCache.map((e) => [
|
|
192
|
+
e.anchorFId,
|
|
193
|
+
{
|
|
194
|
+
anchorFId: e.anchorFId,
|
|
195
|
+
packetId: e.packetId,
|
|
196
|
+
ptsMs: e.ptsMs,
|
|
197
|
+
independentBytes: Buffer.from(e.independentBytes, 'base64'),
|
|
198
|
+
anchorFSha256: e.anchorFSha256,
|
|
199
|
+
stripBytes: e.stripBytes != null ? Buffer.from(e.stripBytes, 'base64') : undefined,
|
|
200
|
+
stripSha256: e.stripSha256,
|
|
201
|
+
contentHash: e.contentHash,
|
|
202
|
+
},
|
|
203
|
+
]));
|
|
204
|
+
for (const [key, v] of doc.videos) {
|
|
205
|
+
state.videos.set(key, {
|
|
206
|
+
cursor: {
|
|
207
|
+
fingerprint: v.fingerprint,
|
|
208
|
+
lastConsumedPtsMs: v.lastConsumedPtsMs,
|
|
209
|
+
lastEmittedPacketPtsMs: v.lastEmittedPacketPtsMs,
|
|
210
|
+
snapshot: {
|
|
211
|
+
...v.snapshot,
|
|
212
|
+
arena: v.snapshot.arena == null
|
|
213
|
+
? null
|
|
214
|
+
: {
|
|
215
|
+
ptsMs: v.snapshot.arena.ptsMs,
|
|
216
|
+
rho: v.snapshot.arena.rho,
|
|
217
|
+
g: v.snapshot.arena.g,
|
|
218
|
+
image672: Buffer.from(v.snapshot.arena.image672, 'base64'),
|
|
219
|
+
sourceCropBbox: v.snapshot.arena.sourceCropBbox,
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
pendingPUnits: v.pendingPUnits.map((p) => ({
|
|
223
|
+
ptsMs: p.ptsMs,
|
|
224
|
+
image336: Buffer.from(p.image336, 'base64'),
|
|
225
|
+
sourceCropBbox: p.sourceCropBbox,
|
|
226
|
+
})),
|
|
227
|
+
lastAnchorF: v.lastAnchorF,
|
|
228
|
+
},
|
|
229
|
+
history: {
|
|
230
|
+
packets: v.history.packets.map((h) => ({
|
|
231
|
+
packet: h.packet,
|
|
232
|
+
imageBytes: Buffer.from(h.imageBytes, 'base64'),
|
|
233
|
+
anchorBytes: h.anchorBytes != null ? Buffer.from(h.anchorBytes, 'base64') : null,
|
|
234
|
+
anchorFContentHash: h.anchorFContentHash,
|
|
235
|
+
})),
|
|
236
|
+
},
|
|
237
|
+
epoch: {
|
|
238
|
+
pendingNew: v.epoch.pendingNew,
|
|
239
|
+
coldRefs: v.epoch.coldRefs.map((r) => ({
|
|
240
|
+
refPacketId: r.refPacketId,
|
|
241
|
+
sourcePacketId: r.sourcePacketId,
|
|
242
|
+
anchorFId: r.anchorFId,
|
|
243
|
+
anchorFSha256: r.anchorFSha256,
|
|
244
|
+
ptsMs: r.ptsMs,
|
|
245
|
+
eventType: r.eventType,
|
|
246
|
+
sourceCropBbox: r.sourceCropBbox,
|
|
247
|
+
bytes: Buffer.from(r.bytes, 'base64'),
|
|
248
|
+
contentHash: r.contentHash,
|
|
249
|
+
})),
|
|
250
|
+
},
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
return state;
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/session/state.ts"],"names":[],"mappings":"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"}
|