@mengine/medeo-tool 1.0.1-alpha.0 → 1.0.1-alpha.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/dist/index.d.mts +13 -4
- package/dist/index.mjs +24 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { JournalEntry, MengineDocSession, PartIdFactory, SemanticOpName, VideoDocument, fromVideoDocument } from "@mengine/medeo-client";
|
|
1
|
+
import { JournalEntry, MengineDocSession, PartIdFactory, SemanticOpName, VideoDocument, VideoDraft, fromVideoDocument } from "@mengine/medeo-client";
|
|
2
2
|
import { AddSpeechesInput, AddVideoClipsInput, AdjustBgmVolumeInput, AdjustSpeechVolumeInput, AdjustVideoClipDurationInput, AdjustVideoClipVolumeInput, ChangeSpeechScriptInput, ChangeSpeechVoiceInput, DeleteBgmInput, DeleteSpeechesInput, DeleteVideoClipsInput, MoveSpeechesInput, MoveVideoClipsInput, ReplaceVideoClipContentInput, SetBgmInput, SetCaptionStyleInput, SetCaptionVisibilityInput, SetVideoClipSpeedShiftInput } from "@mengine/medeo-client/schemas";
|
|
3
3
|
|
|
4
4
|
//#region src/document/compact-projection.d.ts
|
|
@@ -365,6 +365,13 @@ interface CreateMedeoToolOptions {
|
|
|
365
365
|
userId?: ContextualValue<string>;
|
|
366
366
|
/** Stable agent peer id. Supply a host-scoped value so audit provenance is durable. */
|
|
367
367
|
peerId?: ContextualValue<string>;
|
|
368
|
+
/**
|
|
369
|
+
* Load the authoritative legacy draft used to create a missing Mengine
|
|
370
|
+
* document. The tool owns the get-or-create flow: it first probes Mengine,
|
|
371
|
+
* converts this draft into a VideoDocument only on a 404, bootstraps the
|
|
372
|
+
* snapshot, and tolerates a concurrent creator winning the race.
|
|
373
|
+
*/
|
|
374
|
+
loadInitialDraft?: (docId: string) => Promise<VideoDraft>;
|
|
368
375
|
fetchImpl?: typeof fetch;
|
|
369
376
|
sseReconnectDelayMs?: number;
|
|
370
377
|
/** Defaults passed to runEditScript; each call may override them. */
|
|
@@ -444,14 +451,16 @@ interface MedeoTool {
|
|
|
444
451
|
handle(input: unknown): Promise<MedeoToolResult>;
|
|
445
452
|
close(): Promise<void>;
|
|
446
453
|
}
|
|
454
|
+
type MedeoInitialDraft = VideoDraft;
|
|
447
455
|
/**
|
|
448
456
|
* Create the self-contained Medeo LLM tool.
|
|
449
457
|
*
|
|
450
458
|
* The package owns session construction, compact projection, sandbox execution,
|
|
451
|
-
* plan caching, commit, and shutdown. The host supplies
|
|
452
|
-
*
|
|
459
|
+
* plan caching, commit, document get-or-create, and shutdown. The host supplies
|
|
460
|
+
* environment facts plus the authoritative legacy draft loader used only when
|
|
461
|
+
* Mengine has no document yet.
|
|
453
462
|
*/
|
|
454
463
|
declare function createMedeoTool(options: CreateMedeoToolOptions): MedeoTool;
|
|
455
464
|
//#endregion
|
|
456
|
-
export { type ChangePlan, type CommitPlan, type CommitPlanOptions, type CommitPlanResult, type CompactProjectionOptions, type ConsoleShim, type CreateMedeoToolOptions, type EditFacade, EditSandboxSession, type EditSandboxSessionOptions, type EditScriptResult, MEDEO_TOOL_DESCRIPTION, MEDEO_TOOL_NAME, MEDEO_TOOL_PARAMETERS, type MedeoTool, type MedeoToolInput, type MedeoToolOp, type MedeoToolResult, type RunEditScriptOptions, type SandboxCheckpoint, type TimelineClipDescriptor, type TimelineFacade, type TimelinePartDescriptor, collectAffectedPartIds, commitPlan, createMedeoTool, renderCompactProjection, renderPreview, runEditScript };
|
|
465
|
+
export { type ChangePlan, type CommitPlan, type CommitPlanOptions, type CommitPlanResult, type CompactProjectionOptions, type ConsoleShim, type CreateMedeoToolOptions, type EditFacade, EditSandboxSession, type EditSandboxSessionOptions, type EditScriptResult, MEDEO_TOOL_DESCRIPTION, MEDEO_TOOL_NAME, MEDEO_TOOL_PARAMETERS, type MedeoInitialDraft, type MedeoTool, type MedeoToolInput, type MedeoToolOp, type MedeoToolResult, type RunEditScriptOptions, type SandboxCheckpoint, type TimelineClipDescriptor, type TimelineFacade, type TimelinePartDescriptor, collectAffectedPartIds, commitPlan, createMedeoTool, renderCompactProjection, renderPreview, runEditScript };
|
|
457
466
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as renderCompactProjection, n as collectAffectedPartIds, r as renderPreview, t as EditSandboxSession } from "./script-session-B8fc9Ccb.mjs";
|
|
2
|
-
import { MengineDocSession, MengineHttpClient, ValidationError, createPlainMemoryAdapter, replayJournal } from "@mengine/medeo-client";
|
|
2
|
+
import { MengineDocSession, MengineHttpClient, MengineHttpRequestError, ValidationError, createMirrorVideoDocument, createPlainMemoryAdapter, replayJournal, toVideoDocument } from "@mengine/medeo-client";
|
|
3
3
|
import { Worker } from "node:worker_threads";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
//#region src/sandbox/node-host.ts
|
|
@@ -403,8 +403,9 @@ function parseInput(value) {
|
|
|
403
403
|
* Create the self-contained Medeo LLM tool.
|
|
404
404
|
*
|
|
405
405
|
* The package owns session construction, compact projection, sandbox execution,
|
|
406
|
-
* plan caching, commit, and shutdown. The host supplies
|
|
407
|
-
*
|
|
406
|
+
* plan caching, commit, document get-or-create, and shutdown. The host supplies
|
|
407
|
+
* environment facts plus the authoritative legacy draft loader used only when
|
|
408
|
+
* Mengine has no document yet.
|
|
408
409
|
*/
|
|
409
410
|
function createMedeoTool(options) {
|
|
410
411
|
const sessions = /* @__PURE__ */ new Map();
|
|
@@ -424,6 +425,7 @@ function createMedeoTool(options) {
|
|
|
424
425
|
...options.fetchImpl !== void 0 ? { fetchImpl: options.fetchImpl } : {}
|
|
425
426
|
});
|
|
426
427
|
const peerId = optionalContext(options.peerId, docId);
|
|
428
|
+
await getOrCreateDocument(client, docId, peerId);
|
|
427
429
|
const session = new MengineDocSession({
|
|
428
430
|
docId,
|
|
429
431
|
client,
|
|
@@ -446,6 +448,25 @@ function createMedeoTool(options) {
|
|
|
446
448
|
throw error;
|
|
447
449
|
}
|
|
448
450
|
}
|
|
451
|
+
async function getOrCreateDocument(client, docId, peerId) {
|
|
452
|
+
try {
|
|
453
|
+
await client.fetchSnapshot();
|
|
454
|
+
return;
|
|
455
|
+
} catch (error) {
|
|
456
|
+
if (!(error instanceof MengineHttpRequestError) || error.status !== 404) throw error;
|
|
457
|
+
if (options.loadInitialDraft === void 0) throw error;
|
|
458
|
+
}
|
|
459
|
+
const seed = createMirrorVideoDocument(toVideoDocument(await options.loadInitialDraft(docId)), {
|
|
460
|
+
...peerId !== void 0 ? { peerId } : {},
|
|
461
|
+
origin: "mengine.medeo_tool.bootstrap"
|
|
462
|
+
});
|
|
463
|
+
try {
|
|
464
|
+
await client.bootstrapSnapshot(seed.export({ mode: "snapshot" }));
|
|
465
|
+
} catch (error) {
|
|
466
|
+
if (!(error instanceof MengineHttpRequestError) || error.status !== 400) throw error;
|
|
467
|
+
await client.fetchSnapshot();
|
|
468
|
+
}
|
|
469
|
+
}
|
|
449
470
|
function rememberPlan(docId, plan) {
|
|
450
471
|
const planId = randomUUID();
|
|
451
472
|
plans.set(planId, {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/sandbox/node-host.ts","../src/prompt.ts","../src/schema.ts","../src/session/commit-plan.ts","../src/host-tool.ts"],"sourcesContent":["/// <reference types=\"node\" />\n\nimport { Worker } from 'node:worker_threads';\n\nimport type { JournalEntry, VideoDocument } from '@mengine/medeo-client';\n\nimport type { ChangePlan } from './script-session.ts';\n\n/**\n * Host API for running an agent edit script in an isolated Node worker.\n *\n * Requires Node.js >= 24.15 (engines) so the worker can load TypeScript via\n * `--experimental-transform-types`. Do not inherit `process.execArgv` — vitest\n * injects loaders that break worker boot.\n */\n\nexport interface RunEditScriptOptions {\n document: VideoDocument;\n baseVersion: string;\n script: string;\n inputs?: Record<string, unknown>;\n /** Deterministic id mint label for tests; omit to use the default ULID factory. */\n idLabel?: string;\n /** Hard wall-clock timeout; default 2000 ms. */\n timeoutMs?: number;\n /** V8 old-generation ceiling for the worker; default 256 MB. */\n memoryLimitMb?: number;\n /** Override worker module URL (defaults to sibling `worker-entry.ts`). */\n workerEntryUrl?: URL;\n}\n\nexport type EditScriptResult =\n | {\n ok: true;\n plan: ChangePlan;\n /** Script execution time after worker readiness; excludes cold start. */\n durationMs: number;\n }\n | {\n ok: false;\n phase: 'parse' | 'runtime' | 'timeout' | 'memory';\n error: { message: string; line?: number; column?: number; stack?: string };\n partial: { ops: readonly JournalEntry[]; logs: string[] };\n };\n\ntype WorkerMessage =\n | { t: 'ready' }\n | { t: 'entry'; entry: JournalEntry }\n | { t: 'log'; line: string }\n | { t: 'truncate'; index: number }\n | { t: 'done'; preview: string; opsCount: number }\n | {\n t: 'fail';\n phase: 'parse' | 'runtime';\n error: { message: string; line?: number; column?: number; stack?: string };\n };\n\nconst DEFAULT_TIMEOUT_MS = 2000;\nconst DEFAULT_MEMORY_MB = 256;\n\n/**\n * Source runs load the checked-in TypeScript worker; packed runs load the\n * sibling JavaScript chunk emitted as a second package entry. Keeping this\n * branch explicit avoids shipping a `dist/*.ts` URL in the npm artifact.\n */\nfunction sourceSibling(fileName: string): URL {\n const selfUrl = new URL(import.meta.url);\n const extension = selfUrl.pathname.endsWith('.ts') ? 'ts' : 'mjs';\n return new URL(`./${fileName}.${extension}`, selfUrl);\n}\n\n/** Run `script` against a forked document snapshot; always resolves (never rejects). */\nexport function runEditScript(options: RunEditScriptOptions): Promise<EditScriptResult> {\n // Set when the worker has loaded its bundle and is about to invoke the script.\n // Keep this clock separate from worker boot so success timing matches the\n // timeout boundary and excludes cold-start/module-loading cost.\n let scriptStartedAt = performance.now();\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const memoryLimitMb = options.memoryLimitMb ?? DEFAULT_MEMORY_MB;\n const workerEntryUrl = options.workerEntryUrl ?? sourceSibling('worker-entry');\n const resolveRegisterUrl = sourceSibling('node-esm-resolve-register');\n\n const ops: JournalEntry[] = [];\n const logs: string[] = [];\n\n return new Promise<EditScriptResult>((resolve) => {\n let settled = false;\n let timedOut = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const worker = new Worker(workerEntryUrl, {\n workerData: {\n document: options.document,\n script: options.script,\n inputs: options.inputs,\n idLabel: options.idLabel,\n },\n // Explicit argv only — never inherit process.execArgv (vitest loaders).\n // Source workers need TypeScript transform plus the resolver hook for\n // workspace packages that still use extensionless directory imports.\n // Packed JavaScript workers already contain those dependencies.\n execArgv: resolveRegisterUrl.pathname.endsWith('.ts')\n ? [\n '--experimental-transform-types',\n '--disable-warning=ExperimentalWarning',\n `--import=${resolveRegisterUrl.href}`,\n ]\n : [],\n resourceLimits: { maxOldGenerationSizeMb: memoryLimitMb },\n });\n\n /** Start wall-clock timeout only after worker signals script is about to run. */\n const armTimeout = (): void => {\n if (settled || timer != null) return;\n timer = setTimeout(() => {\n timedOut = true;\n void worker.terminate();\n finish({\n ok: false,\n phase: 'timeout',\n error: { message: `edit script exceeded timeout of ${timeoutMs}ms` },\n partial: { ops: ops.slice(), logs: logs.slice() },\n });\n }, timeoutMs);\n };\n\n const finish = (result: EditScriptResult): void => {\n if (settled) return;\n settled = true;\n if (timer != null) clearTimeout(timer);\n void worker.terminate();\n if (result.ok) {\n resolve({ ...result, durationMs: performance.now() - scriptStartedAt });\n } else {\n resolve(result);\n }\n };\n\n worker.on('message', (message: WorkerMessage) => {\n if (settled) return;\n if (message.t === 'ready') {\n scriptStartedAt = performance.now();\n armTimeout();\n return;\n }\n if (message.t === 'entry') {\n ops.push(message.entry);\n return;\n }\n if (message.t === 'log') {\n logs.push(message.line);\n return;\n }\n if (message.t === 'truncate') {\n ops.length = Math.max(0, Math.min(message.index, ops.length));\n return;\n }\n if (message.t === 'done') {\n if (message.opsCount !== ops.length) {\n finish({\n ok: false,\n phase: 'runtime',\n error: {\n message: `opsCount mismatch: worker reported ${message.opsCount}, host collected ${ops.length}`,\n },\n partial: { ops: ops.slice(), logs: logs.slice() },\n });\n return;\n }\n finish({\n ok: true,\n plan: {\n doc_id: options.document.meta.draft_id ?? '',\n base_version: options.baseVersion,\n ops: ops.slice(),\n preview: message.preview,\n logs: logs.slice(),\n },\n durationMs: 0,\n });\n return;\n }\n if (message.t === 'fail') {\n finish({\n ok: false,\n phase: message.phase,\n error: message.error,\n partial: { ops: ops.slice(), logs: logs.slice() },\n });\n }\n });\n\n worker.on('error', (error: Error) => {\n if (settled) return;\n const text = error.message ?? String(error);\n const phase = /memory limit/i.test(text) ? 'memory' : 'runtime';\n finish({\n ok: false,\n phase,\n error: { message: text, stack: error.stack },\n partial: { ops: ops.slice(), logs: logs.slice() },\n });\n });\n\n worker.on('exit', (code: number) => {\n if (settled) return;\n if (timedOut) return;\n finish({\n ok: false,\n phase: 'runtime',\n error: { message: `worker exited with code ${code ?? 'null'} before completion` },\n partial: { ops: ops.slice(), logs: logs.slice() },\n });\n });\n });\n}\n","export const MEDEO_TOOL_DESCRIPTION = `\nEdit a Medeo video document through a deterministic, side-effect-free JavaScript sandbox.\n\nOperations:\n- snapshot: return the compact timeline projection and opaque base version.\n- run-edit-script: execute JavaScript against a forked snapshot. Inspect timeline.*, compute coordinates, and call edit.* methods in one script. The sandbox has no network, storage, clock, or generation access. Pass materialized asset/speech facts through inputs. A successful run returns preview, logs, base_version, and plan_id — not the full op journal.\n- commit-plan: replay a cached plan_id into the live MengineDocSession through SemanticEditor. Use validation=version for all-or-nothing commit, or preflight to localize an op conflict after concurrent edits.\n\nDefault flow: snapshot → run-edit-script with auto_commit=false → inspect preview → commit-plan. Use auto_commit=true only for low-risk edits when the host does not need user confirmation. On version mismatch, rerun snapshot and the script; never try to patch a rejected journal by hand.\n`.trim();\n","export const MEDEO_TOOL_NAME = 'medeo';\n\nexport type MedeoToolOp = 'snapshot' | 'run-edit-script' | 'commit-plan';\n\n/**\n * JSON Schema for the host-facing three-op `medeo` tool surface.\n *\n * The schema intentionally does not return or accept the full op journal:\n * journals stay in the tool process and are referenced by `plan_id`. This keeps\n * large intermediate products out of model context while preserving the exact\n * journal used for commit.\n */\nexport const MEDEO_TOOL_PARAMETERS = {\n type: 'object',\n required: ['op', 'doc_id'],\n additionalProperties: false,\n properties: {\n op: {\n type: 'string',\n enum: ['snapshot', 'run-edit-script', 'commit-plan'],\n description: 'Which Medeo document operation to run.',\n },\n doc_id: {\n type: 'string',\n minLength: 1,\n description: 'Medeo document id. Copy it from the host context; never invent it.',\n },\n script: {\n type: 'string',\n minLength: 1,\n description:\n 'JavaScript body for run-edit-script. It receives edit, timeline, checkpoint, rollbackTo, inputs, and console; perform all calculations in the script.',\n },\n inputs: {\n type: 'object',\n description:\n 'Pre-materialized, side-effect-free values passed into the script. Generation and network IO must happen in the host before this call.',\n },\n timeout_ms: {\n type: 'integer',\n minimum: 1,\n description: 'Maximum script wall-clock time after worker startup (default 2000).',\n },\n memory_limit_mb: {\n type: 'integer',\n minimum: 16,\n description: 'Worker old-generation memory ceiling in MB (default 256).',\n },\n auto_commit: {\n type: 'boolean',\n description:\n 'Commit the returned plan immediately after the sandbox succeeds. Default false: return preview plus plan_id for explicit commit.',\n },\n plan_id: {\n type: 'string',\n minLength: 1,\n description: 'Plan id returned by run-edit-script; required by commit-plan.',\n },\n validation: {\n type: 'string',\n enum: ['version', 'preflight'],\n description:\n 'commit-plan mode: version rejects any concurrent change; preflight revalidates each op against the current snapshot.',\n },\n },\n oneOf: [\n {\n required: ['op', 'doc_id'],\n properties: {\n op: { const: 'snapshot' },\n doc_id: { $ref: '#/properties/doc_id' },\n },\n additionalProperties: false,\n },\n {\n required: ['op', 'doc_id', 'script'],\n properties: {\n op: { const: 'run-edit-script' },\n doc_id: { $ref: '#/properties/doc_id' },\n script: { $ref: '#/properties/script' },\n inputs: { $ref: '#/properties/inputs' },\n timeout_ms: { $ref: '#/properties/timeout_ms' },\n memory_limit_mb: { $ref: '#/properties/memory_limit_mb' },\n auto_commit: { $ref: '#/properties/auto_commit' },\n },\n additionalProperties: false,\n },\n {\n required: ['op', 'doc_id', 'plan_id'],\n properties: {\n op: { const: 'commit-plan' },\n doc_id: { $ref: '#/properties/doc_id' },\n plan_id: { $ref: '#/properties/plan_id' },\n validation: { $ref: '#/properties/validation' },\n },\n additionalProperties: false,\n },\n ],\n} as const;\n","import {\n createPlainMemoryAdapter,\n replayJournal,\n ValidationError,\n type JournalEntry,\n type MengineDocSession,\n type SemanticOpName,\n} from '@mengine/medeo-client';\n\n/**\n * A sandbox journal plus the opaque version token taken at fork time.\n * `commitPlan` rejects the whole plan when the live session has moved on\n * (phase-1 version gate), or localizes a business conflict to a journal\n * entry under `{ validation: 'preflight' }`.\n */\nexport interface CommitPlan {\n /** `session.version()` at the moment the sandbox was forked. */\n base_version: string;\n ops: readonly JournalEntry[];\n}\n\nexport type CommitPlanResult =\n | { kind: 'committed'; ops_applied: number }\n | { kind: 'rejected'; reason: 'version_mismatch'; expected: string; actual: string }\n | {\n kind: 'rejected';\n reason: 'op_conflict';\n /** Failing entry index in the journal — agent rerun anchor. */\n index: number;\n op_kind: SemanticOpName;\n /** Validator message, passed through verbatim (never a raw Error). */\n message: string;\n };\n\nexport interface CommitPlanOptions {\n /** `'version'` (default, phase-1 hard gate) | `'preflight'` (phase-2 per-op revalidation). */\n validation?: 'version' | 'preflight';\n}\n\n/**\n * Replay a sandbox journal into a live session through its document adapter\n * (SemanticEditor → Loro → mengine-server).\n *\n * - Default / `{ validation: 'version' }`: if `session.version()` ≠\n * `plan.base_version`, reject with zero writes.\n * - `{ validation: 'preflight' }`: skip the version gate; revalidate each op\n * against a PlainMemoryAdapter seeded from the current live snapshot, then\n * replay for real. A SchemaValidator failure becomes `op_conflict` with the\n * failing entry's index. Journal integrity errors (unrecorded/unconsumed\n * ids) still propagate as throws in both modes.\n */\nexport async function commitPlan(\n session: MengineDocSession,\n plan: CommitPlan,\n options?: CommitPlanOptions,\n): Promise<CommitPlanResult> {\n if (options?.validation === 'preflight') {\n return commitPlanPreflight(session, plan);\n }\n\n const actual = session.version();\n if (actual !== plan.base_version) {\n return {\n kind: 'rejected',\n reason: 'version_mismatch',\n expected: plan.base_version,\n actual,\n };\n }\n\n await replayJournal(session.documentAdapter, plan.ops);\n return { kind: 'committed', ops_applied: plan.ops.length };\n}\n\n/**\n * Phase-2 path: scratch revalidation then real replay. Each entry is driven\n * through `replayJournal` alone so a ValidationError maps to a stable index;\n * integrity throws are not wrapped.\n */\nasync function commitPlanPreflight(session: MengineDocSession, plan: CommitPlan): Promise<CommitPlanResult> {\n const scratch = createPlainMemoryAdapter(session.snapshot());\n\n for (let index = 0; index < plan.ops.length; index++) {\n const entry = plan.ops[index];\n if (entry == null) continue;\n try {\n await replayJournal(scratch, [entry]);\n } catch (error) {\n if (error instanceof ValidationError) {\n return opConflict(index, entry.kind, error.message);\n }\n throw error;\n }\n }\n\n // Real replay: optimistic window may still collide; wrap ValidationError the\n // same way. Prior entries in this loop have already been written.\n for (let index = 0; index < plan.ops.length; index++) {\n const entry = plan.ops[index];\n if (entry == null) continue;\n try {\n await replayJournal(session.documentAdapter, [entry]);\n } catch (error) {\n if (error instanceof ValidationError) {\n return opConflict(index, entry.kind, `real replay: ${error.message}`);\n }\n throw error;\n }\n }\n\n return { kind: 'committed', ops_applied: plan.ops.length };\n}\n\nfunction opConflict(index: number, op_kind: SemanticOpName, message: string): CommitPlanResult {\n return { kind: 'rejected', reason: 'op_conflict', index, op_kind, message };\n}\n","import { randomUUID } from 'node:crypto';\n\nimport {\n MengineDocSession,\n MengineHttpClient,\n type MengineDocSessionOptions,\n type VideoDocument,\n} from '@mengine/medeo-client';\n\nimport { renderCompactProjection } from './document/compact-projection.ts';\nimport { MEDEO_TOOL_DESCRIPTION } from './prompt.ts';\nimport { runEditScript } from './sandbox/node-host.ts';\nimport type { ChangePlan } from './sandbox/script-session.ts';\nimport { MEDEO_TOOL_NAME, MEDEO_TOOL_PARAMETERS, type MedeoToolOp } from './schema.ts';\nimport { commitPlan, type CommitPlanOptions, type CommitPlanResult } from './session/commit-plan.ts';\n\ntype ContextualValue<T> = T | ((docId: string) => T | undefined);\n\nexport interface CreateMedeoToolOptions {\n /**\n * Mengine HTTP origin for a document. The host owns environment routing\n * (local/stg/prd/lane) and may return a different origin per document.\n * Sessions cache by doc id, so the origin must remain stable for that doc.\n */\n httpOrigin: ContextualValue<string>;\n /** Optional bearer token, evaluated for each HTTP request. */\n authToken?: ContextualValue<string>;\n /** Optional end-user id header, evaluated for each HTTP request. */\n userId?: ContextualValue<string>;\n /** Stable agent peer id. Supply a host-scoped value so audit provenance is durable. */\n peerId?: ContextualValue<string>;\n fetchImpl?: typeof fetch;\n sseReconnectDelayMs?: number;\n /** Defaults passed to runEditScript; each call may override them. */\n sandbox?: { timeoutMs?: number; memoryLimitMb?: number };\n /** Maximum cached plans; oldest plans are evicted (default 16). */\n maxPlans?: number;\n}\n\nexport type MedeoToolInput =\n | { op: 'snapshot'; doc_id: string }\n | {\n op: 'run-edit-script';\n doc_id: string;\n script: string;\n inputs?: Record<string, unknown>;\n timeout_ms?: number;\n memory_limit_mb?: number;\n auto_commit?: boolean;\n }\n | {\n op: 'commit-plan';\n doc_id: string;\n plan_id: string;\n validation?: 'version' | 'preflight';\n };\n\nexport type MedeoToolResult =\n | { ok: true; op: 'snapshot'; doc_id: string; version: string; preview: string }\n | {\n ok: true;\n op: 'run-edit-script';\n doc_id: string;\n plan_id: string;\n base_version: string;\n ops_count: number;\n preview: string;\n logs: string[];\n duration_ms: number;\n committed?: boolean;\n commit_result?: CommitPlanResult;\n }\n | {\n ok: false;\n op: 'run-edit-script';\n doc_id: string;\n phase: 'parse' | 'runtime' | 'timeout' | 'memory';\n error: { message: string; line?: number; column?: number; stack?: string };\n partial: { ops_count: number; logs: string[] };\n }\n | {\n ok: true;\n op: 'commit-plan';\n doc_id: string;\n plan_id: string;\n committed: boolean;\n result: CommitPlanResult;\n }\n | { ok: false; op: MedeoToolOp; error: string };\n\nexport interface MedeoTool {\n name: typeof MEDEO_TOOL_NAME;\n description: typeof MEDEO_TOOL_DESCRIPTION;\n parameters: typeof MEDEO_TOOL_PARAMETERS;\n handle(input: unknown): Promise<MedeoToolResult>;\n close(): Promise<void>;\n}\n\ninterface CachedPlan {\n docId: string;\n plan: ChangePlan;\n}\n\nconst DEFAULT_MAX_PLANS = 16;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction optionalContext<T>(value: ContextualValue<T> | undefined, docId: string): T | undefined {\n if (value === undefined) return undefined;\n return typeof value === 'function' ? (value as (id: string) => T | undefined)(docId) : value;\n}\n\nfunction requiredContext(value: ContextualValue<string>, docId: string, field: string): string {\n const resolved = optionalContext(value, docId)?.trim();\n if (resolved == null || resolved.length === 0) {\n throw new Error(`${field} must resolve to a non-empty string for doc ${docId}`);\n }\n return resolved;\n}\n\nfunction parseInput(value: unknown): MedeoToolInput {\n if (!isRecord(value)) throw new Error('input must be an object');\n const op = value.op;\n const docId = value.doc_id;\n if (typeof op !== 'string') throw new Error('op must be a string');\n if (typeof docId !== 'string' || docId.trim().length === 0) throw new Error('doc_id must be a non-empty string');\n\n if (op === 'snapshot') return { op, doc_id: docId };\n\n if (op === 'run-edit-script') {\n if (typeof value.script !== 'string' || value.script.length === 0) {\n throw new Error('script must be a non-empty string');\n }\n if (value.inputs !== undefined && !isRecord(value.inputs)) {\n throw new Error('inputs must be an object');\n }\n const timeoutMs = value.timeout_ms;\n if (timeoutMs !== undefined && (typeof timeoutMs !== 'number' || !Number.isInteger(timeoutMs) || timeoutMs <= 0)) {\n throw new Error('timeout_ms must be a positive integer');\n }\n const memoryLimitMb = value.memory_limit_mb;\n if (\n memoryLimitMb !== undefined &&\n (typeof memoryLimitMb !== 'number' || !Number.isInteger(memoryLimitMb) || memoryLimitMb < 16)\n ) {\n throw new Error('memory_limit_mb must be an integer >= 16');\n }\n if (value.auto_commit !== undefined && typeof value.auto_commit !== 'boolean') {\n throw new Error('auto_commit must be a boolean');\n }\n return {\n op,\n doc_id: docId,\n script: value.script,\n ...(value.inputs !== undefined ? { inputs: value.inputs } : {}),\n ...(timeoutMs !== undefined ? { timeout_ms: timeoutMs } : {}),\n ...(memoryLimitMb !== undefined ? { memory_limit_mb: memoryLimitMb } : {}),\n ...(value.auto_commit !== undefined ? { auto_commit: value.auto_commit } : {}),\n };\n }\n\n if (op === 'commit-plan') {\n if (typeof value.plan_id !== 'string' || value.plan_id.length === 0) {\n throw new Error('plan_id must be a non-empty string');\n }\n if (value.validation !== undefined && value.validation !== 'version' && value.validation !== 'preflight') {\n throw new Error('validation must be \"version\" or \"preflight\"');\n }\n return {\n op,\n doc_id: docId,\n plan_id: value.plan_id,\n ...(value.validation !== undefined ? { validation: value.validation } : {}),\n };\n }\n\n throw new Error(`unknown op: ${op}`);\n}\n\n/**\n * Create the self-contained Medeo LLM tool.\n *\n * The package owns session construction, compact projection, sandbox execution,\n * plan caching, commit, and shutdown. The host supplies only environment facts:\n * HTTP origin, credentials, fetch implementation, and a stable peer id.\n */\nexport function createMedeoTool(options: CreateMedeoToolOptions): MedeoTool {\n const sessions = new Map<string, Promise<MengineDocSession>>();\n const plans = new Map<string, CachedPlan>();\n const maxPlans = options.maxPlans ?? DEFAULT_MAX_PLANS;\n let closed = false;\n\n async function getSession(docId: string): Promise<MengineDocSession> {\n if (closed) throw new Error('medeo tool is closed');\n const existing = sessions.get(docId);\n if (existing != null) return await existing;\n\n const created = (async () => {\n const client = new MengineHttpClient({\n docId,\n httpOrigin: requiredContext(options.httpOrigin, docId, 'httpOrigin'),\n ...(options.authToken !== undefined ? { authToken: () => optionalContext(options.authToken, docId) } : {}),\n ...(options.userId !== undefined ? { userId: () => optionalContext(options.userId, docId) } : {}),\n ...(options.fetchImpl !== undefined ? { fetchImpl: options.fetchImpl } : {}),\n });\n const peerId = optionalContext(options.peerId, docId);\n const session = new MengineDocSession({\n docId,\n client,\n ...(peerId !== undefined ? { peerId: peerId as MengineDocSessionOptions['peerId'] } : {}),\n ...(options.sseReconnectDelayMs !== undefined ? { sseReconnectDelayMs: options.sseReconnectDelayMs } : {}),\n });\n try {\n await session.start();\n return session;\n } catch (error) {\n session.destroy();\n throw error;\n }\n })();\n\n sessions.set(docId, created);\n try {\n return await created;\n } catch (error) {\n if (sessions.get(docId) === created) sessions.delete(docId);\n throw error;\n }\n }\n\n function rememberPlan(docId: string, plan: ChangePlan): string {\n const planId = randomUUID();\n plans.set(planId, { docId, plan });\n while (plans.size > maxPlans) {\n const oldest = plans.keys().next().value;\n if (oldest === undefined) break;\n plans.delete(oldest);\n }\n return planId;\n }\n\n async function snapshot(input: Extract<MedeoToolInput, { op: 'snapshot' }>): Promise<MedeoToolResult> {\n const session = await getSession(input.doc_id);\n const document = session.snapshot();\n return {\n ok: true,\n op: 'snapshot',\n doc_id: input.doc_id,\n version: session.version(),\n preview: renderCompactProjection(document),\n };\n }\n\n async function run(input: Extract<MedeoToolInput, { op: 'run-edit-script' }>): Promise<MedeoToolResult> {\n const session = await getSession(input.doc_id);\n const document: VideoDocument = session.snapshot();\n const baseVersion = session.version();\n const result = await runEditScript({\n document,\n baseVersion,\n script: input.script,\n ...(input.inputs !== undefined ? { inputs: input.inputs } : {}),\n timeoutMs: input.timeout_ms ?? options.sandbox?.timeoutMs,\n memoryLimitMb: input.memory_limit_mb ?? options.sandbox?.memoryLimitMb,\n });\n\n if (!result.ok) {\n return {\n ok: false,\n op: 'run-edit-script',\n doc_id: input.doc_id,\n phase: result.phase,\n error: result.error,\n partial: { ops_count: result.partial.ops.length, logs: result.partial.logs },\n };\n }\n\n const planId = rememberPlan(input.doc_id, result.plan);\n const base = {\n ok: true as const,\n op: 'run-edit-script' as const,\n doc_id: input.doc_id,\n plan_id: planId,\n base_version: baseVersion,\n ops_count: result.plan.ops.length,\n preview: result.plan.preview,\n logs: result.plan.logs,\n duration_ms: result.durationMs,\n };\n if (input.auto_commit !== true) return base;\n\n const commit = await commitPlan(session, result.plan);\n return { ...base, committed: commit.kind === 'committed', commit_result: commit };\n }\n\n async function commit(input: Extract<MedeoToolInput, { op: 'commit-plan' }>): Promise<MedeoToolResult> {\n const cached = plans.get(input.plan_id);\n if (cached == null || cached.docId !== input.doc_id) {\n throw new Error(`plan_id ${input.plan_id} is not available for doc ${input.doc_id}`);\n }\n const session = await getSession(input.doc_id);\n const commitOptions: CommitPlanOptions | undefined =\n input.validation === undefined ? undefined : { validation: input.validation };\n const result = await commitPlan(session, cached.plan, commitOptions);\n return {\n ok: true,\n op: 'commit-plan',\n doc_id: input.doc_id,\n plan_id: input.plan_id,\n committed: result.kind === 'committed',\n result,\n };\n }\n\n return {\n name: MEDEO_TOOL_NAME,\n description: MEDEO_TOOL_DESCRIPTION,\n parameters: MEDEO_TOOL_PARAMETERS,\n async handle(input: unknown): Promise<MedeoToolResult> {\n try {\n const parsed = parseInput(input);\n if (parsed.op === 'snapshot') return await snapshot(parsed);\n if (parsed.op === 'run-edit-script') return await run(parsed);\n return await commit(parsed);\n } catch (error) {\n const op = isRecord(input) && typeof input.op === 'string' ? (input.op as MedeoToolOp) : 'snapshot';\n return {\n ok: false,\n op,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n },\n async close(): Promise<void> {\n closed = true;\n const opening = [...sessions.values()];\n sessions.clear();\n plans.clear();\n const errors: unknown[] = [];\n for (const sessionPromise of opening) {\n try {\n const session = await sessionPromise;\n session.destroy();\n } catch (error) {\n errors.push(error);\n }\n }\n if (errors.length === 1) throw errors[0];\n if (errors.length > 1) throw new AggregateError(errors, 'failed to close medeo tool sessions');\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/sandbox/node-host.ts","../src/prompt.ts","../src/schema.ts","../src/session/commit-plan.ts","../src/host-tool.ts"],"sourcesContent":["/// <reference types=\"node\" />\n\nimport { Worker } from 'node:worker_threads';\n\nimport type { JournalEntry, VideoDocument } from '@mengine/medeo-client';\n\nimport type { ChangePlan } from './script-session.ts';\n\n/**\n * Host API for running an agent edit script in an isolated Node worker.\n *\n * Requires Node.js >= 24.15 (engines) so the worker can load TypeScript via\n * `--experimental-transform-types`. Do not inherit `process.execArgv` — vitest\n * injects loaders that break worker boot.\n */\n\nexport interface RunEditScriptOptions {\n document: VideoDocument;\n baseVersion: string;\n script: string;\n inputs?: Record<string, unknown>;\n /** Deterministic id mint label for tests; omit to use the default ULID factory. */\n idLabel?: string;\n /** Hard wall-clock timeout; default 2000 ms. */\n timeoutMs?: number;\n /** V8 old-generation ceiling for the worker; default 256 MB. */\n memoryLimitMb?: number;\n /** Override worker module URL (defaults to sibling `worker-entry.ts`). */\n workerEntryUrl?: URL;\n}\n\nexport type EditScriptResult =\n | {\n ok: true;\n plan: ChangePlan;\n /** Script execution time after worker readiness; excludes cold start. */\n durationMs: number;\n }\n | {\n ok: false;\n phase: 'parse' | 'runtime' | 'timeout' | 'memory';\n error: { message: string; line?: number; column?: number; stack?: string };\n partial: { ops: readonly JournalEntry[]; logs: string[] };\n };\n\ntype WorkerMessage =\n | { t: 'ready' }\n | { t: 'entry'; entry: JournalEntry }\n | { t: 'log'; line: string }\n | { t: 'truncate'; index: number }\n | { t: 'done'; preview: string; opsCount: number }\n | {\n t: 'fail';\n phase: 'parse' | 'runtime';\n error: { message: string; line?: number; column?: number; stack?: string };\n };\n\nconst DEFAULT_TIMEOUT_MS = 2000;\nconst DEFAULT_MEMORY_MB = 256;\n\n/**\n * Source runs load the checked-in TypeScript worker; packed runs load the\n * sibling JavaScript chunk emitted as a second package entry. Keeping this\n * branch explicit avoids shipping a `dist/*.ts` URL in the npm artifact.\n */\nfunction sourceSibling(fileName: string): URL {\n const selfUrl = new URL(import.meta.url);\n const extension = selfUrl.pathname.endsWith('.ts') ? 'ts' : 'mjs';\n return new URL(`./${fileName}.${extension}`, selfUrl);\n}\n\n/** Run `script` against a forked document snapshot; always resolves (never rejects). */\nexport function runEditScript(options: RunEditScriptOptions): Promise<EditScriptResult> {\n // Set when the worker has loaded its bundle and is about to invoke the script.\n // Keep this clock separate from worker boot so success timing matches the\n // timeout boundary and excludes cold-start/module-loading cost.\n let scriptStartedAt = performance.now();\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const memoryLimitMb = options.memoryLimitMb ?? DEFAULT_MEMORY_MB;\n const workerEntryUrl = options.workerEntryUrl ?? sourceSibling('worker-entry');\n const resolveRegisterUrl = sourceSibling('node-esm-resolve-register');\n\n const ops: JournalEntry[] = [];\n const logs: string[] = [];\n\n return new Promise<EditScriptResult>((resolve) => {\n let settled = false;\n let timedOut = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const worker = new Worker(workerEntryUrl, {\n workerData: {\n document: options.document,\n script: options.script,\n inputs: options.inputs,\n idLabel: options.idLabel,\n },\n // Explicit argv only — never inherit process.execArgv (vitest loaders).\n // Source workers need TypeScript transform plus the resolver hook for\n // workspace packages that still use extensionless directory imports.\n // Packed JavaScript workers already contain those dependencies.\n execArgv: resolveRegisterUrl.pathname.endsWith('.ts')\n ? [\n '--experimental-transform-types',\n '--disable-warning=ExperimentalWarning',\n `--import=${resolveRegisterUrl.href}`,\n ]\n : [],\n resourceLimits: { maxOldGenerationSizeMb: memoryLimitMb },\n });\n\n /** Start wall-clock timeout only after worker signals script is about to run. */\n const armTimeout = (): void => {\n if (settled || timer != null) return;\n timer = setTimeout(() => {\n timedOut = true;\n void worker.terminate();\n finish({\n ok: false,\n phase: 'timeout',\n error: { message: `edit script exceeded timeout of ${timeoutMs}ms` },\n partial: { ops: ops.slice(), logs: logs.slice() },\n });\n }, timeoutMs);\n };\n\n const finish = (result: EditScriptResult): void => {\n if (settled) return;\n settled = true;\n if (timer != null) clearTimeout(timer);\n void worker.terminate();\n if (result.ok) {\n resolve({ ...result, durationMs: performance.now() - scriptStartedAt });\n } else {\n resolve(result);\n }\n };\n\n worker.on('message', (message: WorkerMessage) => {\n if (settled) return;\n if (message.t === 'ready') {\n scriptStartedAt = performance.now();\n armTimeout();\n return;\n }\n if (message.t === 'entry') {\n ops.push(message.entry);\n return;\n }\n if (message.t === 'log') {\n logs.push(message.line);\n return;\n }\n if (message.t === 'truncate') {\n ops.length = Math.max(0, Math.min(message.index, ops.length));\n return;\n }\n if (message.t === 'done') {\n if (message.opsCount !== ops.length) {\n finish({\n ok: false,\n phase: 'runtime',\n error: {\n message: `opsCount mismatch: worker reported ${message.opsCount}, host collected ${ops.length}`,\n },\n partial: { ops: ops.slice(), logs: logs.slice() },\n });\n return;\n }\n finish({\n ok: true,\n plan: {\n doc_id: options.document.meta.draft_id ?? '',\n base_version: options.baseVersion,\n ops: ops.slice(),\n preview: message.preview,\n logs: logs.slice(),\n },\n durationMs: 0,\n });\n return;\n }\n if (message.t === 'fail') {\n finish({\n ok: false,\n phase: message.phase,\n error: message.error,\n partial: { ops: ops.slice(), logs: logs.slice() },\n });\n }\n });\n\n worker.on('error', (error: Error) => {\n if (settled) return;\n const text = error.message ?? String(error);\n const phase = /memory limit/i.test(text) ? 'memory' : 'runtime';\n finish({\n ok: false,\n phase,\n error: { message: text, stack: error.stack },\n partial: { ops: ops.slice(), logs: logs.slice() },\n });\n });\n\n worker.on('exit', (code: number) => {\n if (settled) return;\n if (timedOut) return;\n finish({\n ok: false,\n phase: 'runtime',\n error: { message: `worker exited with code ${code ?? 'null'} before completion` },\n partial: { ops: ops.slice(), logs: logs.slice() },\n });\n });\n });\n}\n","export const MEDEO_TOOL_DESCRIPTION = `\nEdit a Medeo video document through a deterministic, side-effect-free JavaScript sandbox.\n\nOperations:\n- snapshot: return the compact timeline projection and opaque base version.\n- run-edit-script: execute JavaScript against a forked snapshot. Inspect timeline.*, compute coordinates, and call edit.* methods in one script. The sandbox has no network, storage, clock, or generation access. Pass materialized asset/speech facts through inputs. A successful run returns preview, logs, base_version, and plan_id — not the full op journal.\n- commit-plan: replay a cached plan_id into the live MengineDocSession through SemanticEditor. Use validation=version for all-or-nothing commit, or preflight to localize an op conflict after concurrent edits.\n\nDefault flow: snapshot → run-edit-script with auto_commit=false → inspect preview → commit-plan. Use auto_commit=true only for low-risk edits when the host does not need user confirmation. On version mismatch, rerun snapshot and the script; never try to patch a rejected journal by hand.\n`.trim();\n","export const MEDEO_TOOL_NAME = 'medeo';\n\nexport type MedeoToolOp = 'snapshot' | 'run-edit-script' | 'commit-plan';\n\n/**\n * JSON Schema for the host-facing three-op `medeo` tool surface.\n *\n * The schema intentionally does not return or accept the full op journal:\n * journals stay in the tool process and are referenced by `plan_id`. This keeps\n * large intermediate products out of model context while preserving the exact\n * journal used for commit.\n */\nexport const MEDEO_TOOL_PARAMETERS = {\n type: 'object',\n required: ['op', 'doc_id'],\n additionalProperties: false,\n properties: {\n op: {\n type: 'string',\n enum: ['snapshot', 'run-edit-script', 'commit-plan'],\n description: 'Which Medeo document operation to run.',\n },\n doc_id: {\n type: 'string',\n minLength: 1,\n description: 'Medeo document id. Copy it from the host context; never invent it.',\n },\n script: {\n type: 'string',\n minLength: 1,\n description:\n 'JavaScript body for run-edit-script. It receives edit, timeline, checkpoint, rollbackTo, inputs, and console; perform all calculations in the script.',\n },\n inputs: {\n type: 'object',\n description:\n 'Pre-materialized, side-effect-free values passed into the script. Generation and network IO must happen in the host before this call.',\n },\n timeout_ms: {\n type: 'integer',\n minimum: 1,\n description: 'Maximum script wall-clock time after worker startup (default 2000).',\n },\n memory_limit_mb: {\n type: 'integer',\n minimum: 16,\n description: 'Worker old-generation memory ceiling in MB (default 256).',\n },\n auto_commit: {\n type: 'boolean',\n description:\n 'Commit the returned plan immediately after the sandbox succeeds. Default false: return preview plus plan_id for explicit commit.',\n },\n plan_id: {\n type: 'string',\n minLength: 1,\n description: 'Plan id returned by run-edit-script; required by commit-plan.',\n },\n validation: {\n type: 'string',\n enum: ['version', 'preflight'],\n description:\n 'commit-plan mode: version rejects any concurrent change; preflight revalidates each op against the current snapshot.',\n },\n },\n oneOf: [\n {\n required: ['op', 'doc_id'],\n properties: {\n op: { const: 'snapshot' },\n doc_id: { $ref: '#/properties/doc_id' },\n },\n additionalProperties: false,\n },\n {\n required: ['op', 'doc_id', 'script'],\n properties: {\n op: { const: 'run-edit-script' },\n doc_id: { $ref: '#/properties/doc_id' },\n script: { $ref: '#/properties/script' },\n inputs: { $ref: '#/properties/inputs' },\n timeout_ms: { $ref: '#/properties/timeout_ms' },\n memory_limit_mb: { $ref: '#/properties/memory_limit_mb' },\n auto_commit: { $ref: '#/properties/auto_commit' },\n },\n additionalProperties: false,\n },\n {\n required: ['op', 'doc_id', 'plan_id'],\n properties: {\n op: { const: 'commit-plan' },\n doc_id: { $ref: '#/properties/doc_id' },\n plan_id: { $ref: '#/properties/plan_id' },\n validation: { $ref: '#/properties/validation' },\n },\n additionalProperties: false,\n },\n ],\n} as const;\n","import {\n createPlainMemoryAdapter,\n replayJournal,\n ValidationError,\n type JournalEntry,\n type MengineDocSession,\n type SemanticOpName,\n} from '@mengine/medeo-client';\n\n/**\n * A sandbox journal plus the opaque version token taken at fork time.\n * `commitPlan` rejects the whole plan when the live session has moved on\n * (phase-1 version gate), or localizes a business conflict to a journal\n * entry under `{ validation: 'preflight' }`.\n */\nexport interface CommitPlan {\n /** `session.version()` at the moment the sandbox was forked. */\n base_version: string;\n ops: readonly JournalEntry[];\n}\n\nexport type CommitPlanResult =\n | { kind: 'committed'; ops_applied: number }\n | { kind: 'rejected'; reason: 'version_mismatch'; expected: string; actual: string }\n | {\n kind: 'rejected';\n reason: 'op_conflict';\n /** Failing entry index in the journal — agent rerun anchor. */\n index: number;\n op_kind: SemanticOpName;\n /** Validator message, passed through verbatim (never a raw Error). */\n message: string;\n };\n\nexport interface CommitPlanOptions {\n /** `'version'` (default, phase-1 hard gate) | `'preflight'` (phase-2 per-op revalidation). */\n validation?: 'version' | 'preflight';\n}\n\n/**\n * Replay a sandbox journal into a live session through its document adapter\n * (SemanticEditor → Loro → mengine-server).\n *\n * - Default / `{ validation: 'version' }`: if `session.version()` ≠\n * `plan.base_version`, reject with zero writes.\n * - `{ validation: 'preflight' }`: skip the version gate; revalidate each op\n * against a PlainMemoryAdapter seeded from the current live snapshot, then\n * replay for real. A SchemaValidator failure becomes `op_conflict` with the\n * failing entry's index. Journal integrity errors (unrecorded/unconsumed\n * ids) still propagate as throws in both modes.\n */\nexport async function commitPlan(\n session: MengineDocSession,\n plan: CommitPlan,\n options?: CommitPlanOptions,\n): Promise<CommitPlanResult> {\n if (options?.validation === 'preflight') {\n return commitPlanPreflight(session, plan);\n }\n\n const actual = session.version();\n if (actual !== plan.base_version) {\n return {\n kind: 'rejected',\n reason: 'version_mismatch',\n expected: plan.base_version,\n actual,\n };\n }\n\n await replayJournal(session.documentAdapter, plan.ops);\n return { kind: 'committed', ops_applied: plan.ops.length };\n}\n\n/**\n * Phase-2 path: scratch revalidation then real replay. Each entry is driven\n * through `replayJournal` alone so a ValidationError maps to a stable index;\n * integrity throws are not wrapped.\n */\nasync function commitPlanPreflight(session: MengineDocSession, plan: CommitPlan): Promise<CommitPlanResult> {\n const scratch = createPlainMemoryAdapter(session.snapshot());\n\n for (let index = 0; index < plan.ops.length; index++) {\n const entry = plan.ops[index];\n if (entry == null) continue;\n try {\n await replayJournal(scratch, [entry]);\n } catch (error) {\n if (error instanceof ValidationError) {\n return opConflict(index, entry.kind, error.message);\n }\n throw error;\n }\n }\n\n // Real replay: optimistic window may still collide; wrap ValidationError the\n // same way. Prior entries in this loop have already been written.\n for (let index = 0; index < plan.ops.length; index++) {\n const entry = plan.ops[index];\n if (entry == null) continue;\n try {\n await replayJournal(session.documentAdapter, [entry]);\n } catch (error) {\n if (error instanceof ValidationError) {\n return opConflict(index, entry.kind, `real replay: ${error.message}`);\n }\n throw error;\n }\n }\n\n return { kind: 'committed', ops_applied: plan.ops.length };\n}\n\nfunction opConflict(index: number, op_kind: SemanticOpName, message: string): CommitPlanResult {\n return { kind: 'rejected', reason: 'op_conflict', index, op_kind, message };\n}\n","import { randomUUID } from 'node:crypto';\n\nimport {\n createMirrorVideoDocument,\n MengineDocSession,\n MengineHttpClient,\n MengineHttpRequestError,\n toVideoDocument,\n type MengineDocSessionOptions,\n type VideoDocument,\n type VideoDraft,\n} from '@mengine/medeo-client';\n\nimport { renderCompactProjection } from './document/compact-projection.ts';\nimport { MEDEO_TOOL_DESCRIPTION } from './prompt.ts';\nimport { runEditScript } from './sandbox/node-host.ts';\nimport type { ChangePlan } from './sandbox/script-session.ts';\nimport { MEDEO_TOOL_NAME, MEDEO_TOOL_PARAMETERS, type MedeoToolOp } from './schema.ts';\nimport { commitPlan, type CommitPlanOptions, type CommitPlanResult } from './session/commit-plan.ts';\n\ntype ContextualValue<T> = T | ((docId: string) => T | undefined);\n\nexport interface CreateMedeoToolOptions {\n /**\n * Mengine HTTP origin for a document. The host owns environment routing\n * (local/stg/prd/lane) and may return a different origin per document.\n * Sessions cache by doc id, so the origin must remain stable for that doc.\n */\n httpOrigin: ContextualValue<string>;\n /** Optional bearer token, evaluated for each HTTP request. */\n authToken?: ContextualValue<string>;\n /** Optional end-user id header, evaluated for each HTTP request. */\n userId?: ContextualValue<string>;\n /** Stable agent peer id. Supply a host-scoped value so audit provenance is durable. */\n peerId?: ContextualValue<string>;\n /**\n * Load the authoritative legacy draft used to create a missing Mengine\n * document. The tool owns the get-or-create flow: it first probes Mengine,\n * converts this draft into a VideoDocument only on a 404, bootstraps the\n * snapshot, and tolerates a concurrent creator winning the race.\n */\n loadInitialDraft?: (docId: string) => Promise<VideoDraft>;\n fetchImpl?: typeof fetch;\n sseReconnectDelayMs?: number;\n /** Defaults passed to runEditScript; each call may override them. */\n sandbox?: { timeoutMs?: number; memoryLimitMb?: number };\n /** Maximum cached plans; oldest plans are evicted (default 16). */\n maxPlans?: number;\n}\n\nexport type MedeoToolInput =\n | { op: 'snapshot'; doc_id: string }\n | {\n op: 'run-edit-script';\n doc_id: string;\n script: string;\n inputs?: Record<string, unknown>;\n timeout_ms?: number;\n memory_limit_mb?: number;\n auto_commit?: boolean;\n }\n | {\n op: 'commit-plan';\n doc_id: string;\n plan_id: string;\n validation?: 'version' | 'preflight';\n };\n\nexport type MedeoToolResult =\n | { ok: true; op: 'snapshot'; doc_id: string; version: string; preview: string }\n | {\n ok: true;\n op: 'run-edit-script';\n doc_id: string;\n plan_id: string;\n base_version: string;\n ops_count: number;\n preview: string;\n logs: string[];\n duration_ms: number;\n committed?: boolean;\n commit_result?: CommitPlanResult;\n }\n | {\n ok: false;\n op: 'run-edit-script';\n doc_id: string;\n phase: 'parse' | 'runtime' | 'timeout' | 'memory';\n error: { message: string; line?: number; column?: number; stack?: string };\n partial: { ops_count: number; logs: string[] };\n }\n | {\n ok: true;\n op: 'commit-plan';\n doc_id: string;\n plan_id: string;\n committed: boolean;\n result: CommitPlanResult;\n }\n | { ok: false; op: MedeoToolOp; error: string };\n\nexport interface MedeoTool {\n name: typeof MEDEO_TOOL_NAME;\n description: typeof MEDEO_TOOL_DESCRIPTION;\n parameters: typeof MEDEO_TOOL_PARAMETERS;\n handle(input: unknown): Promise<MedeoToolResult>;\n close(): Promise<void>;\n}\n\nexport type MedeoInitialDraft = VideoDraft;\n\ninterface CachedPlan {\n docId: string;\n plan: ChangePlan;\n}\n\nconst DEFAULT_MAX_PLANS = 16;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction optionalContext<T>(value: ContextualValue<T> | undefined, docId: string): T | undefined {\n if (value === undefined) return undefined;\n return typeof value === 'function' ? (value as (id: string) => T | undefined)(docId) : value;\n}\n\nfunction requiredContext(value: ContextualValue<string>, docId: string, field: string): string {\n const resolved = optionalContext(value, docId)?.trim();\n if (resolved == null || resolved.length === 0) {\n throw new Error(`${field} must resolve to a non-empty string for doc ${docId}`);\n }\n return resolved;\n}\n\nfunction parseInput(value: unknown): MedeoToolInput {\n if (!isRecord(value)) throw new Error('input must be an object');\n const op = value.op;\n const docId = value.doc_id;\n if (typeof op !== 'string') throw new Error('op must be a string');\n if (typeof docId !== 'string' || docId.trim().length === 0) throw new Error('doc_id must be a non-empty string');\n\n if (op === 'snapshot') return { op, doc_id: docId };\n\n if (op === 'run-edit-script') {\n if (typeof value.script !== 'string' || value.script.length === 0) {\n throw new Error('script must be a non-empty string');\n }\n if (value.inputs !== undefined && !isRecord(value.inputs)) {\n throw new Error('inputs must be an object');\n }\n const timeoutMs = value.timeout_ms;\n if (timeoutMs !== undefined && (typeof timeoutMs !== 'number' || !Number.isInteger(timeoutMs) || timeoutMs <= 0)) {\n throw new Error('timeout_ms must be a positive integer');\n }\n const memoryLimitMb = value.memory_limit_mb;\n if (\n memoryLimitMb !== undefined &&\n (typeof memoryLimitMb !== 'number' || !Number.isInteger(memoryLimitMb) || memoryLimitMb < 16)\n ) {\n throw new Error('memory_limit_mb must be an integer >= 16');\n }\n if (value.auto_commit !== undefined && typeof value.auto_commit !== 'boolean') {\n throw new Error('auto_commit must be a boolean');\n }\n return {\n op,\n doc_id: docId,\n script: value.script,\n ...(value.inputs !== undefined ? { inputs: value.inputs } : {}),\n ...(timeoutMs !== undefined ? { timeout_ms: timeoutMs } : {}),\n ...(memoryLimitMb !== undefined ? { memory_limit_mb: memoryLimitMb } : {}),\n ...(value.auto_commit !== undefined ? { auto_commit: value.auto_commit } : {}),\n };\n }\n\n if (op === 'commit-plan') {\n if (typeof value.plan_id !== 'string' || value.plan_id.length === 0) {\n throw new Error('plan_id must be a non-empty string');\n }\n if (value.validation !== undefined && value.validation !== 'version' && value.validation !== 'preflight') {\n throw new Error('validation must be \"version\" or \"preflight\"');\n }\n return {\n op,\n doc_id: docId,\n plan_id: value.plan_id,\n ...(value.validation !== undefined ? { validation: value.validation } : {}),\n };\n }\n\n throw new Error(`unknown op: ${op}`);\n}\n\n/**\n * Create the self-contained Medeo LLM tool.\n *\n * The package owns session construction, compact projection, sandbox execution,\n * plan caching, commit, document get-or-create, and shutdown. The host supplies\n * environment facts plus the authoritative legacy draft loader used only when\n * Mengine has no document yet.\n */\nexport function createMedeoTool(options: CreateMedeoToolOptions): MedeoTool {\n const sessions = new Map<string, Promise<MengineDocSession>>();\n const plans = new Map<string, CachedPlan>();\n const maxPlans = options.maxPlans ?? DEFAULT_MAX_PLANS;\n let closed = false;\n\n async function getSession(docId: string): Promise<MengineDocSession> {\n if (closed) throw new Error('medeo tool is closed');\n const existing = sessions.get(docId);\n if (existing != null) return await existing;\n\n const created = (async () => {\n const client = new MengineHttpClient({\n docId,\n httpOrigin: requiredContext(options.httpOrigin, docId, 'httpOrigin'),\n ...(options.authToken !== undefined ? { authToken: () => optionalContext(options.authToken, docId) } : {}),\n ...(options.userId !== undefined ? { userId: () => optionalContext(options.userId, docId) } : {}),\n ...(options.fetchImpl !== undefined ? { fetchImpl: options.fetchImpl } : {}),\n });\n const peerId = optionalContext(options.peerId, docId) as MengineDocSessionOptions['peerId'] | undefined;\n await getOrCreateDocument(client, docId, peerId);\n const session = new MengineDocSession({\n docId,\n client,\n ...(peerId !== undefined ? { peerId } : {}),\n ...(options.sseReconnectDelayMs !== undefined ? { sseReconnectDelayMs: options.sseReconnectDelayMs } : {}),\n });\n try {\n await session.start();\n return session;\n } catch (error) {\n session.destroy();\n throw error;\n }\n })();\n\n sessions.set(docId, created);\n try {\n return await created;\n } catch (error) {\n if (sessions.get(docId) === created) sessions.delete(docId);\n throw error;\n }\n }\n\n async function getOrCreateDocument(\n client: MengineHttpClient,\n docId: string,\n peerId: MengineDocSessionOptions['peerId'] | undefined,\n ): Promise<void> {\n try {\n await client.fetchSnapshot();\n return;\n } catch (error) {\n if (!(error instanceof MengineHttpRequestError) || error.status !== 404) throw error;\n if (options.loadInitialDraft === undefined) throw error;\n }\n\n const draft = await options.loadInitialDraft(docId);\n const document = toVideoDocument(draft);\n const seed = createMirrorVideoDocument(document, {\n ...(peerId !== undefined ? { peerId } : {}),\n origin: 'mengine.medeo_tool.bootstrap',\n });\n\n try {\n await client.bootstrapSnapshot(seed.export({ mode: 'snapshot' }));\n } catch (error) {\n // Bootstrap is create-only. If another worker created the same document\n // after our 404 probe, accept that winner only after an authenticated\n // snapshot read proves the document now exists and is accessible.\n if (!(error instanceof MengineHttpRequestError) || error.status !== 400) throw error;\n await client.fetchSnapshot();\n }\n }\n\n function rememberPlan(docId: string, plan: ChangePlan): string {\n const planId = randomUUID();\n plans.set(planId, { docId, plan });\n while (plans.size > maxPlans) {\n const oldest = plans.keys().next().value;\n if (oldest === undefined) break;\n plans.delete(oldest);\n }\n return planId;\n }\n\n async function snapshot(input: Extract<MedeoToolInput, { op: 'snapshot' }>): Promise<MedeoToolResult> {\n const session = await getSession(input.doc_id);\n const document = session.snapshot();\n return {\n ok: true,\n op: 'snapshot',\n doc_id: input.doc_id,\n version: session.version(),\n preview: renderCompactProjection(document),\n };\n }\n\n async function run(input: Extract<MedeoToolInput, { op: 'run-edit-script' }>): Promise<MedeoToolResult> {\n const session = await getSession(input.doc_id);\n const document: VideoDocument = session.snapshot();\n const baseVersion = session.version();\n const result = await runEditScript({\n document,\n baseVersion,\n script: input.script,\n ...(input.inputs !== undefined ? { inputs: input.inputs } : {}),\n timeoutMs: input.timeout_ms ?? options.sandbox?.timeoutMs,\n memoryLimitMb: input.memory_limit_mb ?? options.sandbox?.memoryLimitMb,\n });\n\n if (!result.ok) {\n return {\n ok: false,\n op: 'run-edit-script',\n doc_id: input.doc_id,\n phase: result.phase,\n error: result.error,\n partial: { ops_count: result.partial.ops.length, logs: result.partial.logs },\n };\n }\n\n const planId = rememberPlan(input.doc_id, result.plan);\n const base = {\n ok: true as const,\n op: 'run-edit-script' as const,\n doc_id: input.doc_id,\n plan_id: planId,\n base_version: baseVersion,\n ops_count: result.plan.ops.length,\n preview: result.plan.preview,\n logs: result.plan.logs,\n duration_ms: result.durationMs,\n };\n if (input.auto_commit !== true) return base;\n\n const commit = await commitPlan(session, result.plan);\n return { ...base, committed: commit.kind === 'committed', commit_result: commit };\n }\n\n async function commit(input: Extract<MedeoToolInput, { op: 'commit-plan' }>): Promise<MedeoToolResult> {\n const cached = plans.get(input.plan_id);\n if (cached == null || cached.docId !== input.doc_id) {\n throw new Error(`plan_id ${input.plan_id} is not available for doc ${input.doc_id}`);\n }\n const session = await getSession(input.doc_id);\n const commitOptions: CommitPlanOptions | undefined =\n input.validation === undefined ? undefined : { validation: input.validation };\n const result = await commitPlan(session, cached.plan, commitOptions);\n return {\n ok: true,\n op: 'commit-plan',\n doc_id: input.doc_id,\n plan_id: input.plan_id,\n committed: result.kind === 'committed',\n result,\n };\n }\n\n return {\n name: MEDEO_TOOL_NAME,\n description: MEDEO_TOOL_DESCRIPTION,\n parameters: MEDEO_TOOL_PARAMETERS,\n async handle(input: unknown): Promise<MedeoToolResult> {\n try {\n const parsed = parseInput(input);\n if (parsed.op === 'snapshot') return await snapshot(parsed);\n if (parsed.op === 'run-edit-script') return await run(parsed);\n return await commit(parsed);\n } catch (error) {\n const op = isRecord(input) && typeof input.op === 'string' ? (input.op as MedeoToolOp) : 'snapshot';\n return {\n ok: false,\n op,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n },\n async close(): Promise<void> {\n closed = true;\n const opening = [...sessions.values()];\n sessions.clear();\n plans.clear();\n const errors: unknown[] = [];\n for (const sessionPromise of opening) {\n try {\n const session = await sessionPromise;\n session.destroy();\n } catch (error) {\n errors.push(error);\n }\n }\n if (errors.length === 1) throw errors[0];\n if (errors.length > 1) throw new AggregateError(errors, 'failed to close medeo tool sessions');\n },\n };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mengine/medeo-tool",
|
|
3
|
-
"version": "1.0.1-alpha.
|
|
3
|
+
"version": "1.0.1-alpha.2",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"registry": "https://registry.npmjs.org/"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@mengine/medeo-client": "1.0.1-alpha.
|
|
27
|
+
"@mengine/medeo-client": "1.0.1-alpha.2"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/node": "^25.9.1",
|