@mengine/medeo-tool 1.4.1-alpha.5 → 2.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/README.md CHANGED
@@ -84,6 +84,15 @@ Resource-free Caption composition from AudioScript is also supported. Each
84
84
  on-screen placement has its own Clip and display SequenceMarker, connected by
85
85
  ordinary relations; intrinsic Caption timing remains independent.
86
86
 
87
+ Voice resources use `external: {system: 'memota-speech', key: speechId}`.
88
+ Await `rgetAssetFromEntity(voiceId)` before constructing placement relations: the
89
+ host supplies `storageKey`, the full millisecond `extent`, and the optional TTS
90
+ `voice` locator. The loader returns `{assetId, content: {storageKey, durationMs,
91
+ voice?}}` from a project-scoped Speech lookup. Recorded speech omits `voice`;
92
+ TTS retains its explicit PhoneticScript relation. Resource reads do not create
93
+ script text or display markers. New or changed Speech references are also
94
+ resolved before commit, and failed reads publish no partial edits.
95
+
87
96
  `materializeResources` and generation/resource loaders are host APIs. The model
88
97
  never receives these capabilities. Project initialization and historical data
89
98
  migration also remain outside script execution. Retrying an unconfirmed commit
@@ -116,7 +116,7 @@ interface EntityPayloadByKind {
116
116
  };
117
117
  }
118
118
  /** Stored own fields; a variant may obtain required content fields from its declared bases. */
119
- type StoredEntityPayload<K extends KnownEntityKind> = EntityPayloadByKind[K] | (K extends 'caption' ? JsonObject & Pick<MediaAssetPayload, 'external'> : never) | (JsonObject & Partial<EntityPayloadByKind[K]> & {
119
+ type StoredEntityPayload<K extends KnownEntityKind> = EntityPayloadByKind[K] | (K extends 'caption' | 'voice' ? JsonObject & Pick<MediaAssetPayload, 'external'> : never) | (JsonObject & Partial<EntityPayloadByKind[K]> & {
120
120
  baseEntityIds: string[];
121
121
  });
122
122
  interface SandboxEntity<K extends KnownEntityKind = KnownEntityKind> {
@@ -238,4 +238,4 @@ interface BusinessRelationFacade {
238
238
  }
239
239
  //#endregion
240
240
  export { UpdateEntityInput as C, UnlinkRelationInput as S, LinkRelationInput as _, DeleteEntityInput as a, SandboxEntity as b, EntitySandboxCheckpoint as c, JsonObject as d, JsonPrimitive as f, LinkGeneratedRelationInput as g, KnownRelationKind as h, CreateEntityInput as i, EntityStoreSnapshot as l, KnownEntityKind as m, BusinessEntityFacade as n, EntityCommand as o, JsonValue as p, BusinessRelationFacade as r, EntityPlanState as s, AuthorableRelationKind as t, EntityUpdateInput as u, RelationUpdateInput as v, SandboxRelation as x, ResourceEntityKind as y };
241
- //# sourceMappingURL=entity-contract-DlmUSouB.d.mts.map
241
+ //# sourceMappingURL=entity-contract-G4HxwNXl.d.mts.map
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { C as UpdateEntityInput, S as UnlinkRelationInput, _ as LinkRelationInput, a as DeleteEntityInput, b as SandboxEntity, c as EntitySandboxCheckpoint, d as JsonObject, f as JsonPrimitive, g as LinkGeneratedRelationInput, h as KnownRelationKind, i as CreateEntityInput, l as EntityStoreSnapshot, m as KnownEntityKind, n as BusinessEntityFacade, o as EntityCommand, p as JsonValue, r as BusinessRelationFacade, s as EntityPlanState, t as AuthorableRelationKind, u as EntityUpdateInput, v as RelationUpdateInput, x as SandboxRelation, y as ResourceEntityKind } from "./entity-contract-DlmUSouB.mjs";
1
+ import { C as UpdateEntityInput, S as UnlinkRelationInput, _ as LinkRelationInput, a as DeleteEntityInput, b as SandboxEntity, c as EntitySandboxCheckpoint, d as JsonObject, f as JsonPrimitive, g as LinkGeneratedRelationInput, h as KnownRelationKind, i as CreateEntityInput, l as EntityStoreSnapshot, m as KnownEntityKind, n as BusinessEntityFacade, o as EntityCommand, p as JsonValue, r as BusinessRelationFacade, s as EntityPlanState, t as AuthorableRelationKind, u as EntityUpdateInput, v as RelationUpdateInput, x as SandboxRelation, y as ResourceEntityKind } from "./entity-contract-G4HxwNXl.mjs";
2
2
  import { JournalEntry, ManualSyncDoc, MediaAssetFact, PartIdFactory, SemanticOpName, VideoDocument, VideoDraft } from "@mengine/medeo-client";
3
3
 
4
4
  //#region src/document/compact-projection.d.ts
package/dist/index.mjs CHANGED
@@ -985,7 +985,7 @@ const ENTITY_EDIT_SANDBOX_API_DTS = [
985
985
  "/** Stored own fields; a variant may obtain required content fields from its declared bases. */",
986
986
  "export type StoredEntityPayload<K extends KnownEntityKind> =",
987
987
  " | EntityPayloadByKind[K]",
988
- " | (K extends 'caption' ? JsonObject & Pick<MediaAssetPayload, 'external'> : never)",
988
+ " | (K extends 'caption' | 'voice' ? JsonObject & Pick<MediaAssetPayload, 'external'> : never)",
989
989
  " | (JsonObject &",
990
990
  " Partial<EntityPayloadByKind[K]> & {",
991
991
  " baseEntityIds: string[];",
@@ -1008,7 +1008,7 @@ const ENTITY_EDIT_SANDBOX_API_DTS = [
1008
1008
  "}",
1009
1009
  "export declare const entities: BusinessEntityFacade;",
1010
1010
  "export declare const relations: BusinessRelationFacade;",
1011
- "/** Resolve this Entity's attached resource through the host; await before using an uninitialized Caption. */",
1011
+ "/** Resolve this Entity's attached resource through the host; await before using an uninitialized Caption or Voice. */",
1012
1012
  "export declare function rgetAssetFromEntity(entityId: string): Promise<EntityAssetContent>;",
1013
1013
  "export declare function checkpoint(): EntitySandboxCheckpoint;",
1014
1014
  "export declare function rollbackTo(cp: EntitySandboxCheckpoint): void;",
@@ -1048,6 +1048,8 @@ Generation tools return resource references. An asset id may be passed in an ent
1048
1048
 
1049
1049
  Project initialization creates one current Timeline, the four standard Tracks and one attached AudioScript with segments:[]. A project may contain multiple independent complete AudioScripts (for example a generated script and an uploaded video transcript). The project AudioScript attachment selects only the panel view; it is not a singleton or membership constraint. Locate scripts with entities.list and choose the appropriate source. AudioScript owns independent multi-segment text; each can have multiple Caption variants. Caption and PhoneticScript compose it through baseEntityIds. Caption owns exactly one selection object ({segmentId,textRange?}), never an array or the legacy selections field. It selects one script segment or a contiguous substring, and owns only that selection's intrinsic timing and style; segmentId is a stable script-local identity, not an entity reference or transient array index; selection textRange is a half-open code-point range and can split display text without rewriting the script. PhoneticScript owns pronunciation/prosody; Voice is generated from it and related by phonetic-script-render(voice,phoneticScript). Speech and caption occupy separate Clips. Subtitles normally accompany sound; use source media or generate Voice from PhoneticScript when the request requires narration. Do not fabricate a sound resource.
1050
1050
 
1051
+ For Speech resources, create a Voice with external:{system:'memota-speech',key:speechId}, then await rgetAssetFromEntity(voiceId) before linking its placement. The host supplies full extent and optional voice-library identity, and assembles physical storage facts internally. Read the visible fields through entities.get; never invent them or use a Speech ID as a Memota media ID. TTS Voice still requires its real PhoneticScript relation; resource loading does not invent script content.
1052
+
1051
1053
  AudioScript has no intrinsic time and cannot be Clip content. ASR input Audio/Video/Voice associates via audio-script-source(script,source). Its external annotation SequenceMarker associates via audio-script-marker(script,marker) and receives assigned segmentRanges, not references to another marker. Caption intrinsic timing and its Clip's display SequenceMarker are distinct. Move/stretch display by editing only the placement marker.
1052
1054
 
1053
1055
  To place content, create a Clip and a SequenceMarker, then link track-clip(track,clip), clip-marker(clip,marker) and marker-content(marker,content). Existing track membership uses timeline-track(timeline,track). The editor has one track of each role: video_clip for Image/Video, speech for Voice, caption for Caption, bgm for Audio. Inspect factual media extents; never invent duration. Each placement is exactly one of Clip.order (sequential), Marker.targetRange (absolute) or clip-anchor(childClip,hostClip) plus Marker.anchorOffset. Marker.sourceRange selects source, duration describes playback/display. Whole milliseconds are required by this editor projection. Clip.volume is decibels (-60..20, 0 original). Image is unbounded/constant. Linear timeRemapping is {kind:'linear',rate:2,mode:'constant'}, with duration matching the rounded source span/rate. BGM can use durationPolicy:'timeline'. Nonlinear speed and multiple overlay tracks are unsupported. Caption visibility is the caption Track's hidden field. Caption style is its style map. Handle structural links explicitly when moving/deleting; there is no implicit cascade.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["stableId","isRecord","isRecord"],"sources":["../src/document/compact-projection.ts","../src/sandbox/preview.ts","../src/sandbox/node-host.ts","../src/entity/caption-asset-assembly.ts","../src/entity/entity-contract.ts","../src/entity/entity-http-client.ts","../src/entity/generation-sync.ts","../src/sandbox/generated/entity-edit-sandbox-model-context.ts","../src/prompt.ts","../src/schema.ts","../src/session/commit-plan.ts","../src/host-tool.ts","../src/entity/materialize-resources.ts"],"sourcesContent":["import {\n effectiveVideoClipDurationMs,\n solveVideoDocument,\n speedOf,\n type PartKind,\n type PartUnion,\n type SpeedShift,\n type TrackItem,\n type TrackItemTimePosition,\n type VideoClipPart,\n type VideoDocument,\n} from '@mengine/medeo-client';\n\n/**\n * Compact text projection of a `VideoDocument` for sandbox ChangePlan\n * `preview` (and pipeline dry-run preview). Pure, runtime-neutral: solves\n * via `solveVideoDocument`, emits one header line plus one row per timeline\n * item (library orphans are never rendered). Row intervals and per-kind\n * effective durations align with `toReadViewPartLibrary` /\n * `fromVideoDocument`.\n */\n\nexport interface CompactProjectionOptions {\n /** Only render these parts (header still reports the full timeline total). Default = all. */\n onlyPartIds?: ReadonlySet<string>;\n /** Caption text preview truncation length. Default 24. */\n textPreviewLength?: number;\n}\n\nconst DEFAULT_TEXT_PREVIEW_LENGTH = 24;\n\n/** Kind tag shown in the first column (`video_clip` → `clip`). */\nfunction kindTag(kind: PartKind): string {\n return kind === 'video_clip' ? 'clip' : kind;\n}\n\n/** Lane label: `video_clip` tracks display as `main`, otherwise `parts_kind`. */\nfunction laneLabel(partsKind: PartKind): string {\n return partsKind === 'video_clip' ? 'main' : partsKind;\n}\n\n/** Speed token: absent → `1`; linear → numeric multiplier; anything else → `custom`. */\nfunction speedToken(speedShift: SpeedShift | undefined): string {\n if (speedShift == null) return '1';\n if (speedShift.category === 'linear') return String(speedOf(speedShift));\n return 'custom';\n}\n\nfunction effectiveDurationMs(part: PartUnion, timelineDurationMs: number): number {\n if (part.video_clip != null) return effectiveVideoClipDurationMs(part.video_clip);\n if (part.speech != null) return part.speech.media_duration_ms ?? 0;\n if (part.caption != null) return part.caption.initial_duration_ms ?? 0;\n if (part.bgm != null) return timelineDurationMs;\n return 0;\n}\n\nfunction truncateText(text: string, budget: number): string {\n if (text.length <= budget) return text;\n return `${text.slice(0, budget)}…`;\n}\n\nfunction anchorToken(timePosition: TrackItemTimePosition): string {\n if (timePosition.mode === 'anchored') {\n return `anchor=${timePosition.anchorPartId}+${timePosition.offsetMs}`;\n }\n if (timePosition.mode === 'absolute') return 'anchor=abs';\n return 'anchor=abs';\n}\n\nfunction clipAttrs(clip: VideoClipPart): string {\n const playIn = clip.play_in ?? 0;\n const playOut = clip.play_out ?? 0;\n return `media=${clip.origin_media_id ?? ''} trim=${playIn}-${playOut} speed=${speedToken(clip.speed_shift)} vol=${clip.volume ?? 0}`;\n}\n\nfunction partAttrs(part: PartUnion, item: TrackItem, textPreviewLength: number): string {\n if (part.video_clip != null) return clipAttrs(part.video_clip);\n if (part.speech != null) {\n return `${anchorToken(item.time_position)} dur=${part.speech.media_duration_ms ?? 0}`;\n }\n if (part.caption != null) {\n const preview = truncateText(part.caption.text ?? '', textPreviewLength);\n return `${anchorToken(item.time_position)} text=\"${preview}\"`;\n }\n if (part.bgm != null) return `vol=${part.bgm.volume ?? 0}`;\n return '';\n}\n\n/**\n * Render a `VideoDocument` as compact text: one header line plus one row per\n * timeline part (optionally filtered by `onlyPartIds`). Deterministic and\n * side-effect free — same document always yields the same string.\n */\nexport function renderCompactProjection(document: VideoDocument, options?: CompactProjectionOptions): string {\n const onlyPartIds = options?.onlyPartIds;\n const textPreviewLength = options?.textPreviewLength ?? DEFAULT_TEXT_PREVIEW_LENGTH;\n\n const solved = solveVideoDocument(document);\n const library = document.part_library ?? {};\n const tracks = document.tracks ?? [];\n\n let totalParts = 0;\n const rows: string[] = [];\n\n for (const track of tracks) {\n const partsKind = track.parts_kind;\n if (partsKind == null) continue;\n const lane = laneLabel(partsKind);\n const tag = kindTag(partsKind);\n\n for (const item of track.items ?? []) {\n totalParts += 1;\n const partId = item.part_id;\n if (onlyPartIds != null && !onlyPartIds.has(partId)) continue;\n\n const part = library[partId];\n if (part == null) continue;\n\n const abs = solved.absByPartId.get(partId) ?? 0;\n const dur = effectiveDurationMs(part, solved.durationMs);\n const attrs = partAttrs(part, item, textPreviewLength);\n rows.push(`${tag} ${partId} ${lane} [${abs},${abs + dur}) ${attrs}`);\n }\n }\n\n const header = `# draft=${document.meta.draft_id ?? ''} v=${document.meta.version ?? 0} duration=${solved.durationMs} parts=${totalParts} shown=${rows.length}`;\n return [header, ...rows].join('\\n');\n}\n","import type { JournalEntry, VideoDocument } from '@mengine/medeo-client';\n\nimport { renderCompactProjection } from '../document/compact-projection.ts';\n\n/**\n * Collect part ids referenced by a journal for compact preview filtering.\n * Walks known id-shaped payload keys (宁多勿少) and unions `generated_ids`.\n */\nconst PART_ID_KEYS = new Set([\n 'clip_id',\n 'clip_ids',\n 'before_clip_id',\n 'after_clip_id',\n 'speech_id',\n 'speech_ids',\n 'speech_part_id',\n 'caption_id',\n 'caption_ids',\n 'bgm_id',\n 'anchor_part_id',\n 'part_id',\n 'body_part_id',\n]);\n\n/** Extract every part id a journal entry touches (payload refs + minted ids). */\nexport function collectAffectedPartIds(journal: readonly JournalEntry[]): Set<string> {\n const ids = new Set<string>();\n for (const entry of journal) {\n for (const generated of entry.generated_ids ?? []) {\n if (generated.length > 0) ids.add(generated);\n }\n collectFromValue(entry.payload, ids);\n }\n return ids;\n}\n\nfunction collectFromValue(value: unknown, ids: Set<string>): void {\n if (value == null) return;\n if (Array.isArray(value)) {\n for (const item of value) collectFromValue(item, ids);\n return;\n }\n if (typeof value !== 'object') return;\n for (const [key, child] of Object.entries(value as Record<string, unknown>)) {\n if (PART_ID_KEYS.has(key)) {\n if (typeof child === 'string' && child.length > 0) ids.add(child);\n else if (Array.isArray(child)) {\n for (const item of child) {\n if (typeof item === 'string' && item.length > 0) ids.add(item);\n }\n }\n }\n collectFromValue(child, ids);\n }\n}\n\n/**\n * Render a ChangePlan preview: header + rows for journal-affected parts only.\n * Empty journal → empty `onlyPartIds` (header alone), matching the T2 contract.\n */\nexport function renderPreview(document: VideoDocument, journal: readonly JournalEntry[]): string {\n const onlyPartIds = journal.length === 0 ? new Set<string>() : collectAffectedPartIds(journal);\n return renderCompactProjection(document, { onlyPartIds });\n}\n","/// <reference types=\"node\" />\nimport { Worker } from 'node:worker_threads';\n\nimport type { JournalEntry, VideoDocument } from '@mengine/medeo-client';\n\nimport type { EntityAssetContent } from '../entity/entity-asset.ts';\nimport type { SandboxEntity } from '../entity/entity-contract.ts';\nimport type { EntityCommand, EntityStoreSnapshot } from '../entity/entity-contract.ts';\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 loadEntityAsset?: (entity: SandboxEntity) => Promise<EntityAssetContent>;\n document: VideoDocument;\n baseVersion: string;\n script: string;\n inputs?: Record<string, unknown>;\n /** Authoritative entity/relation rows and revision fetched for this document. */\n entityState?: EntityStoreSnapshot;\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: {\n ops: readonly JournalEntry[];\n entityCommands: readonly EntityCommand[];\n logs: string[];\n };\n };\n\ntype WorkerMessage =\n | { t: 'entity-asset'; requestId: number; entity: SandboxEntity }\n | { t: 'ready' }\n | { t: 'entry'; entry: JournalEntry }\n | { t: 'entity-entry'; command: EntityCommand }\n | { t: 'log'; line: string }\n | { t: 'truncate'; index: number }\n | { t: 'entity-truncate'; index: number }\n | {\n t: 'done';\n preview: string;\n opsCount: number;\n entityCommandsCount: number;\n loroUpdate?: string;\n entityBaseRevision: number;\n entityRows?: EntityStoreSnapshot;\n deletedEntityIds: readonly string[];\n deletedRelationIds: readonly string[];\n planKind: 'timeline' | 'entities';\n }\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 entityCommands: EntityCommand[] = [];\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 entityState: options.entityState,\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: {\n ops: ops.slice(),\n entityCommands: entityCommands.slice(),\n logs: logs.slice(),\n },\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 === 'entity-asset') {\n void (async () => {\n try {\n if (!options.loadEntityAsset) throw new Error('Entity Asset loader is unavailable');\n const result = await options.loadEntityAsset(message.entity);\n if (!settled) worker.postMessage({ t: 'entity-asset-result', requestId: message.requestId, result });\n } catch (error) {\n if (!settled)\n worker.postMessage({\n t: 'entity-asset-result',\n requestId: message.requestId,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n })();\n return;\n }\n if (message.t === 'entry') {\n ops.push(message.entry);\n return;\n }\n if (message.t === 'entity-entry') {\n entityCommands.push(message.command);\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 === 'entity-truncate') {\n entityCommands.length = Math.max(0, Math.min(message.index, entityCommands.length));\n return;\n }\n if (message.t === 'done') {\n if (message.opsCount !== ops.length || message.entityCommandsCount !== entityCommands.length) {\n finish({\n ok: false,\n phase: 'runtime',\n error: {\n message:\n `journal count mismatch: worker reported timeline=${message.opsCount}, entities=${message.entityCommandsCount}; ` +\n `host collected timeline=${ops.length}, entities=${entityCommands.length}`,\n },\n partial: {\n ops: ops.slice(),\n entityCommands: entityCommands.slice(),\n logs: logs.slice(),\n },\n });\n return;\n }\n finish({\n ok: true,\n plan: {\n plan_kind: message.planKind,\n doc_id: options.document.meta.draft_id ?? '',\n base_version: options.baseVersion,\n ops: ops.slice(),\n ...(message.loroUpdate ? { loro_update: message.loroUpdate } : {}),\n entity_base_revision: message.entityBaseRevision,\n entity_commands: entityCommands.slice(),\n ...(message.entityRows !== undefined ? { entity_rows: message.entityRows } : {}),\n deleted_entity_ids: message.deletedEntityIds,\n deleted_relation_ids: message.deletedRelationIds,\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: {\n ops: ops.slice(),\n entityCommands: entityCommands.slice(),\n logs: logs.slice(),\n },\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: {\n ops: ops.slice(),\n entityCommands: entityCommands.slice(),\n logs: logs.slice(),\n },\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: {\n ops: ops.slice(),\n entityCommands: entityCommands.slice(),\n logs: logs.slice(),\n },\n });\n });\n });\n}\n","import { createHash } from 'node:crypto';\n\nimport type { SandboxEntity, SandboxRelation } from './entity-contract.ts';\nimport type { EntityHttpClient } from './entity-http-client.ts';\n\n/** Optional physical artifact registered for one immutable Caption identity. */\nexport interface CaptionAssetFact {\n readonly captionEntityId: string;\n readonly assetId: string;\n readonly storageKey: string;\n}\n\n/** Host-only lookup. Missing facts mean the Caption has no physical artifact. */\nexport type CaptionAssetsLoader = (\n docId: string,\n captionEntityIds: readonly string[],\n) => Promise<readonly CaptionAssetFact[]>;\n\nexport interface CaptionAssetAssemblyOutcome {\n readonly status: 'applied' | 'current' | 'failed';\n readonly message?: string;\n}\n\n/** Assemble optional infrastructure after business execution, using exact entity identity. */\nexport async function assembleCaptionAssets(input: {\n client: EntityHttpClient;\n docId: string;\n loadAssets: CaptionAssetsLoader;\n}): Promise<CaptionAssetAssemblyOutcome> {\n try {\n const state = await input.client.fetchState();\n const candidates = state.entities.filter(\n (entity) =>\n entity.entity_kind === 'caption' &&\n !state.relations.some(\n (relation) =>\n relation.relation_kind === 'physical-asset' &&\n (relation.endpoint_0_entity_id === entity.entity_id || relation.endpoint_1_entity_id === entity.entity_id),\n ),\n );\n if (!candidates.length) return { status: 'current' };\n const ids = new Set(candidates.map((entity) => entity.entity_id));\n const facts = await input.loadAssets(input.docId, [...ids]);\n const entities: SandboxEntity[] = [...state.entities];\n const relations: SandboxRelation[] = [...state.relations];\n const bound = new Map<string, string>();\n for (const fact of facts) {\n if (!ids.has(fact.captionEntityId) || !trimmed(fact.assetId) || !trimmed(fact.storageKey))\n throw new Error('Caption Asset fact must identify a requested Caption and a real Asset locator');\n const previous = bound.get(fact.captionEntityId);\n if (previous !== undefined) {\n if (previous !== fact.assetId) throw new Error(`Conflicting Assets for Caption ${fact.captionEntityId}`);\n continue;\n }\n bound.set(fact.captionEntityId, fact.assetId);\n const matches = entities.filter((entity) => {\n const external = entity.payload.external;\n return (\n external !== null &&\n typeof external === 'object' &&\n !Array.isArray(external) &&\n external.system === 'memota' &&\n external.key === fact.assetId\n );\n });\n if (matches.length > 1 || (matches[0] && matches[0].entity_kind !== 'asset'))\n throw new Error(`Conflicting resource identity for Caption Asset ${fact.assetId}`);\n let asset = matches[0];\n if (asset && asset.payload.storageKey !== fact.storageKey)\n throw new Error(`Conflicting storage key for Caption Asset ${fact.assetId}`);\n if (!asset) {\n asset = {\n entity_id: stableId('asset', fact.assetId),\n entity_kind: 'asset',\n payload: { external: { system: 'memota', key: fact.assetId }, storageKey: fact.storageKey },\n };\n if (entities.some((entity) => entity.entity_id === asset!.entity_id))\n throw new Error('Caption Asset identity collision');\n entities.push(asset);\n }\n relations.push({\n relation_id: stableId('relation', fact.captionEntityId, asset.entity_id),\n relation_kind: 'physical-asset',\n endpoint_0_entity_id: fact.captionEntityId,\n endpoint_1_entity_id: asset.entity_id,\n metadata: {},\n trace: {},\n });\n }\n if (!bound.size) return { status: 'current' };\n await input.client.commit(state.revision, { ...state, entities, relations });\n return { status: 'applied' };\n } catch (error) {\n return { status: 'failed', message: error instanceof Error ? error.message : String(error) };\n }\n}\n\nfunction stableId(prefix: string, ...parts: string[]): string {\n return `${prefix}_${createHash('sha256').update(JSON.stringify(parts)).digest('hex')}`;\n}\nfunction trimmed(value: string): boolean {\n return typeof value === 'string' && value.length > 0 && value.trim() === value;\n}\n","import type { FieldChange, MediaAssetFact } from '@mengine/medeo-client';\n\nexport type JsonPrimitive = string | number | boolean | null;\nexport type JsonValue = JsonPrimitive | JsonObject | JsonValue[];\nexport interface JsonObject {\n [key: string]: JsonValue;\n}\n\nexport type KnownEntityKind =\n | 'axvideo'\n | 'timeline'\n | 'track'\n | 'clip'\n | 'asset'\n | 'video'\n | 'audio'\n | 'voice'\n | 'image'\n | 'sequence-marker'\n | 'viewport'\n | 'audio-script'\n | 'phonetic-script'\n | 'caption';\n\n/** Asset identity, either an old physical-only row or a directly composed media variant. */\nexport type ResourceEntityKind = 'image' | 'video' | 'audio' | 'voice';\n\nexport const KNOWN_ENTITY_KINDS: readonly KnownEntityKind[] = [\n 'axvideo',\n 'timeline',\n 'track',\n 'clip',\n 'asset',\n 'video',\n 'audio',\n 'voice',\n 'image',\n 'sequence-marker',\n 'viewport',\n 'audio-script',\n 'phonetic-script',\n 'caption',\n];\n\nexport type KnownRelationKind =\n | 'timeline-track'\n | 'track-clip'\n | 'clip-marker'\n | 'marker-content'\n | 'axvideo-marker'\n | 'marker-timeline'\n | 'physical-asset'\n | 'generated'\n | 'caption-alignment'\n | 'clip-anchor'\n | 'phonetic-script-render'\n | 'audio-script-source'\n | 'audio-script-marker';\n\nexport const KNOWN_RELATION_KINDS: readonly KnownRelationKind[] = [\n 'timeline-track',\n 'track-clip',\n 'clip-marker',\n 'marker-content',\n 'axvideo-marker',\n 'marker-timeline',\n 'physical-asset',\n 'generated',\n 'caption-alignment',\n 'clip-anchor',\n 'phonetic-script-render',\n 'audio-script-source',\n 'audio-script-marker',\n];\n\nexport type AuthorableRelationKind = KnownRelationKind;\n\nexport interface BoundedNativeSequencePayload extends JsonObject {\n /** Factual coordinates from recalled media metadata; never invent an end/duration. */\n extent: { kind: 'bounded'; start: number; end: number };\n sampling: 'native';\n coordinateSpace: JsonValue;\n}\n\nexport interface UnboundedConstantSequencePayload extends JsonObject {\n extent: { kind: 'unbounded'; start: number };\n sampling: 'constant';\n coordinateSpace: JsonValue;\n}\n\nexport interface BoundedDerivedSequencePayload extends JsonObject {\n extent: { kind: 'bounded'; start: number; end: number };\n sampling: 'derived';\n coordinateSpace: JsonValue;\n}\n\nexport type ScriptTextSegment = JsonObject & {\n segmentId: string;\n text: string;\n language?: string;\n};\n\nexport type MediaAssetPayload = JsonObject & {\n external: { system: 'memota' | 'memota-speech'; key: string };\n storageKey?: string;\n};\n\nexport type CaptionTextSelection = JsonObject & {\n segmentId: string;\n /** Half-open Unicode code-point range within the selected source segment. */\n textRange?: { start: number; end: number };\n};\n\n/** Read result only: base text is assembled from the real AudioScript row. */\nexport interface ComposedScriptContent {\n audio_script_entity_id: string;\n text: string;\n segments: ScriptTextSegment[];\n}\n\nexport interface ComposedPhoneticContent extends ComposedScriptContent {\n phonemeScript?: string;\n prosody?: JsonObject;\n}\n\nexport interface EntityPayloadByKind {\n axvideo: BoundedDerivedSequencePayload;\n timeline: JsonObject;\n track: JsonObject & { hidden?: boolean; role?: string };\n clip: JsonObject;\n /** Physical resource fields; never a copy of Caption content. */\n asset: JsonObject;\n video: BoundedNativeSequencePayload & MediaAssetPayload;\n audio: BoundedNativeSequencePayload & MediaAssetPayload;\n voice: BoundedNativeSequencePayload & MediaAssetPayload;\n image: UnboundedConstantSequencePayload & MediaAssetPayload;\n 'sequence-marker': JsonObject & {\n sourceRange: { start: number; end: number };\n targetRange?: { start: number; end: number };\n duration: { mode: 'from-source' } | { mode: 'fixed'; value: number };\n timeRemapping?: JsonValue;\n anchorOffset?: number;\n durationPolicy?: 'timeline';\n /** Directly assigned AudioScript annotation times; annotation Markers only. */\n segmentRanges?: { segmentId: string; startMs: number; endMs: number }[];\n };\n viewport: JsonObject;\n 'audio-script': JsonObject & { segments: ScriptTextSegment[] };\n 'phonetic-script': JsonObject & { baseEntityIds: string[]; phonemeScript?: string; prosody?: JsonObject };\n caption: BoundedNativeSequencePayload & {\n baseEntityIds: string[];\n selection: CaptionTextSelection;\n style?: JsonObject;\n segmentRanges?: { segmentId: string; startMs: number; endMs: number }[];\n };\n}\n\n/** Stored own fields; a variant may obtain required content fields from its declared bases. */\nexport type StoredEntityPayload<K extends KnownEntityKind> =\n | EntityPayloadByKind[K]\n | (K extends 'caption' ? JsonObject & Pick<MediaAssetPayload, 'external'> : never)\n | (JsonObject & Partial<EntityPayloadByKind[K]> & { baseEntityIds: string[] });\n\nexport interface SandboxEntity<K extends KnownEntityKind = KnownEntityKind> {\n entity_id: string;\n entity_kind: K;\n payload: StoredEntityPayload<K>;\n}\n\nexport interface SandboxRelation {\n relation_id: string;\n relation_kind: KnownRelationKind;\n endpoint_0_entity_id: string;\n endpoint_1_entity_id: string;\n metadata: JsonObject;\n trace: JsonObject;\n}\n\nexport interface EntityStoreSnapshot {\n /** Causal compiler baseline; required for publishing edits. */\n loroSnapshot?: string;\n revision: number;\n /** Current AudioScript version attached to the project; initialized projects always attach a script, possibly empty. */\n audioScriptEntityId: string | null;\n entities: SandboxEntity[];\n relations: SandboxRelation[];\n}\n\nexport type CreateEntityInput = {\n [K in KnownEntityKind]: {\n entity_id?: string;\n entity_kind: K;\n payload: StoredEntityPayload<K>;\n };\n}[KnownEntityKind];\n\n/** Patch supplied fields on the assembled entity; omitted fields remain unchanged. */\nexport interface UpdateEntityInput {\n entity_id: string;\n payload: JsonObject;\n}\n\nexport interface DeleteEntityInput {\n entity_id: string;\n}\n\nexport type EmptyRelationKind =\n | 'timeline-track'\n | 'track-clip'\n | 'clip-marker'\n | 'marker-content'\n | 'axvideo-marker'\n | 'marker-timeline'\n | 'audio-script-marker';\n\ninterface LinkRelationBase {\n relation_id?: string;\n endpoint_0_entity_id: string;\n endpoint_1_entity_id: string;\n trace?: JsonObject;\n}\n\nexport interface LinkRelationInput extends LinkRelationBase {\n relation_kind: KnownRelationKind;\n metadata?: JsonObject;\n}\nexport interface EntityUpdateInput {\n entity_id: string;\n changes: FieldChange[];\n}\nexport interface RelationUpdateInput {\n relation_id: string;\n changes: FieldChange[];\n}\n/** Tokens have no script-authored data; only the creating session can validate them. */\nexport interface EntitySandboxCheckpoint {\n readonly __checkpoint: unique symbol;\n}\n\nexport interface LinkGeneratedRelationInput {\n relation_id?: string;\n output_entity_id: string;\n input_entity_id: string;\n trace?: JsonObject;\n}\n\nexport interface LinkClipAnchorRelationInput {\n relation_id?: string;\n child_clip_entity_id: string;\n host_clip_entity_id: string;\n trace?: JsonObject;\n}\n\nexport interface LinkPhoneticScriptRenderRelationInput {\n relation_id?: string;\n output_entity_id: string;\n phonetic_script_entity_id: string;\n trace?: JsonObject;\n}\n\n/** `audio-script-source(script, source)`; the script was transcribed from the source media. */\nexport interface LinkAudioScriptSourceRelationInput {\n relation_id?: string;\n script_entity_id: string;\n source_entity_id: string;\n trace?: JsonObject;\n}\n\nexport interface UnlinkRelationInput {\n relation_id: string;\n}\n\nexport type EntityCommand =\n | { kind: 'create-entity'; entity: SandboxEntity }\n | { kind: 'update-entity'; entity_id: string; payload: JsonObject }\n | { kind: 'change-entity'; entity_id: string; changes: FieldChange[] }\n | { kind: 'change-relation'; relation_id: string; changes: FieldChange[] }\n | { kind: 'delete-entity'; entity_id: string }\n | { kind: 'link-relation'; relation: SandboxRelation }\n | { kind: 'unlink-relation'; relation_id: string };\n\nexport interface EntityPlanState {\n base_revision: number;\n commands: readonly EntityCommand[];\n rows: EntityStoreSnapshot;\n deleted_entity_ids: readonly string[];\n deleted_relation_ids: readonly string[];\n}\n\nexport interface EntityStateWireResponse {\n loro_snapshot: string;\n doc_id: string;\n audio_script_entity_id: string | null;\n revision: number;\n rows: {\n entities: SandboxEntity[];\n relations: SandboxRelation[];\n };\n}\n\nexport interface EntityFacade {\n /** Read complete assembled fields; returned objects are snapshots. Use update to persist edits. */\n list(): SandboxEntity[];\n get(entityId: string): SandboxEntity | null;\n /** Find document resources by external Memota asset id, including directly composed media variants. */\n findByAssetId(assetId: string): SandboxEntity<ResourceEntityKind>[];\n /** Assemble selected Caption text; missing composition is an error. */\n readCaptionContent(entityId: string): ComposedScriptContent;\n /** Assemble base text and pronunciation fields before generating Voice. */\n readPhoneticScriptContent(entityId: string): ComposedPhoneticContent;\n create(input: CreateEntityInput): string;\n /** Patch assembled fields, routing inherited fields to their declaring entity. */\n update(input: UpdateEntityInput): void;\n changeFields(input: EntityUpdateInput): void;\n /** Explicitly declare own fields, overriding unambiguous bases without modifying them. Ordinary edits use update. */\n declareFields(input: UpdateEntityInput): void;\n /** Delete an Entity only after all of its incident Relations have been explicitly unlinked. */\n delete(input: DeleteEntityInput): void;\n /** Get or create one typed Asset by factual external id and return its single content identity. Never creates a Clip. */\n ensureMedia(fact: MediaAssetFact): { contentEntityId: string };\n}\n\nexport interface RelationFacade {\n list(): SandboxRelation[];\n /** Incident lookup is endpoint-agnostic; persisted endpoint positions stay unchanged. */\n of(entityId: string, relationKind?: KnownRelationKind): SandboxRelation[];\n /** Link existing entities through ordinary associations; variant bases are stored directly on the variant. */\n link(input: LinkRelationInput): string;\n /** Author ordered generated(output,input); generic link() deliberately rejects this kind. */\n linkGenerated(input: LinkGeneratedRelationInput): string;\n /** Author ordered clip-anchor(child,host) without positional endpoint ambiguity. */\n linkClipAnchor(input: LinkClipAnchorRelationInput): string;\n /** Author ordered phonetic-script-render(output,script) without positional endpoint ambiguity. */\n linkPhoneticScriptRender(input: LinkPhoneticScriptRenderRelationInput): string;\n /** Author ordered audio-script-source(script,source) without positional endpoint ambiguity. */\n linkAudioScriptSource(input: LinkAudioScriptSourceRelationInput): string;\n /** Remove a Relation by identity; endpoint replacement is an explicit unlink plus link. */\n unlink(input: UnlinkRelationInput): void;\n update(input: RelationUpdateInput): void;\n}\n\n/** Business editing surface. Reads are assembled snapshots; writes preserve native operation intent. */\nexport interface BusinessEntityFacade {\n list(): SandboxEntity[];\n get(entityId: string): SandboxEntity | null;\n create(input: Exclude<CreateEntityInput, { entity_kind: 'asset' }>): string;\n update(input: EntityUpdateInput): void;\n declareFields(input: UpdateEntityInput): void;\n delete(input: DeleteEntityInput): void;\n}\n\n/** Endpoint order is retained; each relation kind defines its endpoint semantics. */\nexport interface BusinessRelationFacade {\n list(): SandboxRelation[];\n of(entityId: string, relationKind?: KnownRelationKind): SandboxRelation[];\n link(input: LinkRelationInput): string;\n update(input: RelationUpdateInput): void;\n unlink(input: UnlinkRelationInput): void;\n}\n","import { bytesToBase64, compileEntityRows, base64ToBytes } from '@mengine/medeo-client';\nimport { createEntityId, createRelationId } from '@mengine/medeo-dsl';\n\nimport {\n KNOWN_ENTITY_KINDS,\n KNOWN_RELATION_KINDS,\n type EntityStateWireResponse,\n type EntityStoreSnapshot,\n type JsonObject,\n type SandboxEntity,\n type SandboxRelation,\n} from './entity-contract.ts';\n\nconst API_PREFIX = '/api/mengine/v1';\nconst entityKinds = new Set<string>(KNOWN_ENTITY_KINDS);\nconst relationKinds = new Set<string>(KNOWN_RELATION_KINDS);\n\nexport interface EntityHttpClientOptions {\n docId: string;\n httpOrigin: string;\n authToken?: string | (() => string | undefined);\n userId?: string | (() => string | undefined);\n fetchImpl?: typeof fetch;\n}\n\nexport interface EntityCommitDeletions {\n deleted_entity_ids?: readonly string[];\n deleted_relation_ids?: readonly string[];\n}\n\nexport class MengineEntityHttpRequestError extends Error {\n constructor(\n readonly status: number,\n readonly payload: unknown,\n ) {\n super(`mengine entity-state request failed: ${status}`);\n this.name = 'MengineEntityHttpRequestError';\n }\n}\n\n/** Narrow authenticated client for the Loro entity endpoint. */\nexport class EntityHttpClient {\n private readonly fetchImpl: typeof fetch;\n\n constructor(private readonly options: EntityHttpClientOptions) {\n this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);\n }\n\n async fetchState(): Promise<EntityStoreSnapshot> {\n return toSnapshot(await this.requestJson({ method: 'GET' }), this.options.docId);\n }\n\n async commit(\n _transportSequence: number,\n state: EntityStoreSnapshot,\n _deletions: EntityCommitDeletions = {},\n ): Promise<EntityStoreSnapshot> {\n if (!state.loroSnapshot) throw new Error('Entity edit is missing its causal Loro baseline');\n // The baseline comes from this plan, never a freshly fetched replacement.\n const rows = {\n entities: state.entities.map((row) => ({\n entityId: createEntityId(row.entity_id),\n entityKind: row.entity_kind,\n payload: row.payload,\n })),\n relations: state.relations.map((row) => ({\n relationId: createRelationId(row.relation_id),\n relationKind: row.relation_kind,\n endpoint0EntityId: createEntityId(row.endpoint_0_entity_id),\n endpoint1EntityId: createEntityId(row.endpoint_1_entity_id),\n metadata: row.metadata,\n trace: row.trace,\n })),\n } as Parameters<typeof compileEntityRows>[1];\n const compiled = compileEntityRows(base64ToBytes(state.loroSnapshot), rows);\n return this.commitUpdate(bytesToBase64(compiled.update));\n }\n\n async commitUpdate(update: string): Promise<EntityStoreSnapshot> {\n return toSnapshot(await this.requestJson({ method: 'POST', body: JSON.stringify({ update }) }), this.options.docId);\n }\n\n private async requestJson(init: RequestInit): Promise<unknown> {\n const response = await this.fetchImpl(this.endpoint(), { ...init, headers: this.headers() });\n const payload = await safeReadJson(response);\n if (!response.ok) throw new MengineEntityHttpRequestError(response.status, payload);\n return payload;\n }\n\n private headers(): Headers {\n const headers = new Headers({ accept: 'application/json', 'content-type': 'application/json' });\n const authToken = typeof this.options.authToken === 'function' ? this.options.authToken() : this.options.authToken;\n if (authToken != null && authToken !== '') headers.set('authorization', `Bearer ${authToken}`);\n const userId = typeof this.options.userId === 'function' ? this.options.userId() : this.options.userId;\n if (userId != null && userId !== '') headers.set('medeo-user-id', userId);\n return headers;\n }\n\n private endpoint(): string {\n const origin = this.options.httpOrigin.replace(/\\/$/, '');\n return `${origin}${API_PREFIX}/docs/${encodeURIComponent(this.options.docId)}/entity-state`;\n }\n}\n\nfunction toSnapshot(value: unknown, expectedDocId: string): EntityStoreSnapshot {\n if (!isRecord(value) || typeof value.doc_id !== 'string' || !isNonNegativeInteger(value.revision)) {\n throw new Error('invalid entity-state response envelope');\n }\n if (value.doc_id !== expectedDocId) {\n throw new Error(`entity-state response doc_id mismatch: expected \"${expectedDocId}\"`);\n }\n if (!isRecord(value.rows) || !Array.isArray(value.rows.entities) || !Array.isArray(value.rows.relations)) {\n throw new Error('invalid entity-state response rows');\n }\n if (value.audio_script_entity_id === null) throw new Error('Document AudioScript is not initialized');\n if (!isTrimmed(value.audio_script_entity_id)) throw new Error('invalid document AudioScript identity');\n if (typeof value.loro_snapshot !== 'string') throw new Error('Missing causal Loro snapshot');\n const response = value as unknown as EntityStateWireResponse;\n if (\n response.audio_script_entity_id !== null &&\n !response.rows.entities.some(\n (entity) => entity.entity_id === response.audio_script_entity_id && entity.entity_kind === 'audio-script',\n )\n )\n throw new Error('Document AudioScript must name the project AudioScript');\n return {\n loroSnapshot: response.loro_snapshot,\n revision: response.revision,\n audioScriptEntityId: response.audio_script_entity_id,\n entities: response.rows.entities.map(parseEntity),\n relations: response.rows.relations.map(parseRelation),\n };\n}\n\nfunction parseEntity(value: unknown): SandboxEntity {\n if (\n !isRecord(value) ||\n !isTrimmed(value.entity_id) ||\n typeof value.entity_kind !== 'string' ||\n !entityKinds.has(value.entity_kind) ||\n !isJsonObject(value.payload)\n ) {\n throw new Error('invalid Entity row in entity-state response');\n }\n return structuredClone(value) as unknown as SandboxEntity;\n}\n\nfunction parseRelation(value: unknown): SandboxRelation {\n if (\n !isRecord(value) ||\n !isTrimmed(value.relation_id) ||\n typeof value.relation_kind !== 'string' ||\n !relationKinds.has(value.relation_kind) ||\n !isTrimmed(value.endpoint_0_entity_id) ||\n !isTrimmed(value.endpoint_1_entity_id) ||\n !isJsonObject(value.metadata) ||\n !isJsonObject(value.trace)\n ) {\n throw new Error('invalid Relation row in entity-state response');\n }\n return structuredClone(value) as unknown as SandboxRelation;\n}\n\nfunction isJsonObject(value: unknown): value is JsonObject {\n return isJsonValue(value, new Set()) && isRecord(value);\n}\n\nfunction isJsonValue(value: unknown, ancestors: Set<object>): boolean {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return true;\n if (typeof value === 'number') return Number.isFinite(value);\n if (typeof value !== 'object' || ancestors.has(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) return false;\n ancestors.add(value);\n const valid = Array.isArray(value)\n ? value.every((item) => isJsonValue(item, ancestors))\n : Object.values(value).every((item) => isJsonValue(item, ancestors));\n ancestors.delete(value);\n return valid;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction isTrimmed(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0 && value.trim() === value;\n}\n\nfunction isNonNegativeInteger(value: unknown): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;\n}\n\nasync function safeReadJson(response: Response): Promise<unknown> {\n const text = await response.text();\n if (text.length === 0) return null;\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { isMediaAssetVariantKind } from '@mengine/medeo-dsl';\n\nimport type { EntityCommand, EntityStoreSnapshot, SandboxRelation } from './entity-contract.ts';\nimport type { EntityHttpClient } from './entity-http-client.ts';\n\n/**\n * External systems whose asset entities carry a factual Memota identity.\n * Voice results use the speech system; every other medium uses `memota`.\n */\nconst ASSET_SYSTEMS: ReadonlySet<string> = new Set(['memota', 'memota-speech']);\n\n/** Factual generation lineage for recalled Memota assets, supplied by the host. */\nexport interface AssetGenerationFact {\n /** External asset id of the generation output (memota asset or speech result id). */\n readonly outputAssetId: string;\n /** Factual input asset ids; empty for text-only generation. */\n readonly inputAssetIds: readonly string[];\n}\n\n/**\n * Host callback resolving lineage by external asset id. Implementations return\n * every known generation record involving the given ids in either role; an\n * empty array means no known lineage and a rejection means the lineage query\n * failed. Entity and Relation semantics stay inside this package.\n */\nexport type GenerationFactsLoader = (\n docId: string,\n assetIds: readonly string[],\n) => Promise<readonly AssetGenerationFact[]>;\n\n/**\n * Outcome of the post-commit lineage sync. `failed` is always also surfaced as\n * a `generation_sync_failed` warning so an unavailable lineage query is never\n * presented as synced state.\n */\nexport interface GenerationSyncOutcome {\n /**\n * applied: new generated Relations were committed.\n * current: the query succeeded and nothing was missing (no created asset,\n * single side absent, text-only generation, or pair already linked).\n * failed: the host query or the sync commit failed.\n */\n readonly status: 'applied' | 'current' | 'failed';\n readonly created_relation_ids?: readonly string[];\n readonly message?: string;\n}\n\nexport interface SyncGeneratedRelationsInput {\n readonly client: EntityHttpClient;\n readonly docId: string;\n /** Causal entity state the committed plan was based on. */\n readonly baseState: EntityStoreSnapshot;\n /** Entity commands of the committed plan; they scope which lineage is queried. */\n readonly entityCommands: readonly EntityCommand[];\n readonly loadFacts: GenerationFactsLoader;\n}\n\n/** Validate host-supplied facts; a malformed record fails the whole query. */\nexport function parseGenerationFacts(value: unknown): AssetGenerationFact[] {\n if (!Array.isArray(value)) throw new Error('generation facts must be an array');\n return value.map((item): AssetGenerationFact => {\n if (!isRecord(item)) throw new Error('each generation fact must be an object');\n const { outputAssetId, inputAssetIds } = item;\n if (typeof outputAssetId !== 'string' || outputAssetId.length === 0 || outputAssetId.trim() !== outputAssetId) {\n throw new Error('generation fact outputAssetId must be a non-empty trimmed string');\n }\n if (!Array.isArray(inputAssetIds)) {\n // A missing field is a malformed record, not text-only evidence: only an\n // explicit empty array states \"no factual inputs\" (pure text source).\n throw new Error('generation fact inputAssetIds must be an array (explicit [] means text-only)');\n }\n const inputs = inputAssetIds;\n for (const input of inputs) {\n if (typeof input !== 'string' || input.length === 0 || input.trim() !== input) {\n throw new Error('generation fact inputAssetIds entries must be non-empty trimmed strings');\n }\n }\n return { outputAssetId, inputAssetIds: [...inputs] };\n });\n}\n\n/**\n * Resource identities newly introduced by the edit. Asset identity is immutable;\n * Clip placement and display metadata updates are not new generation sources.\n * Untouched/deleted lineage is never resurrected.\n */\nexport interface GenerationSyncScope {\n readonly scopedMediaIds: ReadonlySet<string>;\n readonly queryAssetKeys: readonly string[];\n}\n\nexport function planGenerationScope(\n base: EntityStoreSnapshot,\n commands: readonly EntityCommand[],\n state: EntityStoreSnapshot,\n): GenerationSyncScope {\n const touchedIds = new Set<string>();\n for (const command of commands) {\n if (command.kind === 'create-entity' && isMediaAssetVariantKind(command.entity.entity_kind)) {\n touchedIds.add(command.entity.entity_id);\n }\n }\n const beforeByKey = resolveMediaByAssetKey(base);\n const scoped = new Set<string>();\n const queryKeys = new Set<string>();\n for (const [key, mediaIds] of resolveMediaByAssetKey(state)) {\n const previousIds = new Set(beforeByKey.get(key) ?? []);\n for (const id of mediaIds) {\n if (!touchedIds.has(id) || previousIds.has(id)) continue;\n scoped.add(id);\n queryKeys.add(key);\n }\n }\n return { scopedMediaIds: scoped, queryAssetKeys: [...queryKeys].sort() };\n}\n\n/**\n * Ordered generated(output,input) Relations missing from `state` for the given\n * factual records. Both endpoints must already exist and match their own Asset\n * identities, and the pair must involve a media Entity the plan\n * newly fact-exposed (`scopedMediaIds`): lineage scopes to the commit's diff,\n * so a pair the user deleted between untouched entities stays deleted. A pair\n * the facts already resolved against the plan's base state is likewise skipped.\n * One-sided facts, text-only records, self pairs, and already-linked pairs are\n * skipped. Duplicate records collapse to one Relation.\n */\nexport function planGeneratedRelations(input: {\n baseState: EntityStoreSnapshot;\n state: EntityStoreSnapshot;\n scopedMediaIds: ReadonlySet<string>;\n facts: readonly AssetGenerationFact[];\n newRelationId: () => string;\n}): SandboxRelation[] {\n const { state, facts } = input;\n const scoped = input.scopedMediaIds;\n const factKeys = new Set(facts.flatMap((fact) => [fact.outputAssetId, ...fact.inputAssetIds]));\n const mediaByAssetKey = resolveMediaByAssetKey(state, factKeys);\n const baseResolvable = new Set(resolvablePairs(resolveMediaByAssetKey(input.baseState, factKeys), facts));\n const linkedPairs = new Set(\n state.relations\n .filter((relation) => relation.relation_kind === 'generated')\n .map((relation) => pairKey(relation.endpoint_0_entity_id, relation.endpoint_1_entity_id)),\n );\n const relations: SandboxRelation[] = [];\n for (const fact of facts) {\n for (const outputId of mediaByAssetKey.get(fact.outputAssetId) ?? []) {\n for (const inputAssetId of fact.inputAssetIds) {\n for (const inputId of mediaByAssetKey.get(inputAssetId) ?? []) {\n if (outputId === inputId) continue;\n if (!scoped.has(outputId) && !scoped.has(inputId)) continue;\n const pair = pairKey(outputId, inputId);\n if (linkedPairs.has(pair) || baseResolvable.has(pair)) continue;\n linkedPairs.add(pair);\n relations.push({\n relation_id: input.newRelationId(),\n relation_kind: 'generated',\n endpoint_0_entity_id: outputId,\n endpoint_1_entity_id: inputId,\n metadata: {},\n trace: { synced_by: 'generation-sync' },\n });\n }\n }\n }\n }\n return relations;\n}\n\n/**\n * Sync generation lineage after a confirmed entity commit. Any failure is\n * returned as a `failed` outcome instead of thrown, so the already-durable\n * commit result is never masked; a successful query that finds nothing is\n * `current`. Asset identities are immutable, so facts are queried once. The native update retains its causal baseline and merges without whole-state retries; deleted endpoints are never recreated.\n */\nexport async function syncGeneratedRelations(input: SyncGeneratedRelationsInput): Promise<GenerationSyncOutcome> {\n const { client, docId, baseState, entityCommands, loadFacts } = input;\n try {\n const state = await client.fetchState();\n const scope = planGenerationScope(baseState, entityCommands, state);\n if (scope.queryAssetKeys.length === 0) return { status: 'current' };\n const facts = parseGenerationFacts(await loadFacts(docId, scope.queryAssetKeys));\n const relations = planGeneratedRelations({\n baseState,\n state,\n scopedMediaIds: scope.scopedMediaIds,\n facts,\n newRelationId: mintRelationId,\n });\n if (relations.length === 0) return { status: 'current' };\n const committed = await client.commit(state.revision, { ...state, relations: [...state.relations, ...relations] });\n const active = new Set(committed.relations.map((relation) => relation.relation_id));\n const created = relations.map((relation) => relation.relation_id).filter((id) => active.has(id));\n return created.length ? { status: 'applied', created_relation_ids: created } : { status: 'current' };\n } catch (error) {\n return { status: 'failed', message: `generation lineage query failed: ${errorMessage(error)}` };\n }\n}\n\ninterface AssetLike {\n entity_id: string;\n entity_kind: string;\n payload: unknown;\n}\n\nfunction assetKeyOf(entity: AssetLike): string | undefined {\n if (!isMediaAssetVariantKind(entity.entity_kind)) return undefined;\n const external = (entity.payload as Record<string, unknown> | undefined)?.external;\n if (external == null || typeof external !== 'object' || Array.isArray(external)) return undefined;\n const { system, key } = external as Record<string, unknown>;\n if (typeof system !== 'string' || !ASSET_SYSTEMS.has(system)) return undefined;\n if (typeof key !== 'string' || key.length === 0 || key.trim() !== key) return undefined;\n return key;\n}\n\n/** Media variants own their Asset locator; generation lookup never follows Relations. */\nfunction resolveMediaByAssetKey(state: EntityStoreSnapshot, factKeys?: ReadonlySet<string>): Map<string, string[]> {\n // The host history contract carries bare IDs, not namespaces. Never turn an\n // ambiguous ID into a Cartesian product of unrelated speech/media resources.\n const systemByKey = new Map<string, unknown>();\n for (const entity of state.entities) {\n const key = assetKeyOf(entity);\n if (key === undefined || !factKeys?.has(key)) continue;\n const system = (entity.payload.external as Record<string, unknown>).system;\n if (systemByKey.has(key) && systemByKey.get(key) !== system)\n throw new Error(`Ambiguous generation asset id ${key} across media and speech namespaces`);\n systemByKey.set(key, system);\n }\n const resolved = new Map<string, string[]>();\n for (const entity of state.entities) {\n if (!isMediaAssetVariantKind(entity.entity_kind)) continue;\n const key = assetKeyOf(entity);\n if (key === undefined) continue;\n const matches = resolved.get(key) ?? [];\n matches.push(entity.entity_id);\n resolved.set(key, matches);\n }\n return resolved;\n}\n\nfunction pairKey(endpoint0: string, endpoint1: string): string {\n return `${endpoint0}\\u0000${endpoint1}`;\n}\n\n/** Pair keys the facts already resolve to under the given base bindings. */\nfunction resolvablePairs(mediaByAssetKey: Map<string, string[]>, facts: readonly AssetGenerationFact[]): string[] {\n const pairs: string[] = [];\n for (const fact of facts) {\n for (const outputId of mediaByAssetKey.get(fact.outputAssetId) ?? []) {\n for (const inputAssetId of fact.inputAssetIds) {\n for (const inputId of mediaByAssetKey.get(inputAssetId) ?? []) {\n if (outputId !== inputId) pairs.push(pairKey(outputId, inputId));\n }\n }\n }\n }\n return pairs;\n}\n\nfunction mintRelationId(): string {\n return `relation_${randomUUID()}`;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n","/** @generated by gen:sandbox-dts. DO NOT EDIT. */\nexport const ENTITY_EDIT_SANDBOX_API_DTS = [\n '/** @generated by gen:sandbox-dts. Entity-native editor contract; DO NOT EDIT. */',\n 'export interface BoundedDerivedSequencePayload extends JsonObject {',\n ' extent: {',\n \" kind: 'bounded';\",\n ' start: number;',\n ' end: number;',\n ' };',\n \" sampling: 'derived';\",\n ' coordinateSpace: JsonValue;',\n '}',\n 'export interface BoundedNativeSequencePayload extends JsonObject {',\n ' /** Factual coordinates from recalled media metadata; never invent an end/duration. */',\n ' extent: {',\n \" kind: 'bounded';\",\n ' start: number;',\n ' end: number;',\n ' };',\n \" sampling: 'native';\",\n ' coordinateSpace: JsonValue;',\n '}',\n '/** Business editing surface. Reads are assembled snapshots; writes preserve native operation intent. */',\n 'export interface BusinessEntityFacade {',\n ' list(): SandboxEntity[];',\n ' get(entityId: string): SandboxEntity | null;',\n ' create(',\n ' input: Exclude<',\n ' CreateEntityInput,',\n ' {',\n \" entity_kind: 'asset';\",\n ' }',\n ' >,',\n ' ): string;',\n ' update(input: EntityUpdateInput): void;',\n ' declareFields(input: UpdateEntityInput): void;',\n ' delete(input: DeleteEntityInput): void;',\n '}',\n '/** Endpoint order is retained; each relation kind defines its endpoint semantics. */',\n 'export interface BusinessRelationFacade {',\n ' list(): SandboxRelation[];',\n ' of(entityId: string, relationKind?: KnownRelationKind): SandboxRelation[];',\n ' link(input: LinkRelationInput): string;',\n ' update(input: RelationUpdateInput): void;',\n ' unlink(input: UnlinkRelationInput): void;',\n '}',\n 'export type CaptionTextSelection = JsonObject & {',\n ' segmentId: string;',\n ' /** Half-open Unicode code-point range within the selected source segment. */',\n ' textRange?: {',\n ' start: number;',\n ' end: number;',\n ' };',\n '};',\n 'export type CreateEntityInput = {',\n ' [K in KnownEntityKind]: {',\n ' entity_id?: string;',\n ' entity_kind: K;',\n ' payload: StoredEntityPayload<K>;',\n ' };',\n '}[KnownEntityKind];',\n 'export interface DeleteEntityInput {',\n ' entity_id: string;',\n '}',\n '/** Immutable resource content resolved by the host for a document Entity. */',\n 'export interface EntityAssetContent {',\n ' assetId: string;',\n ' content: JsonValue;',\n '}',\n 'export interface EntityPayloadByKind {',\n ' axvideo: BoundedDerivedSequencePayload;',\n ' timeline: JsonObject;',\n ' track: JsonObject & {',\n ' hidden?: boolean;',\n ' role?: string;',\n ' };',\n ' clip: JsonObject;',\n ' video: BoundedNativeSequencePayload & MediaAssetPayload;',\n ' audio: BoundedNativeSequencePayload & MediaAssetPayload;',\n ' voice: BoundedNativeSequencePayload & MediaAssetPayload;',\n ' image: UnboundedConstantSequencePayload & MediaAssetPayload;',\n \" 'sequence-marker': JsonObject & {\",\n ' sourceRange: {',\n ' start: number;',\n ' end: number;',\n ' };',\n ' targetRange?: {',\n ' start: number;',\n ' end: number;',\n ' };',\n ' duration:',\n ' | {',\n \" mode: 'from-source';\",\n ' }',\n ' | {',\n \" mode: 'fixed';\",\n ' value: number;',\n ' };',\n ' timeRemapping?: JsonValue;',\n ' anchorOffset?: number;',\n \" durationPolicy?: 'timeline';\",\n ' /** Directly assigned AudioScript annotation times; annotation Markers only. */',\n ' segmentRanges?: {',\n ' segmentId: string;',\n ' startMs: number;',\n ' endMs: number;',\n ' }[];',\n ' };',\n ' viewport: JsonObject;',\n \" 'audio-script': JsonObject & {\",\n ' segments: ScriptTextSegment[];',\n ' };',\n \" 'phonetic-script': JsonObject & {\",\n ' baseEntityIds: string[];',\n ' phonemeScript?: string;',\n ' prosody?: JsonObject;',\n ' };',\n ' caption: BoundedNativeSequencePayload & {',\n ' baseEntityIds: string[];',\n ' selection: CaptionTextSelection;',\n ' style?: JsonObject;',\n ' segmentRanges?: {',\n ' segmentId: string;',\n ' startMs: number;',\n ' endMs: number;',\n ' }[];',\n ' };',\n '}',\n '/** Tokens have no script-authored data; only the creating session can validate them. */',\n 'export interface EntitySandboxCheckpoint {',\n ' readonly __checkpoint: unique symbol;',\n '}',\n 'export interface EntityUpdateInput {',\n ' entity_id: string;',\n ' changes: FieldChange[];',\n '}',\n 'export type FieldChange =',\n ' | {',\n \" op: 'set';\",\n ' path: FieldPath;',\n ' value: JsonValue;',\n ' }',\n ' | {',\n \" op: 'unset';\",\n ' path: FieldPath;',\n ' }',\n ' | {',\n \" op: 'text.splice';\",\n ' path: FieldPath;',\n ' index: number;',\n ' deleteCount: number;',\n ' text: string;',\n ' }',\n ' | {',\n \" op: 'list.insert';\",\n ' path: FieldPath;',\n ' value: JsonValue;',\n ' beforeElementId: string | null;',\n ' }',\n ' | {',\n \" op: 'list.move';\",\n ' path: FieldPath;',\n ' elementId: string;',\n ' beforeElementId: string | null;',\n ' }',\n ' | {',\n \" op: 'list.remove';\",\n ' path: FieldPath;',\n ' elementId: string;',\n ' };',\n '/** List members are addressed by identity, never a transient array offset. */',\n 'export type FieldPath = readonly (',\n ' | string',\n ' | {',\n ' elementId: string;',\n ' }',\n ')[];',\n 'export interface JsonObject {',\n ' [key: string]: JsonValue;',\n '}',\n 'export type JsonPrimitive = string | number | boolean | null;',\n 'export type JsonValue = JsonPrimitive | JsonObject | JsonValue[];',\n 'export type KnownEntityKind =',\n \" | 'axvideo'\",\n \" | 'timeline'\",\n \" | 'track'\",\n \" | 'clip'\",\n \" | 'video'\",\n \" | 'audio'\",\n \" | 'voice'\",\n \" | 'image'\",\n \" | 'sequence-marker'\",\n \" | 'viewport'\",\n \" | 'audio-script'\",\n \" | 'phonetic-script'\",\n \" | 'caption';\",\n 'export type KnownRelationKind =',\n \" | 'timeline-track'\",\n \" | 'track-clip'\",\n \" | 'clip-marker'\",\n \" | 'marker-content'\",\n \" | 'axvideo-marker'\",\n \" | 'marker-timeline'\",\n \" | 'generated'\",\n \" | 'caption-alignment'\",\n \" | 'clip-anchor'\",\n \" | 'phonetic-script-render'\",\n \" | 'audio-script-source'\",\n \" | 'audio-script-marker';\",\n 'interface LinkRelationBase {',\n ' relation_id?: string;',\n ' endpoint_0_entity_id: string;',\n ' endpoint_1_entity_id: string;',\n ' trace?: JsonObject;',\n '}',\n 'export interface LinkRelationInput extends LinkRelationBase {',\n ' relation_kind: KnownRelationKind;',\n ' metadata?: JsonObject;',\n '}',\n 'export type MediaAssetPayload = JsonObject & {',\n ' external: {',\n \" system: 'memota' | 'memota-speech';\",\n ' key: string;',\n ' };',\n '};',\n 'export interface RelationUpdateInput {',\n ' relation_id: string;',\n ' changes: FieldChange[];',\n '}',\n 'export interface SandboxEntity<K extends KnownEntityKind = KnownEntityKind> {',\n ' entity_id: string;',\n ' entity_kind: K;',\n ' payload: StoredEntityPayload<K>;',\n '}',\n 'export interface SandboxRelation {',\n ' relation_id: string;',\n ' relation_kind: KnownRelationKind;',\n ' endpoint_0_entity_id: string;',\n ' endpoint_1_entity_id: string;',\n ' metadata: JsonObject;',\n ' trace: JsonObject;',\n '}',\n 'export type ScriptTextSegment = JsonObject & {',\n ' segmentId: string;',\n ' text: string;',\n ' language?: string;',\n '};',\n '/** Stored own fields; a variant may obtain required content fields from its declared bases. */',\n 'export type StoredEntityPayload<K extends KnownEntityKind> =',\n ' | EntityPayloadByKind[K]',\n \" | (K extends 'caption' ? JsonObject & Pick<MediaAssetPayload, 'external'> : never)\",\n ' | (JsonObject &',\n ' Partial<EntityPayloadByKind[K]> & {',\n ' baseEntityIds: string[];',\n ' });',\n 'export interface UnboundedConstantSequencePayload extends JsonObject {',\n ' extent: {',\n \" kind: 'unbounded';\",\n ' start: number;',\n ' };',\n \" sampling: 'constant';\",\n ' coordinateSpace: JsonValue;',\n '}',\n 'export interface UnlinkRelationInput {',\n ' relation_id: string;',\n '}',\n '/** Patch supplied fields on the assembled entity; omitted fields remain unchanged. */',\n 'export interface UpdateEntityInput {',\n ' entity_id: string;',\n ' payload: JsonObject;',\n '}',\n 'export declare const entities: BusinessEntityFacade;',\n 'export declare const relations: BusinessRelationFacade;',\n \"/** Resolve this Entity's attached resource through the host; await before using an uninitialized Caption. */\",\n 'export declare function rgetAssetFromEntity(entityId: string): Promise<EntityAssetContent>;',\n 'export declare function checkpoint(): EntitySandboxCheckpoint;',\n 'export declare function rollbackTo(cp: EntitySandboxCheckpoint): void;',\n 'export declare const inputs: Readonly<Record<string, unknown>>;',\n 'export declare const console: {',\n ' log(...values: unknown[]): void;',\n ' info(...values: unknown[]): void;',\n ' warn(...values: unknown[]): void;',\n ' error(...values: unknown[]): void;',\n '};',\n '',\n].join('\\n');\n","import { ENTITY_EDIT_SANDBOX_API_DTS } from './sandbox/generated/entity-edit-sandbox-model-context.ts';\n\nexport const MEDEO_TOOL_DESCRIPTION = `\nEdit the authoritative Medeo Entity/Relation graph in an isolated JavaScript sandbox.\n\nOperations:\n- snapshot: read assembled entities, relations, project attachments and the current document version. Reading never initializes or changes the document.\n- run-edit-script: use entities and relations to inspect and edit the causal working view. rgetAssetFromEntity(entityId) delegates an attached-resource read to the host. The script has no network, generation or storage access. A successful run returns preview, logs and plan_id.\n- commit-plan: publish the original native Loro operations compiled against the plan's causal baseline. Independent concurrent edits merge; failed transport is unconfirmed, so retry the same plan_id to preserve operation identity.\n\nDefault flow: snapshot → run-edit-script with auto_commit=false → inspect preview → commit-plan. Use auto_commit=true for low-risk edits that need no host confirmation. A domain conflict requires inspecting and explicitly resolving the merged state; never overwrite the document or silently replay an old plan on a new snapshot.\n`.trim();\n\nconst MEDEO_TOOL_EXECUTION_RULES = `\nThe host supplies the current document. Do not invent or request a document id. The sandbox exposes only the API below: entity operations, relation operations, entity-bound resource reading and checkpoints. All business edits are expressed using entity fields and relation kinds.\n\nEntity reads return assembled snapshots. Mutating returned objects has no persistence effect. Create declares own fields. Update requires a nonempty changes array and atomically applies its ordered operations to assembled fields, routing each to its declaring owner. DeclareFields explicitly establishes own fields or an override; it is not the normal way to edit inherited content. Deletion requires explicitly handling incident relations, variant references and protected project attachments; it never deletes external resources or cascades business entities.\n\nFieldChange paths start at payload for an entity, and at metadata or trace for a relation. Use strings for fields and {elementId:'...'} for list members, never numeric indices. Segment identity is segmentId; reference identity is the referenced id. set writes scalars or schema-declared atomic values, including complete sourceRange, targetRange, extent, duration, timeRemapping, selection, textRange and external. It cannot replace collaborative text, lists or maps. Edit text with text.splice (Unicode code-point index and deleteCount), and segments/segmentRanges with list.insert, list.move or list.remove. beforeElementId:null means append; moving before itself, duplicate identity or an absent anchor is an error. Unset removes optional fields only. Map fields are edited through leaf paths; initialize a new own map via declareFields. baseEntityIds is unordered composition membership: insert/remove are supported, moving bases cannot resolve field conflicts. Independent fields and list-item text edits retain native Loro identities.\n\nEntities own data. Relations associate two existing entities; endpoint_0 and endpoint_1 retain their declared positions. Each relation kind defines direction and meaning; neither relation listing order nor endpoint storage order implies a global business order. Relations.update changes metadata/trace fields only; kind/endpoints require explicit unlink plus link with a new identity. Generated relations use generated(output,input). Ordinary associations do not implement composition.\n\nVariants directly hold baseEntityIds. Assembly validates every base before applying explicit own overrides: two bases supplying the same field are an error even if values match or the variant declares that field. Missing/cyclic bases fail. Consumers operate assembled fields without copying inherited content or resolving owners themselves. An owned-field edit creates a new immutable entity version. Base changes automatically advance variant base references and project attachments without versioning an unchanged variant. A variant-owned change versions the variant and retains unchanged bases. Do not manually clone entities for versioning. Use the current plan's ids throughout that execution; refresh after commit.\n\nGeneration tools return resource references. An asset id may be passed in an entity's external:{system:'memota',key:assetId}; it is never an entity id, baseEntityId or relation endpoint. Physical resources are host infrastructure. The sandbox has no direct resource lookup/CRUD by asset id. rgetAssetFromEntity takes only an existing business entity id and returns {assetId,content} for its attached resource. For output_caption, create a Caption with payload:{external:{system:'memota',key:assetId}}, then await rgetAssetFromEntity(captionId). The host initializes the complete AudioScript and one Caption per resource segment in the same causal plan when selection is omitted. The requested Caption represents the first segment; additional Caption entities share that same script and external reference. After awaiting, discover ALL resource Captions with entities.list filtered by entity_kind and payload.external.key, inspect each singular selection/extent, and place each in its own Clip/SequenceMarker. An explicit selection initializes only that selected Caption. Never place the first Caption over the whole transcript; Without explicit bases, the host creates an independent AudioScript for that resource. With bases, it resolves their unique AudioScript text owner and preserves other nonconflicting bases. It never routes text through the panel selection. Read the editable fields with entities.get afterwards. Repeated reads preserve edited text and return the original immutable resource content. Unawaited initialization is completed before validation; failure prevents publication. Resource-free Caption composition from AudioScript is also valid.\n\nProject initialization creates one current Timeline, the four standard Tracks and one attached AudioScript with segments:[]. A project may contain multiple independent complete AudioScripts (for example a generated script and an uploaded video transcript). The project AudioScript attachment selects only the panel view; it is not a singleton or membership constraint. Locate scripts with entities.list and choose the appropriate source. AudioScript owns independent multi-segment text; each can have multiple Caption variants. Caption and PhoneticScript compose it through baseEntityIds. Caption owns exactly one selection object ({segmentId,textRange?}), never an array or the legacy selections field. It selects one script segment or a contiguous substring, and owns only that selection's intrinsic timing and style; segmentId is a stable script-local identity, not an entity reference or transient array index; selection textRange is a half-open code-point range and can split display text without rewriting the script. PhoneticScript owns pronunciation/prosody; Voice is generated from it and related by phonetic-script-render(voice,phoneticScript). Speech and caption occupy separate Clips. Subtitles normally accompany sound; use source media or generate Voice from PhoneticScript when the request requires narration. Do not fabricate a sound resource.\n\nAudioScript has no intrinsic time and cannot be Clip content. ASR input Audio/Video/Voice associates via audio-script-source(script,source). Its external annotation SequenceMarker associates via audio-script-marker(script,marker) and receives assigned segmentRanges, not references to another marker. Caption intrinsic timing and its Clip's display SequenceMarker are distinct. Move/stretch display by editing only the placement marker.\n\nTo place content, create a Clip and a SequenceMarker, then link track-clip(track,clip), clip-marker(clip,marker) and marker-content(marker,content). Existing track membership uses timeline-track(timeline,track). The editor has one track of each role: video_clip for Image/Video, speech for Voice, caption for Caption, bgm for Audio. Inspect factual media extents; never invent duration. Each placement is exactly one of Clip.order (sequential), Marker.targetRange (absolute) or clip-anchor(childClip,hostClip) plus Marker.anchorOffset. Marker.sourceRange selects source, duration describes playback/display. Whole milliseconds are required by this editor projection. Clip.volume is decibels (-60..20, 0 original). Image is unbounded/constant. Linear timeRemapping is {kind:'linear',rate:2,mode:'constant'}, with duration matching the rounded source span/rate. BGM can use durationPolicy:'timeline'. Nonlinear speed and multiple overlay tracks are unsupported. Caption visibility is the caption Track's hidden field. Caption style is its style map. Handle structural links explicitly when moving/deleting; there is no implicit cascade.\n\ncheckpoint returns an opaque token valid only in this execution. rollbackTo restores that point and invalidates later checkpoints. Returned read snapshots and inputs are not writable document authorities. Use only the declarations below.\n`.trim();\n\nexport interface RenderMedeoModelContextInput {\n documentVersion: string;\n updatedSincePreviousModelCall: boolean | null;\n}\n\n/** MEngine owns API disclosure; Harness only supplies the changing document context. */\nexport function renderMedeoModelContext(input: RenderMedeoModelContextInput): string {\n const updated =\n input.updatedSincePreviousModelCall == null\n ? 'unknown (first model call)'\n : String(input.updatedSincePreviousModelCall);\n return `\n${MEDEO_TOOL_DESCRIPTION}\n\n${MEDEO_TOOL_EXECUTION_RULES}\n\nCurrent MEngine document state (sampled immediately before this model call):\n- document_version: ${JSON.stringify(input.documentVersion)}\n- updated_since_previous_model_call: ${updated}\n\nWhen updated_since_previous_model_call is true, take a fresh snapshot before planning further edits.\n\nSandbox TypeScript interface:\n\\`\\`\\`ts\n${ENTITY_EDIT_SANDBOX_API_DTS}\n\\`\\`\\`\n`.trim();\n}\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 `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. Use edit, timeline, entities, relations, checkpoint, rollbackTo, inputs, and console. Asset import, media relations, and timeline entity edits share one entity plan.',\n },\n inputs: {\n type: 'object',\n description:\n 'Pre-materialized, side-effect-free values passed into the script, including recalled asset facts. Generation history is never an input: the host queries lineage itself and syncs generated Relations after each commit. 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: ['preflight'],\n description: 'Publish the native update already validated on its causal Loro fork.',\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 decodeDocVersionMark,\n encodeDocVersionMark,\n replayJournal,\n ValidationError,\n type JournalEntry,\n type ManualSyncDoc,\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 document 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 /** Encoded `ManualSyncDoc.versionMark()` from when the sandbox was forked. */\n base_version: string;\n ops: readonly JournalEntry[];\n}\n\nexport interface CommitPlanWarning {\n kind: 'pull_failed';\n message: string;\n}\n\nexport type CommitPlanResult =\n | {\n kind: 'committed';\n ops_applied: number;\n collaborated: boolean;\n warnings?: CommitPlanWarning[];\n }\n | { kind: 'unconfirmed'; reason: 'push_failed'; ops_applied: number; message: string }\n | { kind: 'rejected'; reason: 'version_mismatch'; expected: string; actual: string }\n | { kind: 'rejected'; reason: 'push_rejected'; code?: string; message: 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 manually-synchronized document and push the\n * whole plan as one causally complete update.\n *\n * - Default / `{ validation: 'version' }`: if the current document mark differs\n * from `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 doc: ManualSyncDoc,\n plan: CommitPlan,\n options?: CommitPlanOptions,\n): Promise<CommitPlanResult> {\n if (options?.validation === 'preflight') {\n return commitPlanPreflight(doc, plan);\n }\n\n const actual = encodeDocVersionMark(doc.versionMark());\n const expected = decodeDocVersionMark(plan.base_version);\n if (expected == null || doc.hasChangedSince(expected)) {\n return {\n kind: 'rejected',\n reason: 'version_mismatch',\n expected: plan.base_version,\n actual,\n };\n }\n\n await doc.replayJournal(plan.ops);\n return retryPlanPush(doc, 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(doc: ManualSyncDoc, plan: CommitPlan): Promise<CommitPlanResult> {\n const scratch = createPlainMemoryAdapter(doc.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 doc.replayJournal([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 retryPlanPush(doc, plan.ops.length);\n}\n\n/** Push an already-replayed plan again without replaying or re-running its version gate. */\nexport async function retryPlanPush(doc: ManualSyncDoc, opsApplied: number): Promise<CommitPlanResult> {\n const result = await doc.push();\n if (result.kind === 'ack' || result.kind === 'duplicate' || result.kind === 'nothing_to_push') {\n // A push can reveal that another peer wrote concurrently. Pull after the\n // durable verdict so the cached document does not serve a stale snapshot on\n // the next tool call; a pull failure cannot undo the acknowledged write.\n const reconciled = result.collaborated ? await doc.pull() : undefined;\n const warnings =\n reconciled != null && !reconciled.ok\n ? [{ kind: 'pull_failed' as const, message: reconciled.error.message }]\n : undefined;\n return {\n kind: 'committed',\n ops_applied: opsApplied,\n collaborated: result.collaborated,\n ...(warnings !== undefined ? { warnings } : {}),\n };\n }\n if (result.kind === 'rejected') {\n return {\n kind: 'rejected',\n reason: 'push_rejected',\n ...(result.code !== undefined ? { code: result.code } : {}),\n message: result.error?.message ?? 'mengine rejected the sandbox plan',\n };\n }\n return {\n kind: 'unconfirmed',\n reason: 'push_failed',\n ops_applied: opsApplied,\n message: result.error?.message ?? 'mengine push failed',\n };\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","/// <reference types=\"node\" />\nimport { randomUUID } from 'node:crypto';\n\nimport {\n createMirrorVideoDocument,\n encodeDocVersionMark,\n ManualSyncDoc,\n MengineHttpClient,\n MengineHttpRequestError,\n ensureEditorFoundation,\n LoroEntityDocument,\n toVideoDocument,\n type ManualSyncDocOptions,\n type VideoDocument,\n type VideoDraft,\n} from '@mengine/medeo-client';\n\nimport {\n assembleCaptionAssets,\n type CaptionAssetsLoader,\n type CaptionAssetAssemblyOutcome,\n} from './entity/caption-asset-assembly.ts';\nimport type { EntityAssetLoader } from './entity/entity-asset.ts';\nimport type { EntityStoreSnapshot } from './entity/entity-contract.ts';\nimport { EntityHttpClient, MengineEntityHttpRequestError } from './entity/entity-http-client.ts';\nimport {\n syncGeneratedRelations,\n type GenerationFactsLoader,\n type GenerationSyncOutcome,\n} from './entity/generation-sync.ts';\nimport { MEDEO_TOOL_DESCRIPTION, renderMedeoModelContext } from './prompt.ts';\nimport { businessState } from './sandbox/business-facades.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 { retryPlanPush, 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 * Documents 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 /**\n * Resolve factual generation lineage by external asset id after a confirmed\n * entity commit. Return every known generation record involving the given\n * ids in either role; an empty array means no known lineage and a rejection\n * means the lineage query failed (surfaced as a warning, never as synced\n * state). The package owns all Entity/Relation semantics: the host never\n * names entities, relations, or endpoints.\n */\n loadGenerationFacts?: GenerationFactsLoader;\n /** Assemble optional Caption artifacts by immutable entity ID; never exposed to scripts. */\n loadCaptionAssets?: CaptionAssetsLoader;\n loadEntityAsset?: EntityAssetLoader;\n fetchImpl?: typeof fetch;\n /** @deprecated ManualSyncDoc has no SSE or reconnect loop. */\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 /** Maximum model-call version baselines retained across host contexts (default 128). */\n maxModelContexts?: number;\n}\n\nexport interface MedeoModelContextInput {\n /** Internal MEngine document id. This is host-supplied and never model-facing. */\n doc_id: string;\n /** Stable host conversation/session key used to compare consecutive model calls. */\n context_id: string;\n}\n\nexport interface MedeoModelContext {\n /** Complete MEngine-owned prompt: workflow, runtime state, and sandbox TypeScript interface. */\n prompt: string;\n document_version: string;\n updated_since_previous_model_call: boolean | null;\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?: 'preflight';\n };\n\nexport type MedeoToolWarning =\n | { kind: 'asset_assembly_failed'; message: string }\n | { kind: 'pull_failed'; message: string }\n | { kind: 'generation_sync_failed'; message: string };\n\nexport type EntityCommitResult =\n | { kind: 'conflicted'; accepted: true; entity_revision: number; message: string }\n | {\n kind: 'committed';\n ops_applied: number;\n collaborated: boolean;\n entity_revision: number;\n /** Present only when the host supplies loadGenerationFacts. */\n generation_sync?: GenerationSyncOutcome;\n asset_assembly?: CaptionAssetAssemblyOutcome;\n warnings?: MedeoToolWarning[];\n }\n | { kind: 'unconfirmed'; reason: 'push_failed'; ops_applied: number; message: string }\n | {\n kind: 'rejected';\n reason: 'entity_state_rejected';\n status: number;\n message: string;\n };\n\nexport type MedeoCommitResult = CommitPlanResult | EntityCommitResult;\n\nexport type MedeoToolResult =\n | {\n ok: true;\n op: 'snapshot';\n doc_id: string;\n version: string;\n preview: string;\n collaborated?: boolean;\n warnings?: MedeoToolWarning[];\n }\n | {\n ok: true;\n op: 'run-edit-script';\n doc_id: string;\n plan_id: string;\n plan_kind: 'timeline' | 'entities';\n base_version: string;\n entity_base_revision: number;\n ops_count: number;\n preview: string;\n logs: string[];\n duration_ms: number;\n committed?: boolean;\n commit_result?: MedeoCommitResult;\n collaborated?: boolean;\n warnings?: MedeoToolWarning[];\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 plan_kind: 'timeline' | 'entities';\n committed: boolean;\n result: MedeoCommitResult;\n collaborated?: boolean;\n warnings?: MedeoToolWarning[];\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 getModelContext(input: MedeoModelContextInput): Promise<MedeoModelContext>;\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 /** Entity-store state the plan was built from; the generation sync's diff base. */\n baseState?: EntityStoreSnapshot;\n}\n\ninterface TimelinePendingPush {\n kind: 'timeline';\n planId: string;\n plan: ChangePlan;\n opsApplied: number;\n}\n\ninterface EntityPendingPush {\n kind: 'entities';\n planId: string;\n plan: ChangePlan;\n /** Diff base for the generation sync after recovery; see CachedPlan. */\n baseState?: EntityStoreSnapshot;\n}\n\ntype PendingPush = TimelinePendingPush | EntityPendingPush;\n\ninterface PullObservation {\n collaborated: boolean;\n warnings?: MedeoToolWarning[];\n}\n\nconst DEFAULT_MAX_PLANS = 16;\nconst DEFAULT_MAX_MODEL_CONTEXTS = 128;\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 renderEntitySnapshot(raw: EntityStoreSnapshot): string {\n const state = businessState(raw);\n const rows = [\n ...state.entities.map((entity) => JSON.stringify(entity)),\n ...state.relations.map((relation) => JSON.stringify(relation)),\n ];\n const shown = rows.slice(0, 200);\n return [\n `Entity revision=${state.revision} audioScriptEntityId=${JSON.stringify(state.audioScriptEntityId)} entities=${state.entities.length} relations=${state.relations.length}`,\n ...shown,\n ...(shown.length < rows.length ? ['[truncated; inspect entities/relations in the sandbox]'] : []),\n ].join('\\n');\n}\n\nasync function commitEntityPlan(client: EntityHttpClient, plan: ChangePlan): Promise<EntityCommitResult> {\n const rows = plan.entity_rows;\n if (rows === undefined) throw new Error('entity plan is missing its authoritative rows');\n try {\n if (!plan.loro_update) throw new Error('Entity plan has no compiled Loro update');\n const committed = await client.commitUpdate(plan.loro_update);\n return {\n kind: 'committed',\n ops_applied: plan.entity_commands.length,\n collaborated: committed.revision > plan.entity_base_revision + 1,\n entity_revision: committed.revision,\n };\n } catch (error) {\n if (error instanceof MengineEntityHttpRequestError) {\n if (isRecord(error.payload) && error.payload.accepted === true && typeof error.payload.revision === 'number')\n return {\n kind: 'conflicted',\n accepted: true,\n entity_revision: error.payload.revision,\n message: entityHttpErrorMessage(error.payload),\n };\n return {\n kind: 'rejected',\n reason: 'entity_state_rejected',\n status: error.status,\n message: entityHttpErrorMessage(error.payload),\n };\n }\n return {\n kind: 'unconfirmed',\n reason: 'push_failed',\n ops_applied: plan.entity_commands.length,\n message: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nfunction entityHttpErrorMessage(payload: unknown): string {\n if (isRecord(payload) && isRecord(payload.error) && typeof payload.error.message === 'string')\n return payload.error.message;\n if (isRecord(payload) && typeof payload.message === 'string' && payload.message.length > 0) return payload.message;\n return typeof payload === 'string' && payload.length > 0 ? payload : 'mengine rejected the entity-state plan';\n}\n\nfunction commitWarnings(result: MedeoCommitResult): MedeoToolWarning[] | undefined {\n return result.kind === 'committed' && 'warnings' in result && result.warnings !== undefined\n ? [...result.warnings]\n : undefined;\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 !== 'preflight') {\n throw new Error('validation must be \"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 document 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 documents = new Map<string, Promise<ManualSyncDoc>>();\n const entityClients = new Map<string, EntityHttpClient>();\n const documentTails = new Map<string, Promise<void>>();\n const pendingPushes = new Map<string, PendingPush>();\n const plans = new Map<string, CachedPlan>();\n const modelContextVersions = new Map<string, string>();\n const maxPlans = options.maxPlans ?? DEFAULT_MAX_PLANS;\n const maxModelContexts = options.maxModelContexts ?? DEFAULT_MAX_MODEL_CONTEXTS;\n let closed = false;\n\n async function getDocument(docId: string): Promise<ManualSyncDoc> {\n if (closed) throw new Error('medeo tool is closed');\n const existing = documents.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 ManualSyncDocOptions['peerId'] | undefined;\n return await getOrCreateDocument(client, docId, peerId);\n })();\n\n documents.set(docId, created);\n try {\n return await created;\n } catch (error) {\n if (documents.get(docId) === created) documents.delete(docId);\n throw error;\n }\n }\n\n function getEntityClient(docId: string): EntityHttpClient {\n if (closed) throw new Error('medeo tool is closed');\n const existing = entityClients.get(docId);\n if (existing != null) return existing;\n const client = new EntityHttpClient({\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 entityClients.set(docId, client);\n return client;\n }\n\n async function runExclusive<T>(docId: string, use: (doc: ManualSyncDoc) => Promise<T>): Promise<T> {\n const previous = documentTails.get(docId) ?? Promise.resolve();\n let release!: () => void;\n const gate = new Promise<void>((resolve) => {\n release = resolve;\n });\n const tail = previous.catch(() => {}).then(() => gate);\n documentTails.set(docId, tail);\n\n await previous.catch(() => {});\n try {\n return await use(await getDocument(docId));\n } finally {\n release();\n if (documentTails.get(docId) === tail) documentTails.delete(docId);\n }\n }\n\n async function getOrCreateDocument(\n client: MengineHttpClient,\n docId: string,\n peerId: ManualSyncDocOptions['peerId'] | undefined,\n ): Promise<ManualSyncDoc> {\n try {\n return await ManualSyncDoc.open({ client, ...(peerId !== undefined ? { peerId } : {}) });\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 if (Object.keys(document.part_library ?? {}).length > 0) {\n throw new Error('Legacy content cannot bootstrap a Loro entity project');\n }\n const seed = createMirrorVideoDocument(document, {\n ...(peerId !== undefined ? { peerId } : {}),\n origin: 'mengine.medeo_tool.bootstrap',\n });\n const foundation = ensureEditorFoundation({ entities: [], relations: [] });\n const entities = LoroEntityDocument.create(foundation.rows, {\n timelineEntityId: foundation.timelineEntityId,\n audioScriptEntityId: foundation.audioScriptEntityId,\n });\n seed.import(entities.doc.export({ mode: 'snapshot' }));\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 // The open below is the authenticated proof that the winner exists.\n }\n return await ManualSyncDoc.open({ client, ...(peerId !== undefined ? { peerId } : {}) });\n }\n\n function rememberPlan(docId: string, plan: ChangePlan, baseState: EntityStoreSnapshot | undefined): string {\n const planId = randomUUID();\n plans.set(planId, {\n docId,\n plan,\n ...(plan.plan_kind === 'entities' ? { baseState: baseState && structuredClone(baseState) } : {}),\n });\n while (plans.size > maxPlans) {\n const protectedPlanIds = new Set([...pendingPushes.values()].map((pending) => pending.planId));\n protectedPlanIds.add(planId);\n const oldestEvictable = [...plans.keys()].find((candidate) => !protectedPlanIds.has(candidate));\n // Pending plans are recovery state, and the plan just returned by this\n // call must remain usable. Let the cache exceed its nominal bound until a\n // later insertion can evict an older, non-pending plan.\n if (oldestEvictable === undefined) break;\n plans.delete(oldestEvictable);\n }\n return planId;\n }\n\n function assertNoPendingPush(docId: string): void {\n const pending = pendingPushes.get(docId);\n if (pending != null) {\n throw new Error(`doc ${docId} has an unconfirmed push; retry plan_id ${pending.planId} before continuing`);\n }\n }\n\n function recordPushResult(\n docId: string,\n planId: string,\n plan: ChangePlan,\n result: MedeoCommitResult,\n baseState: EntityStoreSnapshot | undefined,\n ): void {\n if (result.kind === 'unconfirmed') {\n pendingPushes.set(\n docId,\n plan.plan_kind === 'timeline'\n ? { kind: 'timeline', planId, plan, opsApplied: result.ops_applied }\n : { kind: 'entities', planId, plan, ...(baseState !== undefined ? { baseState } : {}) },\n );\n return;\n }\n pendingPushes.delete(docId);\n if (plan.plan_kind === 'timeline' && result.kind === 'rejected' && result.reason === 'push_rejected') {\n documents.delete(docId);\n }\n }\n\n async function fetchEntityStateForSandbox(\n docId: string,\n _doc: ManualSyncDoc,\n _pull: PullObservation,\n ): Promise<EntityStoreSnapshot> {\n const state = await getEntityClient(docId).fetchState();\n if (!state.loroSnapshot) throw new Error('Project requires the Loro entity contract');\n return state;\n }\n\n async function commitCachedPlan(\n docId: string,\n _doc: ManualSyncDoc,\n plan: ChangePlan,\n validation?: 'preflight',\n baseState?: EntityStoreSnapshot,\n ) {\n if (plan.plan_kind === 'timeline') {\n throw new Error('Legacy timeline plans are not editable; use an Entity/Relation plan');\n }\n // Every plan was preflighted on its causal Loro fork before publication.\n void validation;\n if (plan.entity_rows === undefined) throw new Error('entity plan is missing its authoritative rows');\n const client = getEntityClient(docId);\n // The generation diff must use the same causal baseline as the compiled update.\n if (options.loadGenerationFacts !== undefined && baseState === undefined)\n throw new Error('Generation synchronization is missing the cached causal plan baseline');\n const result = await commitEntityPlan(client, plan);\n const synced = await attachGenerationSync(docId, plan, result, baseState);\n if (synced.kind !== 'committed' || options.loadCaptionAssets === undefined) return synced;\n const assembly = await assembleCaptionAssets({ client, docId, loadAssets: options.loadCaptionAssets });\n return {\n ...synced,\n asset_assembly: assembly,\n ...(assembly.status === 'failed'\n ? {\n warnings: [\n ...(synced.warnings ?? []),\n {\n kind: 'asset_assembly_failed' as const,\n message: assembly.message ?? 'Caption Asset assembly failed',\n },\n ],\n }\n : {}),\n };\n }\n\n /**\n * After a confirmed entity commit, connect fact-matched generated Relations\n * from host-recalled lineage. The commit is already durable, so a sync\n * failure never fails the op; it is attached to the result and surfaced as a\n * warning instead. The plan's diff against `baseState` scopes the sync:\n * newly created media Asset identities — not untouched pairs or placement-only edits.\n * One-sided facts are skipped silently inside the sync.\n */\n async function attachGenerationSync(\n docId: string,\n plan: ChangePlan,\n result: EntityCommitResult,\n baseState: EntityStoreSnapshot | undefined,\n ): Promise<EntityCommitResult> {\n if (result.kind !== 'committed' || options.loadGenerationFacts === undefined || baseState === undefined) {\n return result;\n }\n let outcome: GenerationSyncOutcome;\n try {\n outcome = await syncGeneratedRelations({\n client: getEntityClient(docId),\n docId,\n baseState,\n entityCommands: plan.entity_commands,\n loadFacts: options.loadGenerationFacts,\n });\n } catch (error) {\n outcome = { status: 'failed', message: error instanceof Error ? error.message : String(error) };\n }\n const warnings: MedeoToolWarning[] | undefined =\n outcome.status === 'failed'\n ? [{ kind: 'generation_sync_failed', message: outcome.message ?? 'generation lineage sync failed' }]\n : undefined;\n return {\n ...result,\n generation_sync: outcome,\n ...(warnings !== undefined ? { warnings } : {}),\n };\n }\n\n async function observePull(doc: ManualSyncDoc): Promise<PullObservation> {\n const result = await doc.pull();\n if (result.ok) return { collaborated: result.changed };\n return {\n collaborated: false,\n warnings: [{ kind: 'pull_failed', message: result.error.message }],\n };\n }\n\n function mergeWarnings(\n ...groups: readonly (readonly MedeoToolWarning[] | undefined)[]\n ): MedeoToolWarning[] | undefined {\n const warnings = groups.flatMap((group) => group ?? []);\n return warnings.length > 0 ? warnings : undefined;\n }\n\n async function getModelContext(input: MedeoModelContextInput): Promise<MedeoModelContext> {\n const docId = input.doc_id.trim();\n const contextId = input.context_id.trim();\n if (docId.length === 0) throw new Error('doc_id must be a non-empty string');\n if (contextId.length === 0) throw new Error('context_id must be a non-empty string');\n\n return await runExclusive(docId, async (doc) => {\n // ManualSyncDoc has no background stream. Pull before sampling so remote\n // edits made between model calls participate in the version comparison.\n const pull = await observePull(doc);\n const entityState = await fetchEntityStateForSandbox(docId, doc, pull);\n const documentVersion = `${encodeDocVersionMark(doc.versionMark())}:entities:${entityState.revision}`;\n const baselineKey = `${contextId}\\u0000${docId}`;\n const previousVersion = modelContextVersions.get(baselineKey);\n const updatedSincePreviousModelCall = previousVersion == null ? null : previousVersion !== documentVersion;\n\n // Refresh insertion order so the bounded map behaves as an LRU.\n modelContextVersions.delete(baselineKey);\n modelContextVersions.set(baselineKey, documentVersion);\n while (modelContextVersions.size > maxModelContexts) {\n const oldest = modelContextVersions.keys().next().value;\n if (oldest === undefined) break;\n modelContextVersions.delete(oldest);\n }\n\n return {\n prompt: renderMedeoModelContext({ documentVersion, updatedSincePreviousModelCall }),\n document_version: documentVersion,\n updated_since_previous_model_call: updatedSincePreviousModelCall,\n };\n });\n }\n\n async function snapshot(input: Extract<MedeoToolInput, { op: 'snapshot' }>): Promise<MedeoToolResult> {\n return runExclusive(input.doc_id, async (doc) => {\n assertNoPendingPush(input.doc_id);\n const pull = await observePull(doc);\n const entityState = await fetchEntityStateForSandbox(input.doc_id, doc, pull);\n return {\n ok: true,\n op: 'snapshot',\n doc_id: input.doc_id,\n version: `${encodeDocVersionMark(doc.versionMark())}:entities:${entityState.revision}`,\n preview: renderEntitySnapshot(entityState),\n collaborated: pull.collaborated,\n ...(pull.warnings !== undefined ? { warnings: pull.warnings } : {}),\n };\n });\n }\n\n async function run(input: Extract<MedeoToolInput, { op: 'run-edit-script' }>): Promise<MedeoToolResult> {\n return runExclusive(input.doc_id, async (doc) => {\n assertNoPendingPush(input.doc_id);\n const pull = await observePull(doc);\n const entityState = await fetchEntityStateForSandbox(input.doc_id, doc, pull);\n const document: VideoDocument = doc.snapshot();\n const baseVersion = encodeDocVersionMark(doc.versionMark());\n const result = await runEditScript({\n document,\n baseVersion,\n entityState,\n loadEntityAsset: options.loadEntityAsset\n ? (entity) => options.loadEntityAsset!(input.doc_id, entity)\n : undefined,\n script: input.script,\n ...(input.inputs !== undefined ? { inputs: input.inputs } : {}),\n timeoutMs: input.timeout_ms ?? options.sandbox?.timeoutMs ?? 30_000,\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: {\n ops_count: result.partial.ops.length + result.partial.entityCommands.length,\n logs: result.partial.logs,\n },\n };\n }\n\n // The host-selected mapping is authoritative. A legacy document snapshot\n // may omit meta.draft_id, so never derive an entity route from it.\n const plan = { ...result.plan, doc_id: input.doc_id };\n const planId = rememberPlan(input.doc_id, plan, entityState);\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 plan_kind: plan.plan_kind,\n base_version: baseVersion,\n entity_base_revision: plan.entity_base_revision,\n ops_count: plan.ops.length + plan.entity_commands.length,\n preview: plan.preview,\n logs: plan.logs,\n duration_ms: result.durationMs,\n collaborated: pull.collaborated,\n ...(pull.warnings !== undefined ? { warnings: pull.warnings } : {}),\n };\n if (input.auto_commit !== true) return base;\n\n const commit = await commitCachedPlan(input.doc_id, doc, plan, undefined, entityState);\n recordPushResult(input.doc_id, planId, plan, commit, entityState);\n const warnings = mergeWarnings(pull.warnings, commitWarnings(commit));\n return {\n ...base,\n committed: commit.kind === 'committed',\n commit_result: commit,\n collaborated: pull.collaborated || (commit.kind === 'committed' && commit.collaborated),\n ...(warnings !== undefined ? { warnings } : {}),\n };\n });\n }\n\n async function commit(input: Extract<MedeoToolInput, { op: 'commit-plan' }>): Promise<MedeoToolResult> {\n return runExclusive(input.doc_id, async (doc) => {\n const pending = pendingPushes.get(input.doc_id);\n if (pending != null) {\n if (pending.planId !== input.plan_id) {\n throw new Error(\n `doc ${input.doc_id} has an unconfirmed push for plan_id ${pending.planId}; retry it before ${input.plan_id}`,\n );\n }\n const result =\n pending.kind === 'timeline'\n ? await retryPlanPush(doc, pending.opsApplied)\n : await commitCachedPlan(input.doc_id, doc, pending.plan, input.validation, pending.baseState);\n recordPushResult(\n input.doc_id,\n input.plan_id,\n pending.plan,\n result,\n pending.kind === 'entities' ? pending.baseState : undefined,\n );\n const warnings = commitWarnings(result);\n return {\n ok: true,\n op: 'commit-plan',\n doc_id: input.doc_id,\n plan_id: input.plan_id,\n plan_kind: pending.plan.plan_kind,\n committed: result.kind === 'committed',\n result,\n collaborated: result.kind === 'committed' && result.collaborated,\n ...(warnings !== undefined ? { warnings } : {}),\n };\n }\n\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 pull = cached.plan.plan_kind === 'timeline' ? await observePull(doc) : { collaborated: false };\n const result = await commitCachedPlan(input.doc_id, doc, cached.plan, input.validation, cached.baseState);\n recordPushResult(input.doc_id, input.plan_id, cached.plan, result, cached.baseState);\n const warnings = mergeWarnings(pull.warnings, commitWarnings(result));\n return {\n ok: true,\n op: 'commit-plan',\n doc_id: input.doc_id,\n plan_id: input.plan_id,\n plan_kind: cached.plan.plan_kind,\n committed: result.kind === 'committed',\n result,\n collaborated: pull.collaborated || (result.kind === 'committed' && result.collaborated),\n ...(warnings !== undefined ? { warnings } : {}),\n };\n });\n }\n\n return {\n name: MEDEO_TOOL_NAME,\n description: MEDEO_TOOL_DESCRIPTION,\n parameters: MEDEO_TOOL_PARAMETERS,\n getModelContext,\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 await Promise.allSettled(documentTails.values());\n const opening = [...documents.values()];\n documents.clear();\n entityClients.clear();\n documentTails.clear();\n pendingPushes.clear();\n plans.clear();\n modelContextVersions.clear();\n const errors: unknown[] = [];\n for (const documentPromise of opening) {\n try {\n await documentPromise;\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 documents');\n },\n };\n}\n","import { createHash } from 'node:crypto';\n\nimport type { MediaAssetFact } from '@mengine/medeo-client';\n\nimport type { JsonObject } from './entity-contract.ts';\nimport { EntityHttpClient, type EntityHttpClientOptions } from './entity-http-client.ts';\nimport { EntitySandbox } from './entity-sandbox.ts';\nimport { planGeneratedRelations, parseGenerationFacts, type GenerationFactsLoader } from './generation-sync.ts';\n\n/** Host facts only. This contract is never included in the model's sandbox API. */\nexport type GeneratedResource =\n | MediaAssetFact\n | {\n kind: 'caption';\n assetId: string;\n storageKey: string;\n segments: readonly {\n text: string;\n startMs: number;\n endMs: number;\n /** ASR word timing is available as an annotation for model segmentation. */\n words?: readonly { text: string; startMs: number; endMs: number }[];\n }[];\n };\n\n/** Persist resources before model consumption. The host serializes repeated imports of the same generation task. */\nexport async function materializeResources(\n options: EntityHttpClientOptions & { loadGenerationFacts?: GenerationFactsLoader },\n resources: readonly GeneratedResource[],\n): Promise<readonly string[]> {\n const client = new EntityHttpClient(options);\n const state = await client.fetchState();\n let resourceKey = '';\n const sandbox = new EntitySandbox({ state, idFactory: (prefix) => stableId(prefix, options.docId, resourceKey) });\n const ids: string[] = [];\n for (const resource of resources) {\n resourceKey = `${resource.kind}:${resource.assetId}`;\n if (resource.kind !== 'caption') {\n ids.push(sandbox.entities.ensureMedia(resource).contentEntityId);\n continue;\n }\n const existingCaptions = sandbox.entities\n .list()\n .filter(\n (row) =>\n row.entity_kind === 'caption' && (row.payload.external as JsonObject | undefined)?.key === resource.assetId,\n );\n if (existingCaptions.length) {\n if (existingCaptions.some((caption) => caption.payload.storageKey !== resource.storageKey))\n throw new Error('Conflicting Caption resource identity');\n ids.push(...existingCaptions.map((caption) => caption.entity_id));\n continue;\n }\n if (!resource.assetId.trim() || !resource.storageKey.trim() || !resource.segments.length)\n throw new Error('Caption resource requires a physical locator and timed segments');\n for (const segment of resource.segments) {\n if (\n typeof segment.text !== 'string' ||\n !Number.isFinite(segment.startMs) ||\n !Number.isFinite(segment.endMs) ||\n segment.startMs < 0 ||\n segment.endMs <= segment.startMs\n )\n throw new Error('Caption resource has invalid ASR text or timing');\n for (const word of segment.words ?? []) {\n if (\n typeof word.text !== 'string' ||\n !Number.isFinite(word.startMs) ||\n !Number.isFinite(word.endMs) ||\n word.startMs < segment.startMs ||\n word.endMs > segment.endMs ||\n word.endMs < word.startMs\n )\n throw new Error('Caption resource has invalid ASR word timing');\n }\n }\n const scriptId = stableId('entity', 'audio-script', resource.assetId);\n const segments = resource.segments.map((segment, index) => ({\n segmentId: stableId('segment', resource.assetId, String(index)),\n text: segment.text,\n }));\n const start = Math.min(...resource.segments.map((segment) => segment.startMs));\n const end = Math.max(...resource.segments.map((segment) => segment.endMs));\n // Each transcription is a complete independent script, not appended to the panel selection.\n sandbox.entities.create({ entity_id: scriptId, entity_kind: 'audio-script', payload: { segments } });\n const ranges = resource.segments.map((segment, index) => ({\n segmentId: segments[index]!.segmentId,\n startMs: segment.startMs,\n endMs: segment.endMs,\n }));\n for (const range of ranges) {\n const captionId = stableId('entity', 'caption', resource.assetId, range.segmentId);\n sandbox.entities.create({\n entity_id: captionId,\n entity_kind: 'caption',\n payload: {\n baseEntityIds: [scriptId],\n external: { system: 'memota', key: resource.assetId },\n storageKey: resource.storageKey,\n selection: { segmentId: range.segmentId },\n segmentRanges: [range],\n extent: { kind: 'bounded', start: range.startMs, end: range.endMs },\n sampling: 'native',\n coordinateSpace: 'milliseconds',\n },\n });\n ids.push(captionId);\n }\n const markerId = sandbox.entities.create({\n entity_id: stableId('entity', 'asr-marker', resource.assetId),\n entity_kind: 'sequence-marker',\n payload: {\n sourceRange: { start, end },\n duration: { mode: 'from-source' },\n segmentRanges: resource.segments.map((segment, index) => ({\n segmentId: segments[index]!.segmentId,\n startMs: segment.startMs,\n endMs: segment.endMs,\n })),\n wordRanges: resource.segments.flatMap((segment, index) =>\n (segment.words ?? []).map((word) => ({ ...word, segmentIndex: index })),\n ),\n },\n });\n sandbox.relations.link({\n relation_id: stableId('relation', 'asr-marker', resource.assetId),\n relation_kind: 'audio-script-marker',\n endpoint_0_entity_id: scriptId,\n endpoint_1_entity_id: markerId,\n });\n }\n const candidate = sandbox.buildPlan();\n if (candidate.commands.length && options.loadGenerationFacts) {\n const newIds = new Set(ids.filter((id) => !state.entities.some((row) => row.entity_id === id)));\n const facts = parseGenerationFacts(\n await options.loadGenerationFacts(\n options.docId,\n resources.map((item) => item.assetId),\n ),\n );\n const relations = planGeneratedRelations({\n baseState: state,\n state: candidate.rows,\n scopedMediaIds: newIds,\n facts,\n newRelationId: () => `relation_${globalThis.crypto.randomUUID()}`,\n });\n for (const relation of relations)\n sandbox.relations.linkGenerated({\n relation_id: relation.relation_id,\n output_entity_id: relation.endpoint_0_entity_id,\n input_entity_id: relation.endpoint_1_entity_id,\n trace: relation.trace,\n });\n }\n const plan = sandbox.buildPlan();\n if (!plan.commands.length) return ids;\n const committed = await client.commit(state.revision, plan.rows);\n for (const id of ids) {\n if (!committed.entities.some((entity) => entity.entity_id === id))\n throw new Error(`Resource entity ${id} was not confirmed by the merged document`);\n }\n return ids;\n}\n\nfunction stableId(prefix: string, ...parts: string[]): string {\n return `${prefix}_${createHash('sha256').update(JSON.stringify(parts)).digest('hex')}`;\n}\n"],"mappings":"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ACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;C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"}
1
+ {"version":3,"file":"index.mjs","names":["stableId","isRecord","isRecord"],"sources":["../src/document/compact-projection.ts","../src/sandbox/preview.ts","../src/sandbox/node-host.ts","../src/entity/caption-asset-assembly.ts","../src/entity/entity-contract.ts","../src/entity/entity-http-client.ts","../src/entity/generation-sync.ts","../src/sandbox/generated/entity-edit-sandbox-model-context.ts","../src/prompt.ts","../src/schema.ts","../src/session/commit-plan.ts","../src/host-tool.ts","../src/entity/materialize-resources.ts"],"sourcesContent":["import {\n effectiveVideoClipDurationMs,\n solveVideoDocument,\n speedOf,\n type PartKind,\n type PartUnion,\n type SpeedShift,\n type TrackItem,\n type TrackItemTimePosition,\n type VideoClipPart,\n type VideoDocument,\n} from '@mengine/medeo-client';\n\n/**\n * Compact text projection of a `VideoDocument` for sandbox ChangePlan\n * `preview` (and pipeline dry-run preview). Pure, runtime-neutral: solves\n * via `solveVideoDocument`, emits one header line plus one row per timeline\n * item (library orphans are never rendered). Row intervals and per-kind\n * effective durations align with `toReadViewPartLibrary` /\n * `fromVideoDocument`.\n */\n\nexport interface CompactProjectionOptions {\n /** Only render these parts (header still reports the full timeline total). Default = all. */\n onlyPartIds?: ReadonlySet<string>;\n /** Caption text preview truncation length. Default 24. */\n textPreviewLength?: number;\n}\n\nconst DEFAULT_TEXT_PREVIEW_LENGTH = 24;\n\n/** Kind tag shown in the first column (`video_clip` → `clip`). */\nfunction kindTag(kind: PartKind): string {\n return kind === 'video_clip' ? 'clip' : kind;\n}\n\n/** Lane label: `video_clip` tracks display as `main`, otherwise `parts_kind`. */\nfunction laneLabel(partsKind: PartKind): string {\n return partsKind === 'video_clip' ? 'main' : partsKind;\n}\n\n/** Speed token: absent → `1`; linear → numeric multiplier; anything else → `custom`. */\nfunction speedToken(speedShift: SpeedShift | undefined): string {\n if (speedShift == null) return '1';\n if (speedShift.category === 'linear') return String(speedOf(speedShift));\n return 'custom';\n}\n\nfunction effectiveDurationMs(part: PartUnion, timelineDurationMs: number): number {\n if (part.video_clip != null) return effectiveVideoClipDurationMs(part.video_clip);\n if (part.speech != null) return part.speech.media_duration_ms ?? 0;\n if (part.caption != null) return part.caption.initial_duration_ms ?? 0;\n if (part.bgm != null) return timelineDurationMs;\n return 0;\n}\n\nfunction truncateText(text: string, budget: number): string {\n if (text.length <= budget) return text;\n return `${text.slice(0, budget)}…`;\n}\n\nfunction anchorToken(timePosition: TrackItemTimePosition): string {\n if (timePosition.mode === 'anchored') {\n return `anchor=${timePosition.anchorPartId}+${timePosition.offsetMs}`;\n }\n if (timePosition.mode === 'absolute') return 'anchor=abs';\n return 'anchor=abs';\n}\n\nfunction clipAttrs(clip: VideoClipPart): string {\n const playIn = clip.play_in ?? 0;\n const playOut = clip.play_out ?? 0;\n return `media=${clip.origin_media_id ?? ''} trim=${playIn}-${playOut} speed=${speedToken(clip.speed_shift)} vol=${clip.volume ?? 0}`;\n}\n\nfunction partAttrs(part: PartUnion, item: TrackItem, textPreviewLength: number): string {\n if (part.video_clip != null) return clipAttrs(part.video_clip);\n if (part.speech != null) {\n return `${anchorToken(item.time_position)} dur=${part.speech.media_duration_ms ?? 0}`;\n }\n if (part.caption != null) {\n const preview = truncateText(part.caption.text ?? '', textPreviewLength);\n return `${anchorToken(item.time_position)} text=\"${preview}\"`;\n }\n if (part.bgm != null) return `vol=${part.bgm.volume ?? 0}`;\n return '';\n}\n\n/**\n * Render a `VideoDocument` as compact text: one header line plus one row per\n * timeline part (optionally filtered by `onlyPartIds`). Deterministic and\n * side-effect free — same document always yields the same string.\n */\nexport function renderCompactProjection(document: VideoDocument, options?: CompactProjectionOptions): string {\n const onlyPartIds = options?.onlyPartIds;\n const textPreviewLength = options?.textPreviewLength ?? DEFAULT_TEXT_PREVIEW_LENGTH;\n\n const solved = solveVideoDocument(document);\n const library = document.part_library ?? {};\n const tracks = document.tracks ?? [];\n\n let totalParts = 0;\n const rows: string[] = [];\n\n for (const track of tracks) {\n const partsKind = track.parts_kind;\n if (partsKind == null) continue;\n const lane = laneLabel(partsKind);\n const tag = kindTag(partsKind);\n\n for (const item of track.items ?? []) {\n totalParts += 1;\n const partId = item.part_id;\n if (onlyPartIds != null && !onlyPartIds.has(partId)) continue;\n\n const part = library[partId];\n if (part == null) continue;\n\n const abs = solved.absByPartId.get(partId) ?? 0;\n const dur = effectiveDurationMs(part, solved.durationMs);\n const attrs = partAttrs(part, item, textPreviewLength);\n rows.push(`${tag} ${partId} ${lane} [${abs},${abs + dur}) ${attrs}`);\n }\n }\n\n const header = `# draft=${document.meta.draft_id ?? ''} v=${document.meta.version ?? 0} duration=${solved.durationMs} parts=${totalParts} shown=${rows.length}`;\n return [header, ...rows].join('\\n');\n}\n","import type { JournalEntry, VideoDocument } from '@mengine/medeo-client';\n\nimport { renderCompactProjection } from '../document/compact-projection.ts';\n\n/**\n * Collect part ids referenced by a journal for compact preview filtering.\n * Walks known id-shaped payload keys (宁多勿少) and unions `generated_ids`.\n */\nconst PART_ID_KEYS = new Set([\n 'clip_id',\n 'clip_ids',\n 'before_clip_id',\n 'after_clip_id',\n 'speech_id',\n 'speech_ids',\n 'speech_part_id',\n 'caption_id',\n 'caption_ids',\n 'bgm_id',\n 'anchor_part_id',\n 'part_id',\n 'body_part_id',\n]);\n\n/** Extract every part id a journal entry touches (payload refs + minted ids). */\nexport function collectAffectedPartIds(journal: readonly JournalEntry[]): Set<string> {\n const ids = new Set<string>();\n for (const entry of journal) {\n for (const generated of entry.generated_ids ?? []) {\n if (generated.length > 0) ids.add(generated);\n }\n collectFromValue(entry.payload, ids);\n }\n return ids;\n}\n\nfunction collectFromValue(value: unknown, ids: Set<string>): void {\n if (value == null) return;\n if (Array.isArray(value)) {\n for (const item of value) collectFromValue(item, ids);\n return;\n }\n if (typeof value !== 'object') return;\n for (const [key, child] of Object.entries(value as Record<string, unknown>)) {\n if (PART_ID_KEYS.has(key)) {\n if (typeof child === 'string' && child.length > 0) ids.add(child);\n else if (Array.isArray(child)) {\n for (const item of child) {\n if (typeof item === 'string' && item.length > 0) ids.add(item);\n }\n }\n }\n collectFromValue(child, ids);\n }\n}\n\n/**\n * Render a ChangePlan preview: header + rows for journal-affected parts only.\n * Empty journal → empty `onlyPartIds` (header alone), matching the T2 contract.\n */\nexport function renderPreview(document: VideoDocument, journal: readonly JournalEntry[]): string {\n const onlyPartIds = journal.length === 0 ? new Set<string>() : collectAffectedPartIds(journal);\n return renderCompactProjection(document, { onlyPartIds });\n}\n","/// <reference types=\"node\" />\nimport { Worker } from 'node:worker_threads';\n\nimport type { JournalEntry, VideoDocument } from '@mengine/medeo-client';\n\nimport type { EntityAssetContent } from '../entity/entity-asset.ts';\nimport type { SandboxEntity } from '../entity/entity-contract.ts';\nimport type { EntityCommand, EntityStoreSnapshot } from '../entity/entity-contract.ts';\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 loadEntityAsset?: (entity: SandboxEntity) => Promise<EntityAssetContent>;\n document: VideoDocument;\n baseVersion: string;\n script: string;\n inputs?: Record<string, unknown>;\n /** Authoritative entity/relation rows and revision fetched for this document. */\n entityState?: EntityStoreSnapshot;\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: {\n ops: readonly JournalEntry[];\n entityCommands: readonly EntityCommand[];\n logs: string[];\n };\n };\n\ntype WorkerMessage =\n | { t: 'entity-asset'; requestId: number; entity: SandboxEntity }\n | { t: 'ready' }\n | { t: 'entry'; entry: JournalEntry }\n | { t: 'entity-entry'; command: EntityCommand }\n | { t: 'log'; line: string }\n | { t: 'truncate'; index: number }\n | { t: 'entity-truncate'; index: number }\n | {\n t: 'done';\n preview: string;\n opsCount: number;\n entityCommandsCount: number;\n loroUpdate?: string;\n entityBaseRevision: number;\n entityRows?: EntityStoreSnapshot;\n deletedEntityIds: readonly string[];\n deletedRelationIds: readonly string[];\n planKind: 'timeline' | 'entities';\n }\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 entityCommands: EntityCommand[] = [];\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 entityState: options.entityState,\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: {\n ops: ops.slice(),\n entityCommands: entityCommands.slice(),\n logs: logs.slice(),\n },\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 === 'entity-asset') {\n void (async () => {\n try {\n if (!options.loadEntityAsset) throw new Error('Entity Asset loader is unavailable');\n const result = await options.loadEntityAsset(message.entity);\n if (!settled) worker.postMessage({ t: 'entity-asset-result', requestId: message.requestId, result });\n } catch (error) {\n if (!settled)\n worker.postMessage({\n t: 'entity-asset-result',\n requestId: message.requestId,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n })();\n return;\n }\n if (message.t === 'entry') {\n ops.push(message.entry);\n return;\n }\n if (message.t === 'entity-entry') {\n entityCommands.push(message.command);\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 === 'entity-truncate') {\n entityCommands.length = Math.max(0, Math.min(message.index, entityCommands.length));\n return;\n }\n if (message.t === 'done') {\n if (message.opsCount !== ops.length || message.entityCommandsCount !== entityCommands.length) {\n finish({\n ok: false,\n phase: 'runtime',\n error: {\n message:\n `journal count mismatch: worker reported timeline=${message.opsCount}, entities=${message.entityCommandsCount}; ` +\n `host collected timeline=${ops.length}, entities=${entityCommands.length}`,\n },\n partial: {\n ops: ops.slice(),\n entityCommands: entityCommands.slice(),\n logs: logs.slice(),\n },\n });\n return;\n }\n finish({\n ok: true,\n plan: {\n plan_kind: message.planKind,\n doc_id: options.document.meta.draft_id ?? '',\n base_version: options.baseVersion,\n ops: ops.slice(),\n ...(message.loroUpdate ? { loro_update: message.loroUpdate } : {}),\n entity_base_revision: message.entityBaseRevision,\n entity_commands: entityCommands.slice(),\n ...(message.entityRows !== undefined ? { entity_rows: message.entityRows } : {}),\n deleted_entity_ids: message.deletedEntityIds,\n deleted_relation_ids: message.deletedRelationIds,\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: {\n ops: ops.slice(),\n entityCommands: entityCommands.slice(),\n logs: logs.slice(),\n },\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: {\n ops: ops.slice(),\n entityCommands: entityCommands.slice(),\n logs: logs.slice(),\n },\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: {\n ops: ops.slice(),\n entityCommands: entityCommands.slice(),\n logs: logs.slice(),\n },\n });\n });\n });\n}\n","import { createHash } from 'node:crypto';\n\nimport type { SandboxEntity, SandboxRelation } from './entity-contract.ts';\nimport type { EntityHttpClient } from './entity-http-client.ts';\n\n/** Optional physical artifact registered for one immutable Caption identity. */\nexport interface CaptionAssetFact {\n readonly captionEntityId: string;\n readonly assetId: string;\n readonly storageKey: string;\n}\n\n/** Host-only lookup. Missing facts mean the Caption has no physical artifact. */\nexport type CaptionAssetsLoader = (\n docId: string,\n captionEntityIds: readonly string[],\n) => Promise<readonly CaptionAssetFact[]>;\n\nexport interface CaptionAssetAssemblyOutcome {\n readonly status: 'applied' | 'current' | 'failed';\n readonly message?: string;\n}\n\n/** Assemble optional infrastructure after business execution, using exact entity identity. */\nexport async function assembleCaptionAssets(input: {\n client: EntityHttpClient;\n docId: string;\n loadAssets: CaptionAssetsLoader;\n}): Promise<CaptionAssetAssemblyOutcome> {\n try {\n const state = await input.client.fetchState();\n const candidates = state.entities.filter(\n (entity) =>\n entity.entity_kind === 'caption' &&\n !state.relations.some(\n (relation) =>\n relation.relation_kind === 'physical-asset' &&\n (relation.endpoint_0_entity_id === entity.entity_id || relation.endpoint_1_entity_id === entity.entity_id),\n ),\n );\n if (!candidates.length) return { status: 'current' };\n const ids = new Set(candidates.map((entity) => entity.entity_id));\n const facts = await input.loadAssets(input.docId, [...ids]);\n const entities: SandboxEntity[] = [...state.entities];\n const relations: SandboxRelation[] = [...state.relations];\n const bound = new Map<string, string>();\n for (const fact of facts) {\n if (!ids.has(fact.captionEntityId) || !trimmed(fact.assetId) || !trimmed(fact.storageKey))\n throw new Error('Caption Asset fact must identify a requested Caption and a real Asset locator');\n const previous = bound.get(fact.captionEntityId);\n if (previous !== undefined) {\n if (previous !== fact.assetId) throw new Error(`Conflicting Assets for Caption ${fact.captionEntityId}`);\n continue;\n }\n bound.set(fact.captionEntityId, fact.assetId);\n const matches = entities.filter((entity) => {\n const external = entity.payload.external;\n return (\n external !== null &&\n typeof external === 'object' &&\n !Array.isArray(external) &&\n external.system === 'memota' &&\n external.key === fact.assetId\n );\n });\n if (matches.length > 1 || (matches[0] && matches[0].entity_kind !== 'asset'))\n throw new Error(`Conflicting resource identity for Caption Asset ${fact.assetId}`);\n let asset = matches[0];\n if (asset && asset.payload.storageKey !== fact.storageKey)\n throw new Error(`Conflicting storage key for Caption Asset ${fact.assetId}`);\n if (!asset) {\n asset = {\n entity_id: stableId('asset', fact.assetId),\n entity_kind: 'asset',\n payload: { external: { system: 'memota', key: fact.assetId }, storageKey: fact.storageKey },\n };\n if (entities.some((entity) => entity.entity_id === asset!.entity_id))\n throw new Error('Caption Asset identity collision');\n entities.push(asset);\n }\n relations.push({\n relation_id: stableId('relation', fact.captionEntityId, asset.entity_id),\n relation_kind: 'physical-asset',\n endpoint_0_entity_id: fact.captionEntityId,\n endpoint_1_entity_id: asset.entity_id,\n metadata: {},\n trace: {},\n });\n }\n if (!bound.size) return { status: 'current' };\n await input.client.commit(state.revision, { ...state, entities, relations });\n return { status: 'applied' };\n } catch (error) {\n return { status: 'failed', message: error instanceof Error ? error.message : String(error) };\n }\n}\n\nfunction stableId(prefix: string, ...parts: string[]): string {\n return `${prefix}_${createHash('sha256').update(JSON.stringify(parts)).digest('hex')}`;\n}\nfunction trimmed(value: string): boolean {\n return typeof value === 'string' && value.length > 0 && value.trim() === value;\n}\n","import type { FieldChange, MediaAssetFact } from '@mengine/medeo-client';\n\nexport type JsonPrimitive = string | number | boolean | null;\nexport type JsonValue = JsonPrimitive | JsonObject | JsonValue[];\nexport interface JsonObject {\n [key: string]: JsonValue;\n}\n\nexport type KnownEntityKind =\n | 'axvideo'\n | 'timeline'\n | 'track'\n | 'clip'\n | 'asset'\n | 'video'\n | 'audio'\n | 'voice'\n | 'image'\n | 'sequence-marker'\n | 'viewport'\n | 'audio-script'\n | 'phonetic-script'\n | 'caption';\n\n/** Asset identity, either an old physical-only row or a directly composed media variant. */\nexport type ResourceEntityKind = 'image' | 'video' | 'audio' | 'voice';\n\nexport const KNOWN_ENTITY_KINDS: readonly KnownEntityKind[] = [\n 'axvideo',\n 'timeline',\n 'track',\n 'clip',\n 'asset',\n 'video',\n 'audio',\n 'voice',\n 'image',\n 'sequence-marker',\n 'viewport',\n 'audio-script',\n 'phonetic-script',\n 'caption',\n];\n\nexport type KnownRelationKind =\n | 'timeline-track'\n | 'track-clip'\n | 'clip-marker'\n | 'marker-content'\n | 'axvideo-marker'\n | 'marker-timeline'\n | 'physical-asset'\n | 'generated'\n | 'caption-alignment'\n | 'clip-anchor'\n | 'phonetic-script-render'\n | 'audio-script-source'\n | 'audio-script-marker';\n\nexport const KNOWN_RELATION_KINDS: readonly KnownRelationKind[] = [\n 'timeline-track',\n 'track-clip',\n 'clip-marker',\n 'marker-content',\n 'axvideo-marker',\n 'marker-timeline',\n 'physical-asset',\n 'generated',\n 'caption-alignment',\n 'clip-anchor',\n 'phonetic-script-render',\n 'audio-script-source',\n 'audio-script-marker',\n];\n\nexport type AuthorableRelationKind = KnownRelationKind;\n\nexport interface BoundedNativeSequencePayload extends JsonObject {\n /** Factual coordinates from recalled media metadata; never invent an end/duration. */\n extent: { kind: 'bounded'; start: number; end: number };\n sampling: 'native';\n coordinateSpace: JsonValue;\n}\n\nexport interface UnboundedConstantSequencePayload extends JsonObject {\n extent: { kind: 'unbounded'; start: number };\n sampling: 'constant';\n coordinateSpace: JsonValue;\n}\n\nexport interface BoundedDerivedSequencePayload extends JsonObject {\n extent: { kind: 'bounded'; start: number; end: number };\n sampling: 'derived';\n coordinateSpace: JsonValue;\n}\n\nexport type ScriptTextSegment = JsonObject & {\n segmentId: string;\n text: string;\n language?: string;\n};\n\nexport type MediaAssetPayload = JsonObject & {\n external: { system: 'memota' | 'memota-speech'; key: string };\n storageKey?: string;\n};\n\nexport type CaptionTextSelection = JsonObject & {\n segmentId: string;\n /** Half-open Unicode code-point range within the selected source segment. */\n textRange?: { start: number; end: number };\n};\n\n/** Read result only: base text is assembled from the real AudioScript row. */\nexport interface ComposedScriptContent {\n audio_script_entity_id: string;\n text: string;\n segments: ScriptTextSegment[];\n}\n\nexport interface ComposedPhoneticContent extends ComposedScriptContent {\n phonemeScript?: string;\n prosody?: JsonObject;\n}\n\nexport interface EntityPayloadByKind {\n axvideo: BoundedDerivedSequencePayload;\n timeline: JsonObject;\n track: JsonObject & { hidden?: boolean; role?: string };\n clip: JsonObject;\n /** Physical resource fields; never a copy of Caption content. */\n asset: JsonObject;\n video: BoundedNativeSequencePayload & MediaAssetPayload;\n audio: BoundedNativeSequencePayload & MediaAssetPayload;\n voice: BoundedNativeSequencePayload & MediaAssetPayload;\n image: UnboundedConstantSequencePayload & MediaAssetPayload;\n 'sequence-marker': JsonObject & {\n sourceRange: { start: number; end: number };\n targetRange?: { start: number; end: number };\n duration: { mode: 'from-source' } | { mode: 'fixed'; value: number };\n timeRemapping?: JsonValue;\n anchorOffset?: number;\n durationPolicy?: 'timeline';\n /** Directly assigned AudioScript annotation times; annotation Markers only. */\n segmentRanges?: { segmentId: string; startMs: number; endMs: number }[];\n };\n viewport: JsonObject;\n 'audio-script': JsonObject & { segments: ScriptTextSegment[] };\n 'phonetic-script': JsonObject & { baseEntityIds: string[]; phonemeScript?: string; prosody?: JsonObject };\n caption: BoundedNativeSequencePayload & {\n baseEntityIds: string[];\n selection: CaptionTextSelection;\n style?: JsonObject;\n segmentRanges?: { segmentId: string; startMs: number; endMs: number }[];\n };\n}\n\n/** Stored own fields; a variant may obtain required content fields from its declared bases. */\nexport type StoredEntityPayload<K extends KnownEntityKind> =\n | EntityPayloadByKind[K]\n | (K extends 'caption' | 'voice' ? JsonObject & Pick<MediaAssetPayload, 'external'> : never)\n | (JsonObject & Partial<EntityPayloadByKind[K]> & { baseEntityIds: string[] });\n\nexport interface SandboxEntity<K extends KnownEntityKind = KnownEntityKind> {\n entity_id: string;\n entity_kind: K;\n payload: StoredEntityPayload<K>;\n}\n\nexport interface SandboxRelation {\n relation_id: string;\n relation_kind: KnownRelationKind;\n endpoint_0_entity_id: string;\n endpoint_1_entity_id: string;\n metadata: JsonObject;\n trace: JsonObject;\n}\n\nexport interface EntityStoreSnapshot {\n /** Causal compiler baseline; required for publishing edits. */\n loroSnapshot?: string;\n revision: number;\n /** Current AudioScript version attached to the project; initialized projects always attach a script, possibly empty. */\n audioScriptEntityId: string | null;\n entities: SandboxEntity[];\n relations: SandboxRelation[];\n}\n\nexport type CreateEntityInput = {\n [K in KnownEntityKind]: {\n entity_id?: string;\n entity_kind: K;\n payload: StoredEntityPayload<K>;\n };\n}[KnownEntityKind];\n\n/** Patch supplied fields on the assembled entity; omitted fields remain unchanged. */\nexport interface UpdateEntityInput {\n entity_id: string;\n payload: JsonObject;\n}\n\nexport interface DeleteEntityInput {\n entity_id: string;\n}\n\nexport type EmptyRelationKind =\n | 'timeline-track'\n | 'track-clip'\n | 'clip-marker'\n | 'marker-content'\n | 'axvideo-marker'\n | 'marker-timeline'\n | 'audio-script-marker';\n\ninterface LinkRelationBase {\n relation_id?: string;\n endpoint_0_entity_id: string;\n endpoint_1_entity_id: string;\n trace?: JsonObject;\n}\n\nexport interface LinkRelationInput extends LinkRelationBase {\n relation_kind: KnownRelationKind;\n metadata?: JsonObject;\n}\nexport interface EntityUpdateInput {\n entity_id: string;\n changes: FieldChange[];\n}\nexport interface RelationUpdateInput {\n relation_id: string;\n changes: FieldChange[];\n}\n/** Tokens have no script-authored data; only the creating session can validate them. */\nexport interface EntitySandboxCheckpoint {\n readonly __checkpoint: unique symbol;\n}\n\nexport interface LinkGeneratedRelationInput {\n relation_id?: string;\n output_entity_id: string;\n input_entity_id: string;\n trace?: JsonObject;\n}\n\nexport interface LinkClipAnchorRelationInput {\n relation_id?: string;\n child_clip_entity_id: string;\n host_clip_entity_id: string;\n trace?: JsonObject;\n}\n\nexport interface LinkPhoneticScriptRenderRelationInput {\n relation_id?: string;\n output_entity_id: string;\n phonetic_script_entity_id: string;\n trace?: JsonObject;\n}\n\n/** `audio-script-source(script, source)`; the script was transcribed from the source media. */\nexport interface LinkAudioScriptSourceRelationInput {\n relation_id?: string;\n script_entity_id: string;\n source_entity_id: string;\n trace?: JsonObject;\n}\n\nexport interface UnlinkRelationInput {\n relation_id: string;\n}\n\nexport type EntityCommand =\n | { kind: 'create-entity'; entity: SandboxEntity }\n | { kind: 'update-entity'; entity_id: string; payload: JsonObject }\n | { kind: 'change-entity'; entity_id: string; changes: FieldChange[] }\n | { kind: 'change-relation'; relation_id: string; changes: FieldChange[] }\n | { kind: 'delete-entity'; entity_id: string }\n | { kind: 'link-relation'; relation: SandboxRelation }\n | { kind: 'unlink-relation'; relation_id: string };\n\nexport interface EntityPlanState {\n base_revision: number;\n commands: readonly EntityCommand[];\n rows: EntityStoreSnapshot;\n deleted_entity_ids: readonly string[];\n deleted_relation_ids: readonly string[];\n}\n\nexport interface EntityStateWireResponse {\n loro_snapshot: string;\n doc_id: string;\n audio_script_entity_id: string | null;\n revision: number;\n rows: {\n entities: SandboxEntity[];\n relations: SandboxRelation[];\n };\n}\n\nexport interface EntityFacade {\n /** Read complete assembled fields; returned objects are snapshots. Use update to persist edits. */\n list(): SandboxEntity[];\n get(entityId: string): SandboxEntity | null;\n /** Find document resources by external Memota asset id, including directly composed media variants. */\n findByAssetId(assetId: string): SandboxEntity<ResourceEntityKind>[];\n /** Assemble selected Caption text; missing composition is an error. */\n readCaptionContent(entityId: string): ComposedScriptContent;\n /** Assemble base text and pronunciation fields before generating Voice. */\n readPhoneticScriptContent(entityId: string): ComposedPhoneticContent;\n create(input: CreateEntityInput): string;\n /** Patch assembled fields, routing inherited fields to their declaring entity. */\n update(input: UpdateEntityInput): void;\n changeFields(input: EntityUpdateInput): void;\n /** Explicitly declare own fields, overriding unambiguous bases without modifying them. Ordinary edits use update. */\n declareFields(input: UpdateEntityInput): void;\n /** Delete an Entity only after all of its incident Relations have been explicitly unlinked. */\n delete(input: DeleteEntityInput): void;\n /** Get or create one typed Asset by factual external id and return its single content identity. Never creates a Clip. */\n ensureMedia(fact: MediaAssetFact): { contentEntityId: string };\n}\n\nexport interface RelationFacade {\n list(): SandboxRelation[];\n /** Incident lookup is endpoint-agnostic; persisted endpoint positions stay unchanged. */\n of(entityId: string, relationKind?: KnownRelationKind): SandboxRelation[];\n /** Link existing entities through ordinary associations; variant bases are stored directly on the variant. */\n link(input: LinkRelationInput): string;\n /** Author ordered generated(output,input); generic link() deliberately rejects this kind. */\n linkGenerated(input: LinkGeneratedRelationInput): string;\n /** Author ordered clip-anchor(child,host) without positional endpoint ambiguity. */\n linkClipAnchor(input: LinkClipAnchorRelationInput): string;\n /** Author ordered phonetic-script-render(output,script) without positional endpoint ambiguity. */\n linkPhoneticScriptRender(input: LinkPhoneticScriptRenderRelationInput): string;\n /** Author ordered audio-script-source(script,source) without positional endpoint ambiguity. */\n linkAudioScriptSource(input: LinkAudioScriptSourceRelationInput): string;\n /** Remove a Relation by identity; endpoint replacement is an explicit unlink plus link. */\n unlink(input: UnlinkRelationInput): void;\n update(input: RelationUpdateInput): void;\n}\n\n/** Business editing surface. Reads are assembled snapshots; writes preserve native operation intent. */\nexport interface BusinessEntityFacade {\n list(): SandboxEntity[];\n get(entityId: string): SandboxEntity | null;\n create(input: Exclude<CreateEntityInput, { entity_kind: 'asset' }>): string;\n update(input: EntityUpdateInput): void;\n declareFields(input: UpdateEntityInput): void;\n delete(input: DeleteEntityInput): void;\n}\n\n/** Endpoint order is retained; each relation kind defines its endpoint semantics. */\nexport interface BusinessRelationFacade {\n list(): SandboxRelation[];\n of(entityId: string, relationKind?: KnownRelationKind): SandboxRelation[];\n link(input: LinkRelationInput): string;\n update(input: RelationUpdateInput): void;\n unlink(input: UnlinkRelationInput): void;\n}\n","import { bytesToBase64, compileEntityRows, base64ToBytes } from '@mengine/medeo-client';\nimport { createEntityId, createRelationId } from '@mengine/medeo-dsl';\n\nimport {\n KNOWN_ENTITY_KINDS,\n KNOWN_RELATION_KINDS,\n type EntityStateWireResponse,\n type EntityStoreSnapshot,\n type JsonObject,\n type SandboxEntity,\n type SandboxRelation,\n} from './entity-contract.ts';\n\nconst API_PREFIX = '/api/mengine/v1';\nconst entityKinds = new Set<string>(KNOWN_ENTITY_KINDS);\nconst relationKinds = new Set<string>(KNOWN_RELATION_KINDS);\n\nexport interface EntityHttpClientOptions {\n docId: string;\n httpOrigin: string;\n authToken?: string | (() => string | undefined);\n userId?: string | (() => string | undefined);\n fetchImpl?: typeof fetch;\n}\n\nexport interface EntityCommitDeletions {\n deleted_entity_ids?: readonly string[];\n deleted_relation_ids?: readonly string[];\n}\n\nexport class MengineEntityHttpRequestError extends Error {\n constructor(\n readonly status: number,\n readonly payload: unknown,\n ) {\n super(`mengine entity-state request failed: ${status}`);\n this.name = 'MengineEntityHttpRequestError';\n }\n}\n\n/** Narrow authenticated client for the Loro entity endpoint. */\nexport class EntityHttpClient {\n private readonly fetchImpl: typeof fetch;\n\n constructor(private readonly options: EntityHttpClientOptions) {\n this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);\n }\n\n async fetchState(): Promise<EntityStoreSnapshot> {\n return toSnapshot(await this.requestJson({ method: 'GET' }), this.options.docId);\n }\n\n async commit(\n _transportSequence: number,\n state: EntityStoreSnapshot,\n _deletions: EntityCommitDeletions = {},\n ): Promise<EntityStoreSnapshot> {\n if (!state.loroSnapshot) throw new Error('Entity edit is missing its causal Loro baseline');\n // The baseline comes from this plan, never a freshly fetched replacement.\n const rows = {\n entities: state.entities.map((row) => ({\n entityId: createEntityId(row.entity_id),\n entityKind: row.entity_kind,\n payload: row.payload,\n })),\n relations: state.relations.map((row) => ({\n relationId: createRelationId(row.relation_id),\n relationKind: row.relation_kind,\n endpoint0EntityId: createEntityId(row.endpoint_0_entity_id),\n endpoint1EntityId: createEntityId(row.endpoint_1_entity_id),\n metadata: row.metadata,\n trace: row.trace,\n })),\n } as Parameters<typeof compileEntityRows>[1];\n const compiled = compileEntityRows(base64ToBytes(state.loroSnapshot), rows);\n return this.commitUpdate(bytesToBase64(compiled.update));\n }\n\n async commitUpdate(update: string): Promise<EntityStoreSnapshot> {\n return toSnapshot(await this.requestJson({ method: 'POST', body: JSON.stringify({ update }) }), this.options.docId);\n }\n\n private async requestJson(init: RequestInit): Promise<unknown> {\n const response = await this.fetchImpl(this.endpoint(), { ...init, headers: this.headers() });\n const payload = await safeReadJson(response);\n if (!response.ok) throw new MengineEntityHttpRequestError(response.status, payload);\n return payload;\n }\n\n private headers(): Headers {\n const headers = new Headers({ accept: 'application/json', 'content-type': 'application/json' });\n const authToken = typeof this.options.authToken === 'function' ? this.options.authToken() : this.options.authToken;\n if (authToken != null && authToken !== '') headers.set('authorization', `Bearer ${authToken}`);\n const userId = typeof this.options.userId === 'function' ? this.options.userId() : this.options.userId;\n if (userId != null && userId !== '') headers.set('medeo-user-id', userId);\n return headers;\n }\n\n private endpoint(): string {\n const origin = this.options.httpOrigin.replace(/\\/$/, '');\n return `${origin}${API_PREFIX}/docs/${encodeURIComponent(this.options.docId)}/entity-state`;\n }\n}\n\nfunction toSnapshot(value: unknown, expectedDocId: string): EntityStoreSnapshot {\n if (!isRecord(value) || typeof value.doc_id !== 'string' || !isNonNegativeInteger(value.revision)) {\n throw new Error('invalid entity-state response envelope');\n }\n if (value.doc_id !== expectedDocId) {\n throw new Error(`entity-state response doc_id mismatch: expected \"${expectedDocId}\"`);\n }\n if (!isRecord(value.rows) || !Array.isArray(value.rows.entities) || !Array.isArray(value.rows.relations)) {\n throw new Error('invalid entity-state response rows');\n }\n if (value.audio_script_entity_id === null) throw new Error('Document AudioScript is not initialized');\n if (!isTrimmed(value.audio_script_entity_id)) throw new Error('invalid document AudioScript identity');\n if (typeof value.loro_snapshot !== 'string') throw new Error('Missing causal Loro snapshot');\n const response = value as unknown as EntityStateWireResponse;\n if (\n response.audio_script_entity_id !== null &&\n !response.rows.entities.some(\n (entity) => entity.entity_id === response.audio_script_entity_id && entity.entity_kind === 'audio-script',\n )\n )\n throw new Error('Document AudioScript must name the project AudioScript');\n return {\n loroSnapshot: response.loro_snapshot,\n revision: response.revision,\n audioScriptEntityId: response.audio_script_entity_id,\n entities: response.rows.entities.map(parseEntity),\n relations: response.rows.relations.map(parseRelation),\n };\n}\n\nfunction parseEntity(value: unknown): SandboxEntity {\n if (\n !isRecord(value) ||\n !isTrimmed(value.entity_id) ||\n typeof value.entity_kind !== 'string' ||\n !entityKinds.has(value.entity_kind) ||\n !isJsonObject(value.payload)\n ) {\n throw new Error('invalid Entity row in entity-state response');\n }\n return structuredClone(value) as unknown as SandboxEntity;\n}\n\nfunction parseRelation(value: unknown): SandboxRelation {\n if (\n !isRecord(value) ||\n !isTrimmed(value.relation_id) ||\n typeof value.relation_kind !== 'string' ||\n !relationKinds.has(value.relation_kind) ||\n !isTrimmed(value.endpoint_0_entity_id) ||\n !isTrimmed(value.endpoint_1_entity_id) ||\n !isJsonObject(value.metadata) ||\n !isJsonObject(value.trace)\n ) {\n throw new Error('invalid Relation row in entity-state response');\n }\n return structuredClone(value) as unknown as SandboxRelation;\n}\n\nfunction isJsonObject(value: unknown): value is JsonObject {\n return isJsonValue(value, new Set()) && isRecord(value);\n}\n\nfunction isJsonValue(value: unknown, ancestors: Set<object>): boolean {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return true;\n if (typeof value === 'number') return Number.isFinite(value);\n if (typeof value !== 'object' || ancestors.has(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) return false;\n ancestors.add(value);\n const valid = Array.isArray(value)\n ? value.every((item) => isJsonValue(item, ancestors))\n : Object.values(value).every((item) => isJsonValue(item, ancestors));\n ancestors.delete(value);\n return valid;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction isTrimmed(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0 && value.trim() === value;\n}\n\nfunction isNonNegativeInteger(value: unknown): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;\n}\n\nasync function safeReadJson(response: Response): Promise<unknown> {\n const text = await response.text();\n if (text.length === 0) return null;\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { isMediaAssetVariantKind } from '@mengine/medeo-dsl';\n\nimport type { EntityCommand, EntityStoreSnapshot, SandboxRelation } from './entity-contract.ts';\nimport type { EntityHttpClient } from './entity-http-client.ts';\n\n/**\n * External systems whose asset entities carry a factual Memota identity.\n * Voice results use the speech system; every other medium uses `memota`.\n */\nconst ASSET_SYSTEMS: ReadonlySet<string> = new Set(['memota', 'memota-speech']);\n\n/** Factual generation lineage for recalled Memota assets, supplied by the host. */\nexport interface AssetGenerationFact {\n /** External asset id of the generation output (memota asset or speech result id). */\n readonly outputAssetId: string;\n /** Factual input asset ids; empty for text-only generation. */\n readonly inputAssetIds: readonly string[];\n}\n\n/**\n * Host callback resolving lineage by external asset id. Implementations return\n * every known generation record involving the given ids in either role; an\n * empty array means no known lineage and a rejection means the lineage query\n * failed. Entity and Relation semantics stay inside this package.\n */\nexport type GenerationFactsLoader = (\n docId: string,\n assetIds: readonly string[],\n) => Promise<readonly AssetGenerationFact[]>;\n\n/**\n * Outcome of the post-commit lineage sync. `failed` is always also surfaced as\n * a `generation_sync_failed` warning so an unavailable lineage query is never\n * presented as synced state.\n */\nexport interface GenerationSyncOutcome {\n /**\n * applied: new generated Relations were committed.\n * current: the query succeeded and nothing was missing (no created asset,\n * single side absent, text-only generation, or pair already linked).\n * failed: the host query or the sync commit failed.\n */\n readonly status: 'applied' | 'current' | 'failed';\n readonly created_relation_ids?: readonly string[];\n readonly message?: string;\n}\n\nexport interface SyncGeneratedRelationsInput {\n readonly client: EntityHttpClient;\n readonly docId: string;\n /** Causal entity state the committed plan was based on. */\n readonly baseState: EntityStoreSnapshot;\n /** Entity commands of the committed plan; they scope which lineage is queried. */\n readonly entityCommands: readonly EntityCommand[];\n readonly loadFacts: GenerationFactsLoader;\n}\n\n/** Validate host-supplied facts; a malformed record fails the whole query. */\nexport function parseGenerationFacts(value: unknown): AssetGenerationFact[] {\n if (!Array.isArray(value)) throw new Error('generation facts must be an array');\n return value.map((item): AssetGenerationFact => {\n if (!isRecord(item)) throw new Error('each generation fact must be an object');\n const { outputAssetId, inputAssetIds } = item;\n if (typeof outputAssetId !== 'string' || outputAssetId.length === 0 || outputAssetId.trim() !== outputAssetId) {\n throw new Error('generation fact outputAssetId must be a non-empty trimmed string');\n }\n if (!Array.isArray(inputAssetIds)) {\n // A missing field is a malformed record, not text-only evidence: only an\n // explicit empty array states \"no factual inputs\" (pure text source).\n throw new Error('generation fact inputAssetIds must be an array (explicit [] means text-only)');\n }\n const inputs = inputAssetIds;\n for (const input of inputs) {\n if (typeof input !== 'string' || input.length === 0 || input.trim() !== input) {\n throw new Error('generation fact inputAssetIds entries must be non-empty trimmed strings');\n }\n }\n return { outputAssetId, inputAssetIds: [...inputs] };\n });\n}\n\n/**\n * Resource identities newly introduced by the edit. Asset identity is immutable;\n * Clip placement and display metadata updates are not new generation sources.\n * Untouched/deleted lineage is never resurrected.\n */\nexport interface GenerationSyncScope {\n readonly scopedMediaIds: ReadonlySet<string>;\n readonly queryAssetKeys: readonly string[];\n}\n\nexport function planGenerationScope(\n base: EntityStoreSnapshot,\n commands: readonly EntityCommand[],\n state: EntityStoreSnapshot,\n): GenerationSyncScope {\n const touchedIds = new Set<string>();\n for (const command of commands) {\n if (command.kind === 'create-entity' && isMediaAssetVariantKind(command.entity.entity_kind)) {\n touchedIds.add(command.entity.entity_id);\n }\n }\n const beforeByKey = resolveMediaByAssetKey(base);\n const scoped = new Set<string>();\n const queryKeys = new Set<string>();\n for (const [key, mediaIds] of resolveMediaByAssetKey(state)) {\n const previousIds = new Set(beforeByKey.get(key) ?? []);\n for (const id of mediaIds) {\n if (!touchedIds.has(id) || previousIds.has(id)) continue;\n scoped.add(id);\n queryKeys.add(key);\n }\n }\n return { scopedMediaIds: scoped, queryAssetKeys: [...queryKeys].sort() };\n}\n\n/**\n * Ordered generated(output,input) Relations missing from `state` for the given\n * factual records. Both endpoints must already exist and match their own Asset\n * identities, and the pair must involve a media Entity the plan\n * newly fact-exposed (`scopedMediaIds`): lineage scopes to the commit's diff,\n * so a pair the user deleted between untouched entities stays deleted. A pair\n * the facts already resolved against the plan's base state is likewise skipped.\n * One-sided facts, text-only records, self pairs, and already-linked pairs are\n * skipped. Duplicate records collapse to one Relation.\n */\nexport function planGeneratedRelations(input: {\n baseState: EntityStoreSnapshot;\n state: EntityStoreSnapshot;\n scopedMediaIds: ReadonlySet<string>;\n facts: readonly AssetGenerationFact[];\n newRelationId: () => string;\n}): SandboxRelation[] {\n const { state, facts } = input;\n const scoped = input.scopedMediaIds;\n const factKeys = new Set(facts.flatMap((fact) => [fact.outputAssetId, ...fact.inputAssetIds]));\n const mediaByAssetKey = resolveMediaByAssetKey(state, factKeys);\n const baseResolvable = new Set(resolvablePairs(resolveMediaByAssetKey(input.baseState, factKeys), facts));\n const linkedPairs = new Set(\n state.relations\n .filter((relation) => relation.relation_kind === 'generated')\n .map((relation) => pairKey(relation.endpoint_0_entity_id, relation.endpoint_1_entity_id)),\n );\n const relations: SandboxRelation[] = [];\n for (const fact of facts) {\n for (const outputId of mediaByAssetKey.get(fact.outputAssetId) ?? []) {\n for (const inputAssetId of fact.inputAssetIds) {\n for (const inputId of mediaByAssetKey.get(inputAssetId) ?? []) {\n if (outputId === inputId) continue;\n if (!scoped.has(outputId) && !scoped.has(inputId)) continue;\n const pair = pairKey(outputId, inputId);\n if (linkedPairs.has(pair) || baseResolvable.has(pair)) continue;\n linkedPairs.add(pair);\n relations.push({\n relation_id: input.newRelationId(),\n relation_kind: 'generated',\n endpoint_0_entity_id: outputId,\n endpoint_1_entity_id: inputId,\n metadata: {},\n trace: { synced_by: 'generation-sync' },\n });\n }\n }\n }\n }\n return relations;\n}\n\n/**\n * Sync generation lineage after a confirmed entity commit. Any failure is\n * returned as a `failed` outcome instead of thrown, so the already-durable\n * commit result is never masked; a successful query that finds nothing is\n * `current`. Asset identities are immutable, so facts are queried once. The native update retains its causal baseline and merges without whole-state retries; deleted endpoints are never recreated.\n */\nexport async function syncGeneratedRelations(input: SyncGeneratedRelationsInput): Promise<GenerationSyncOutcome> {\n const { client, docId, baseState, entityCommands, loadFacts } = input;\n try {\n const state = await client.fetchState();\n const scope = planGenerationScope(baseState, entityCommands, state);\n if (scope.queryAssetKeys.length === 0) return { status: 'current' };\n const facts = parseGenerationFacts(await loadFacts(docId, scope.queryAssetKeys));\n const relations = planGeneratedRelations({\n baseState,\n state,\n scopedMediaIds: scope.scopedMediaIds,\n facts,\n newRelationId: mintRelationId,\n });\n if (relations.length === 0) return { status: 'current' };\n const committed = await client.commit(state.revision, { ...state, relations: [...state.relations, ...relations] });\n const active = new Set(committed.relations.map((relation) => relation.relation_id));\n const created = relations.map((relation) => relation.relation_id).filter((id) => active.has(id));\n return created.length ? { status: 'applied', created_relation_ids: created } : { status: 'current' };\n } catch (error) {\n return { status: 'failed', message: `generation lineage query failed: ${errorMessage(error)}` };\n }\n}\n\ninterface AssetLike {\n entity_id: string;\n entity_kind: string;\n payload: unknown;\n}\n\nfunction assetKeyOf(entity: AssetLike): string | undefined {\n if (!isMediaAssetVariantKind(entity.entity_kind)) return undefined;\n const external = (entity.payload as Record<string, unknown> | undefined)?.external;\n if (external == null || typeof external !== 'object' || Array.isArray(external)) return undefined;\n const { system, key } = external as Record<string, unknown>;\n if (typeof system !== 'string' || !ASSET_SYSTEMS.has(system)) return undefined;\n if (typeof key !== 'string' || key.length === 0 || key.trim() !== key) return undefined;\n return key;\n}\n\n/** Media variants own their Asset locator; generation lookup never follows Relations. */\nfunction resolveMediaByAssetKey(state: EntityStoreSnapshot, factKeys?: ReadonlySet<string>): Map<string, string[]> {\n // The host history contract carries bare IDs, not namespaces. Never turn an\n // ambiguous ID into a Cartesian product of unrelated speech/media resources.\n const systemByKey = new Map<string, unknown>();\n for (const entity of state.entities) {\n const key = assetKeyOf(entity);\n if (key === undefined || !factKeys?.has(key)) continue;\n const system = (entity.payload.external as Record<string, unknown>).system;\n if (systemByKey.has(key) && systemByKey.get(key) !== system)\n throw new Error(`Ambiguous generation asset id ${key} across media and speech namespaces`);\n systemByKey.set(key, system);\n }\n const resolved = new Map<string, string[]>();\n for (const entity of state.entities) {\n if (!isMediaAssetVariantKind(entity.entity_kind)) continue;\n const key = assetKeyOf(entity);\n if (key === undefined) continue;\n const matches = resolved.get(key) ?? [];\n matches.push(entity.entity_id);\n resolved.set(key, matches);\n }\n return resolved;\n}\n\nfunction pairKey(endpoint0: string, endpoint1: string): string {\n return `${endpoint0}\\u0000${endpoint1}`;\n}\n\n/** Pair keys the facts already resolve to under the given base bindings. */\nfunction resolvablePairs(mediaByAssetKey: Map<string, string[]>, facts: readonly AssetGenerationFact[]): string[] {\n const pairs: string[] = [];\n for (const fact of facts) {\n for (const outputId of mediaByAssetKey.get(fact.outputAssetId) ?? []) {\n for (const inputAssetId of fact.inputAssetIds) {\n for (const inputId of mediaByAssetKey.get(inputAssetId) ?? []) {\n if (outputId !== inputId) pairs.push(pairKey(outputId, inputId));\n }\n }\n }\n }\n return pairs;\n}\n\nfunction mintRelationId(): string {\n return `relation_${randomUUID()}`;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n","/** @generated by gen:sandbox-dts. DO NOT EDIT. */\nexport const ENTITY_EDIT_SANDBOX_API_DTS = [\n '/** @generated by gen:sandbox-dts. Entity-native editor contract; DO NOT EDIT. */',\n 'export interface BoundedDerivedSequencePayload extends JsonObject {',\n ' extent: {',\n \" kind: 'bounded';\",\n ' start: number;',\n ' end: number;',\n ' };',\n \" sampling: 'derived';\",\n ' coordinateSpace: JsonValue;',\n '}',\n 'export interface BoundedNativeSequencePayload extends JsonObject {',\n ' /** Factual coordinates from recalled media metadata; never invent an end/duration. */',\n ' extent: {',\n \" kind: 'bounded';\",\n ' start: number;',\n ' end: number;',\n ' };',\n \" sampling: 'native';\",\n ' coordinateSpace: JsonValue;',\n '}',\n '/** Business editing surface. Reads are assembled snapshots; writes preserve native operation intent. */',\n 'export interface BusinessEntityFacade {',\n ' list(): SandboxEntity[];',\n ' get(entityId: string): SandboxEntity | null;',\n ' create(',\n ' input: Exclude<',\n ' CreateEntityInput,',\n ' {',\n \" entity_kind: 'asset';\",\n ' }',\n ' >,',\n ' ): string;',\n ' update(input: EntityUpdateInput): void;',\n ' declareFields(input: UpdateEntityInput): void;',\n ' delete(input: DeleteEntityInput): void;',\n '}',\n '/** Endpoint order is retained; each relation kind defines its endpoint semantics. */',\n 'export interface BusinessRelationFacade {',\n ' list(): SandboxRelation[];',\n ' of(entityId: string, relationKind?: KnownRelationKind): SandboxRelation[];',\n ' link(input: LinkRelationInput): string;',\n ' update(input: RelationUpdateInput): void;',\n ' unlink(input: UnlinkRelationInput): void;',\n '}',\n 'export type CaptionTextSelection = JsonObject & {',\n ' segmentId: string;',\n ' /** Half-open Unicode code-point range within the selected source segment. */',\n ' textRange?: {',\n ' start: number;',\n ' end: number;',\n ' };',\n '};',\n 'export type CreateEntityInput = {',\n ' [K in KnownEntityKind]: {',\n ' entity_id?: string;',\n ' entity_kind: K;',\n ' payload: StoredEntityPayload<K>;',\n ' };',\n '}[KnownEntityKind];',\n 'export interface DeleteEntityInput {',\n ' entity_id: string;',\n '}',\n '/** Immutable resource content resolved by the host for a document Entity. */',\n 'export interface EntityAssetContent {',\n ' assetId: string;',\n ' content: JsonValue;',\n '}',\n 'export interface EntityPayloadByKind {',\n ' axvideo: BoundedDerivedSequencePayload;',\n ' timeline: JsonObject;',\n ' track: JsonObject & {',\n ' hidden?: boolean;',\n ' role?: string;',\n ' };',\n ' clip: JsonObject;',\n ' video: BoundedNativeSequencePayload & MediaAssetPayload;',\n ' audio: BoundedNativeSequencePayload & MediaAssetPayload;',\n ' voice: BoundedNativeSequencePayload & MediaAssetPayload;',\n ' image: UnboundedConstantSequencePayload & MediaAssetPayload;',\n \" 'sequence-marker': JsonObject & {\",\n ' sourceRange: {',\n ' start: number;',\n ' end: number;',\n ' };',\n ' targetRange?: {',\n ' start: number;',\n ' end: number;',\n ' };',\n ' duration:',\n ' | {',\n \" mode: 'from-source';\",\n ' }',\n ' | {',\n \" mode: 'fixed';\",\n ' value: number;',\n ' };',\n ' timeRemapping?: JsonValue;',\n ' anchorOffset?: number;',\n \" durationPolicy?: 'timeline';\",\n ' /** Directly assigned AudioScript annotation times; annotation Markers only. */',\n ' segmentRanges?: {',\n ' segmentId: string;',\n ' startMs: number;',\n ' endMs: number;',\n ' }[];',\n ' };',\n ' viewport: JsonObject;',\n \" 'audio-script': JsonObject & {\",\n ' segments: ScriptTextSegment[];',\n ' };',\n \" 'phonetic-script': JsonObject & {\",\n ' baseEntityIds: string[];',\n ' phonemeScript?: string;',\n ' prosody?: JsonObject;',\n ' };',\n ' caption: BoundedNativeSequencePayload & {',\n ' baseEntityIds: string[];',\n ' selection: CaptionTextSelection;',\n ' style?: JsonObject;',\n ' segmentRanges?: {',\n ' segmentId: string;',\n ' startMs: number;',\n ' endMs: number;',\n ' }[];',\n ' };',\n '}',\n '/** Tokens have no script-authored data; only the creating session can validate them. */',\n 'export interface EntitySandboxCheckpoint {',\n ' readonly __checkpoint: unique symbol;',\n '}',\n 'export interface EntityUpdateInput {',\n ' entity_id: string;',\n ' changes: FieldChange[];',\n '}',\n 'export type FieldChange =',\n ' | {',\n \" op: 'set';\",\n ' path: FieldPath;',\n ' value: JsonValue;',\n ' }',\n ' | {',\n \" op: 'unset';\",\n ' path: FieldPath;',\n ' }',\n ' | {',\n \" op: 'text.splice';\",\n ' path: FieldPath;',\n ' index: number;',\n ' deleteCount: number;',\n ' text: string;',\n ' }',\n ' | {',\n \" op: 'list.insert';\",\n ' path: FieldPath;',\n ' value: JsonValue;',\n ' beforeElementId: string | null;',\n ' }',\n ' | {',\n \" op: 'list.move';\",\n ' path: FieldPath;',\n ' elementId: string;',\n ' beforeElementId: string | null;',\n ' }',\n ' | {',\n \" op: 'list.remove';\",\n ' path: FieldPath;',\n ' elementId: string;',\n ' };',\n '/** List members are addressed by identity, never a transient array offset. */',\n 'export type FieldPath = readonly (',\n ' | string',\n ' | {',\n ' elementId: string;',\n ' }',\n ')[];',\n 'export interface JsonObject {',\n ' [key: string]: JsonValue;',\n '}',\n 'export type JsonPrimitive = string | number | boolean | null;',\n 'export type JsonValue = JsonPrimitive | JsonObject | JsonValue[];',\n 'export type KnownEntityKind =',\n \" | 'axvideo'\",\n \" | 'timeline'\",\n \" | 'track'\",\n \" | 'clip'\",\n \" | 'video'\",\n \" | 'audio'\",\n \" | 'voice'\",\n \" | 'image'\",\n \" | 'sequence-marker'\",\n \" | 'viewport'\",\n \" | 'audio-script'\",\n \" | 'phonetic-script'\",\n \" | 'caption';\",\n 'export type KnownRelationKind =',\n \" | 'timeline-track'\",\n \" | 'track-clip'\",\n \" | 'clip-marker'\",\n \" | 'marker-content'\",\n \" | 'axvideo-marker'\",\n \" | 'marker-timeline'\",\n \" | 'generated'\",\n \" | 'caption-alignment'\",\n \" | 'clip-anchor'\",\n \" | 'phonetic-script-render'\",\n \" | 'audio-script-source'\",\n \" | 'audio-script-marker';\",\n 'interface LinkRelationBase {',\n ' relation_id?: string;',\n ' endpoint_0_entity_id: string;',\n ' endpoint_1_entity_id: string;',\n ' trace?: JsonObject;',\n '}',\n 'export interface LinkRelationInput extends LinkRelationBase {',\n ' relation_kind: KnownRelationKind;',\n ' metadata?: JsonObject;',\n '}',\n 'export type MediaAssetPayload = JsonObject & {',\n ' external: {',\n \" system: 'memota' | 'memota-speech';\",\n ' key: string;',\n ' };',\n '};',\n 'export interface RelationUpdateInput {',\n ' relation_id: string;',\n ' changes: FieldChange[];',\n '}',\n 'export interface SandboxEntity<K extends KnownEntityKind = KnownEntityKind> {',\n ' entity_id: string;',\n ' entity_kind: K;',\n ' payload: StoredEntityPayload<K>;',\n '}',\n 'export interface SandboxRelation {',\n ' relation_id: string;',\n ' relation_kind: KnownRelationKind;',\n ' endpoint_0_entity_id: string;',\n ' endpoint_1_entity_id: string;',\n ' metadata: JsonObject;',\n ' trace: JsonObject;',\n '}',\n 'export type ScriptTextSegment = JsonObject & {',\n ' segmentId: string;',\n ' text: string;',\n ' language?: string;',\n '};',\n '/** Stored own fields; a variant may obtain required content fields from its declared bases. */',\n 'export type StoredEntityPayload<K extends KnownEntityKind> =',\n ' | EntityPayloadByKind[K]',\n \" | (K extends 'caption' | 'voice' ? JsonObject & Pick<MediaAssetPayload, 'external'> : never)\",\n ' | (JsonObject &',\n ' Partial<EntityPayloadByKind[K]> & {',\n ' baseEntityIds: string[];',\n ' });',\n 'export interface UnboundedConstantSequencePayload extends JsonObject {',\n ' extent: {',\n \" kind: 'unbounded';\",\n ' start: number;',\n ' };',\n \" sampling: 'constant';\",\n ' coordinateSpace: JsonValue;',\n '}',\n 'export interface UnlinkRelationInput {',\n ' relation_id: string;',\n '}',\n '/** Patch supplied fields on the assembled entity; omitted fields remain unchanged. */',\n 'export interface UpdateEntityInput {',\n ' entity_id: string;',\n ' payload: JsonObject;',\n '}',\n 'export declare const entities: BusinessEntityFacade;',\n 'export declare const relations: BusinessRelationFacade;',\n \"/** Resolve this Entity's attached resource through the host; await before using an uninitialized Caption or Voice. */\",\n 'export declare function rgetAssetFromEntity(entityId: string): Promise<EntityAssetContent>;',\n 'export declare function checkpoint(): EntitySandboxCheckpoint;',\n 'export declare function rollbackTo(cp: EntitySandboxCheckpoint): void;',\n 'export declare const inputs: Readonly<Record<string, unknown>>;',\n 'export declare const console: {',\n ' log(...values: unknown[]): void;',\n ' info(...values: unknown[]): void;',\n ' warn(...values: unknown[]): void;',\n ' error(...values: unknown[]): void;',\n '};',\n '',\n].join('\\n');\n","import { ENTITY_EDIT_SANDBOX_API_DTS } from './sandbox/generated/entity-edit-sandbox-model-context.ts';\n\nexport const MEDEO_TOOL_DESCRIPTION = `\nEdit the authoritative Medeo Entity/Relation graph in an isolated JavaScript sandbox.\n\nOperations:\n- snapshot: read assembled entities, relations, project attachments and the current document version. Reading never initializes or changes the document.\n- run-edit-script: use entities and relations to inspect and edit the causal working view. rgetAssetFromEntity(entityId) delegates an attached-resource read to the host. The script has no network, generation or storage access. A successful run returns preview, logs and plan_id.\n- commit-plan: publish the original native Loro operations compiled against the plan's causal baseline. Independent concurrent edits merge; failed transport is unconfirmed, so retry the same plan_id to preserve operation identity.\n\nDefault flow: snapshot → run-edit-script with auto_commit=false → inspect preview → commit-plan. Use auto_commit=true for low-risk edits that need no host confirmation. A domain conflict requires inspecting and explicitly resolving the merged state; never overwrite the document or silently replay an old plan on a new snapshot.\n`.trim();\n\nconst MEDEO_TOOL_EXECUTION_RULES = `\nThe host supplies the current document. Do not invent or request a document id. The sandbox exposes only the API below: entity operations, relation operations, entity-bound resource reading and checkpoints. All business edits are expressed using entity fields and relation kinds.\n\nEntity reads return assembled snapshots. Mutating returned objects has no persistence effect. Create declares own fields. Update requires a nonempty changes array and atomically applies its ordered operations to assembled fields, routing each to its declaring owner. DeclareFields explicitly establishes own fields or an override; it is not the normal way to edit inherited content. Deletion requires explicitly handling incident relations, variant references and protected project attachments; it never deletes external resources or cascades business entities.\n\nFieldChange paths start at payload for an entity, and at metadata or trace for a relation. Use strings for fields and {elementId:'...'} for list members, never numeric indices. Segment identity is segmentId; reference identity is the referenced id. set writes scalars or schema-declared atomic values, including complete sourceRange, targetRange, extent, duration, timeRemapping, selection, textRange and external. It cannot replace collaborative text, lists or maps. Edit text with text.splice (Unicode code-point index and deleteCount), and segments/segmentRanges with list.insert, list.move or list.remove. beforeElementId:null means append; moving before itself, duplicate identity or an absent anchor is an error. Unset removes optional fields only. Map fields are edited through leaf paths; initialize a new own map via declareFields. baseEntityIds is unordered composition membership: insert/remove are supported, moving bases cannot resolve field conflicts. Independent fields and list-item text edits retain native Loro identities.\n\nEntities own data. Relations associate two existing entities; endpoint_0 and endpoint_1 retain their declared positions. Each relation kind defines direction and meaning; neither relation listing order nor endpoint storage order implies a global business order. Relations.update changes metadata/trace fields only; kind/endpoints require explicit unlink plus link with a new identity. Generated relations use generated(output,input). Ordinary associations do not implement composition.\n\nVariants directly hold baseEntityIds. Assembly validates every base before applying explicit own overrides: two bases supplying the same field are an error even if values match or the variant declares that field. Missing/cyclic bases fail. Consumers operate assembled fields without copying inherited content or resolving owners themselves. An owned-field edit creates a new immutable entity version. Base changes automatically advance variant base references and project attachments without versioning an unchanged variant. A variant-owned change versions the variant and retains unchanged bases. Do not manually clone entities for versioning. Use the current plan's ids throughout that execution; refresh after commit.\n\nGeneration tools return resource references. An asset id may be passed in an entity's external:{system:'memota',key:assetId}; it is never an entity id, baseEntityId or relation endpoint. Physical resources are host infrastructure. The sandbox has no direct resource lookup/CRUD by asset id. rgetAssetFromEntity takes only an existing business entity id and returns {assetId,content} for its attached resource. For output_caption, create a Caption with payload:{external:{system:'memota',key:assetId}}, then await rgetAssetFromEntity(captionId). The host initializes the complete AudioScript and one Caption per resource segment in the same causal plan when selection is omitted. The requested Caption represents the first segment; additional Caption entities share that same script and external reference. After awaiting, discover ALL resource Captions with entities.list filtered by entity_kind and payload.external.key, inspect each singular selection/extent, and place each in its own Clip/SequenceMarker. An explicit selection initializes only that selected Caption. Never place the first Caption over the whole transcript; Without explicit bases, the host creates an independent AudioScript for that resource. With bases, it resolves their unique AudioScript text owner and preserves other nonconflicting bases. It never routes text through the panel selection. Read the editable fields with entities.get afterwards. Repeated reads preserve edited text and return the original immutable resource content. Unawaited initialization is completed before validation; failure prevents publication. Resource-free Caption composition from AudioScript is also valid.\n\nProject initialization creates one current Timeline, the four standard Tracks and one attached AudioScript with segments:[]. A project may contain multiple independent complete AudioScripts (for example a generated script and an uploaded video transcript). The project AudioScript attachment selects only the panel view; it is not a singleton or membership constraint. Locate scripts with entities.list and choose the appropriate source. AudioScript owns independent multi-segment text; each can have multiple Caption variants. Caption and PhoneticScript compose it through baseEntityIds. Caption owns exactly one selection object ({segmentId,textRange?}), never an array or the legacy selections field. It selects one script segment or a contiguous substring, and owns only that selection's intrinsic timing and style; segmentId is a stable script-local identity, not an entity reference or transient array index; selection textRange is a half-open code-point range and can split display text without rewriting the script. PhoneticScript owns pronunciation/prosody; Voice is generated from it and related by phonetic-script-render(voice,phoneticScript). Speech and caption occupy separate Clips. Subtitles normally accompany sound; use source media or generate Voice from PhoneticScript when the request requires narration. Do not fabricate a sound resource.\n\nFor Speech resources, create a Voice with external:{system:'memota-speech',key:speechId}, then await rgetAssetFromEntity(voiceId) before linking its placement. The host supplies full extent and optional voice-library identity, and assembles physical storage facts internally. Read the visible fields through entities.get; never invent them or use a Speech ID as a Memota media ID. TTS Voice still requires its real PhoneticScript relation; resource loading does not invent script content.\n\nAudioScript has no intrinsic time and cannot be Clip content. ASR input Audio/Video/Voice associates via audio-script-source(script,source). Its external annotation SequenceMarker associates via audio-script-marker(script,marker) and receives assigned segmentRanges, not references to another marker. Caption intrinsic timing and its Clip's display SequenceMarker are distinct. Move/stretch display by editing only the placement marker.\n\nTo place content, create a Clip and a SequenceMarker, then link track-clip(track,clip), clip-marker(clip,marker) and marker-content(marker,content). Existing track membership uses timeline-track(timeline,track). The editor has one track of each role: video_clip for Image/Video, speech for Voice, caption for Caption, bgm for Audio. Inspect factual media extents; never invent duration. Each placement is exactly one of Clip.order (sequential), Marker.targetRange (absolute) or clip-anchor(childClip,hostClip) plus Marker.anchorOffset. Marker.sourceRange selects source, duration describes playback/display. Whole milliseconds are required by this editor projection. Clip.volume is decibels (-60..20, 0 original). Image is unbounded/constant. Linear timeRemapping is {kind:'linear',rate:2,mode:'constant'}, with duration matching the rounded source span/rate. BGM can use durationPolicy:'timeline'. Nonlinear speed and multiple overlay tracks are unsupported. Caption visibility is the caption Track's hidden field. Caption style is its style map. Handle structural links explicitly when moving/deleting; there is no implicit cascade.\n\ncheckpoint returns an opaque token valid only in this execution. rollbackTo restores that point and invalidates later checkpoints. Returned read snapshots and inputs are not writable document authorities. Use only the declarations below.\n`.trim();\n\nexport interface RenderMedeoModelContextInput {\n documentVersion: string;\n updatedSincePreviousModelCall: boolean | null;\n}\n\n/** MEngine owns API disclosure; Harness only supplies the changing document context. */\nexport function renderMedeoModelContext(input: RenderMedeoModelContextInput): string {\n const updated =\n input.updatedSincePreviousModelCall == null\n ? 'unknown (first model call)'\n : String(input.updatedSincePreviousModelCall);\n return `\n${MEDEO_TOOL_DESCRIPTION}\n\n${MEDEO_TOOL_EXECUTION_RULES}\n\nCurrent MEngine document state (sampled immediately before this model call):\n- document_version: ${JSON.stringify(input.documentVersion)}\n- updated_since_previous_model_call: ${updated}\n\nWhen updated_since_previous_model_call is true, take a fresh snapshot before planning further edits.\n\nSandbox TypeScript interface:\n\\`\\`\\`ts\n${ENTITY_EDIT_SANDBOX_API_DTS}\n\\`\\`\\`\n`.trim();\n}\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 `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. Use edit, timeline, entities, relations, checkpoint, rollbackTo, inputs, and console. Asset import, media relations, and timeline entity edits share one entity plan.',\n },\n inputs: {\n type: 'object',\n description:\n 'Pre-materialized, side-effect-free values passed into the script, including recalled asset facts. Generation history is never an input: the host queries lineage itself and syncs generated Relations after each commit. 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: ['preflight'],\n description: 'Publish the native update already validated on its causal Loro fork.',\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 decodeDocVersionMark,\n encodeDocVersionMark,\n replayJournal,\n ValidationError,\n type JournalEntry,\n type ManualSyncDoc,\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 document 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 /** Encoded `ManualSyncDoc.versionMark()` from when the sandbox was forked. */\n base_version: string;\n ops: readonly JournalEntry[];\n}\n\nexport interface CommitPlanWarning {\n kind: 'pull_failed';\n message: string;\n}\n\nexport type CommitPlanResult =\n | {\n kind: 'committed';\n ops_applied: number;\n collaborated: boolean;\n warnings?: CommitPlanWarning[];\n }\n | { kind: 'unconfirmed'; reason: 'push_failed'; ops_applied: number; message: string }\n | { kind: 'rejected'; reason: 'version_mismatch'; expected: string; actual: string }\n | { kind: 'rejected'; reason: 'push_rejected'; code?: string; message: 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 manually-synchronized document and push the\n * whole plan as one causally complete update.\n *\n * - Default / `{ validation: 'version' }`: if the current document mark differs\n * from `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 doc: ManualSyncDoc,\n plan: CommitPlan,\n options?: CommitPlanOptions,\n): Promise<CommitPlanResult> {\n if (options?.validation === 'preflight') {\n return commitPlanPreflight(doc, plan);\n }\n\n const actual = encodeDocVersionMark(doc.versionMark());\n const expected = decodeDocVersionMark(plan.base_version);\n if (expected == null || doc.hasChangedSince(expected)) {\n return {\n kind: 'rejected',\n reason: 'version_mismatch',\n expected: plan.base_version,\n actual,\n };\n }\n\n await doc.replayJournal(plan.ops);\n return retryPlanPush(doc, 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(doc: ManualSyncDoc, plan: CommitPlan): Promise<CommitPlanResult> {\n const scratch = createPlainMemoryAdapter(doc.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 doc.replayJournal([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 retryPlanPush(doc, plan.ops.length);\n}\n\n/** Push an already-replayed plan again without replaying or re-running its version gate. */\nexport async function retryPlanPush(doc: ManualSyncDoc, opsApplied: number): Promise<CommitPlanResult> {\n const result = await doc.push();\n if (result.kind === 'ack' || result.kind === 'duplicate' || result.kind === 'nothing_to_push') {\n // A push can reveal that another peer wrote concurrently. Pull after the\n // durable verdict so the cached document does not serve a stale snapshot on\n // the next tool call; a pull failure cannot undo the acknowledged write.\n const reconciled = result.collaborated ? await doc.pull() : undefined;\n const warnings =\n reconciled != null && !reconciled.ok\n ? [{ kind: 'pull_failed' as const, message: reconciled.error.message }]\n : undefined;\n return {\n kind: 'committed',\n ops_applied: opsApplied,\n collaborated: result.collaborated,\n ...(warnings !== undefined ? { warnings } : {}),\n };\n }\n if (result.kind === 'rejected') {\n return {\n kind: 'rejected',\n reason: 'push_rejected',\n ...(result.code !== undefined ? { code: result.code } : {}),\n message: result.error?.message ?? 'mengine rejected the sandbox plan',\n };\n }\n return {\n kind: 'unconfirmed',\n reason: 'push_failed',\n ops_applied: opsApplied,\n message: result.error?.message ?? 'mengine push failed',\n };\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","/// <reference types=\"node\" />\nimport { randomUUID } from 'node:crypto';\n\nimport {\n createMirrorVideoDocument,\n encodeDocVersionMark,\n ManualSyncDoc,\n MengineHttpClient,\n MengineHttpRequestError,\n ensureEditorFoundation,\n LoroEntityDocument,\n toVideoDocument,\n type ManualSyncDocOptions,\n type VideoDocument,\n type VideoDraft,\n} from '@mengine/medeo-client';\n\nimport {\n assembleCaptionAssets,\n type CaptionAssetsLoader,\n type CaptionAssetAssemblyOutcome,\n} from './entity/caption-asset-assembly.ts';\nimport type { EntityAssetLoader } from './entity/entity-asset.ts';\nimport type { EntityStoreSnapshot } from './entity/entity-contract.ts';\nimport { EntityHttpClient, MengineEntityHttpRequestError } from './entity/entity-http-client.ts';\nimport {\n syncGeneratedRelations,\n type GenerationFactsLoader,\n type GenerationSyncOutcome,\n} from './entity/generation-sync.ts';\nimport { MEDEO_TOOL_DESCRIPTION, renderMedeoModelContext } from './prompt.ts';\nimport { businessState } from './sandbox/business-facades.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 { retryPlanPush, 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 * Documents 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 /**\n * Resolve factual generation lineage by external asset id after a confirmed\n * entity commit. Return every known generation record involving the given\n * ids in either role; an empty array means no known lineage and a rejection\n * means the lineage query failed (surfaced as a warning, never as synced\n * state). The package owns all Entity/Relation semantics: the host never\n * names entities, relations, or endpoints.\n */\n loadGenerationFacts?: GenerationFactsLoader;\n /** Assemble optional Caption artifacts by immutable entity ID; never exposed to scripts. */\n loadCaptionAssets?: CaptionAssetsLoader;\n loadEntityAsset?: EntityAssetLoader;\n fetchImpl?: typeof fetch;\n /** @deprecated ManualSyncDoc has no SSE or reconnect loop. */\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 /** Maximum model-call version baselines retained across host contexts (default 128). */\n maxModelContexts?: number;\n}\n\nexport interface MedeoModelContextInput {\n /** Internal MEngine document id. This is host-supplied and never model-facing. */\n doc_id: string;\n /** Stable host conversation/session key used to compare consecutive model calls. */\n context_id: string;\n}\n\nexport interface MedeoModelContext {\n /** Complete MEngine-owned prompt: workflow, runtime state, and sandbox TypeScript interface. */\n prompt: string;\n document_version: string;\n updated_since_previous_model_call: boolean | null;\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?: 'preflight';\n };\n\nexport type MedeoToolWarning =\n | { kind: 'asset_assembly_failed'; message: string }\n | { kind: 'pull_failed'; message: string }\n | { kind: 'generation_sync_failed'; message: string };\n\nexport type EntityCommitResult =\n | { kind: 'conflicted'; accepted: true; entity_revision: number; message: string }\n | {\n kind: 'committed';\n ops_applied: number;\n collaborated: boolean;\n entity_revision: number;\n /** Present only when the host supplies loadGenerationFacts. */\n generation_sync?: GenerationSyncOutcome;\n asset_assembly?: CaptionAssetAssemblyOutcome;\n warnings?: MedeoToolWarning[];\n }\n | { kind: 'unconfirmed'; reason: 'push_failed'; ops_applied: number; message: string }\n | {\n kind: 'rejected';\n reason: 'entity_state_rejected';\n status: number;\n message: string;\n };\n\nexport type MedeoCommitResult = CommitPlanResult | EntityCommitResult;\n\nexport type MedeoToolResult =\n | {\n ok: true;\n op: 'snapshot';\n doc_id: string;\n version: string;\n preview: string;\n collaborated?: boolean;\n warnings?: MedeoToolWarning[];\n }\n | {\n ok: true;\n op: 'run-edit-script';\n doc_id: string;\n plan_id: string;\n plan_kind: 'timeline' | 'entities';\n base_version: string;\n entity_base_revision: number;\n ops_count: number;\n preview: string;\n logs: string[];\n duration_ms: number;\n committed?: boolean;\n commit_result?: MedeoCommitResult;\n collaborated?: boolean;\n warnings?: MedeoToolWarning[];\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 plan_kind: 'timeline' | 'entities';\n committed: boolean;\n result: MedeoCommitResult;\n collaborated?: boolean;\n warnings?: MedeoToolWarning[];\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 getModelContext(input: MedeoModelContextInput): Promise<MedeoModelContext>;\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 /** Entity-store state the plan was built from; the generation sync's diff base. */\n baseState?: EntityStoreSnapshot;\n}\n\ninterface TimelinePendingPush {\n kind: 'timeline';\n planId: string;\n plan: ChangePlan;\n opsApplied: number;\n}\n\ninterface EntityPendingPush {\n kind: 'entities';\n planId: string;\n plan: ChangePlan;\n /** Diff base for the generation sync after recovery; see CachedPlan. */\n baseState?: EntityStoreSnapshot;\n}\n\ntype PendingPush = TimelinePendingPush | EntityPendingPush;\n\ninterface PullObservation {\n collaborated: boolean;\n warnings?: MedeoToolWarning[];\n}\n\nconst DEFAULT_MAX_PLANS = 16;\nconst DEFAULT_MAX_MODEL_CONTEXTS = 128;\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 renderEntitySnapshot(raw: EntityStoreSnapshot): string {\n const state = businessState(raw);\n const rows = [\n ...state.entities.map((entity) => JSON.stringify(entity)),\n ...state.relations.map((relation) => JSON.stringify(relation)),\n ];\n const shown = rows.slice(0, 200);\n return [\n `Entity revision=${state.revision} audioScriptEntityId=${JSON.stringify(state.audioScriptEntityId)} entities=${state.entities.length} relations=${state.relations.length}`,\n ...shown,\n ...(shown.length < rows.length ? ['[truncated; inspect entities/relations in the sandbox]'] : []),\n ].join('\\n');\n}\n\nasync function commitEntityPlan(client: EntityHttpClient, plan: ChangePlan): Promise<EntityCommitResult> {\n const rows = plan.entity_rows;\n if (rows === undefined) throw new Error('entity plan is missing its authoritative rows');\n try {\n if (!plan.loro_update) throw new Error('Entity plan has no compiled Loro update');\n const committed = await client.commitUpdate(plan.loro_update);\n return {\n kind: 'committed',\n ops_applied: plan.entity_commands.length,\n collaborated: committed.revision > plan.entity_base_revision + 1,\n entity_revision: committed.revision,\n };\n } catch (error) {\n if (error instanceof MengineEntityHttpRequestError) {\n if (isRecord(error.payload) && error.payload.accepted === true && typeof error.payload.revision === 'number')\n return {\n kind: 'conflicted',\n accepted: true,\n entity_revision: error.payload.revision,\n message: entityHttpErrorMessage(error.payload),\n };\n return {\n kind: 'rejected',\n reason: 'entity_state_rejected',\n status: error.status,\n message: entityHttpErrorMessage(error.payload),\n };\n }\n return {\n kind: 'unconfirmed',\n reason: 'push_failed',\n ops_applied: plan.entity_commands.length,\n message: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nfunction entityHttpErrorMessage(payload: unknown): string {\n if (isRecord(payload) && isRecord(payload.error) && typeof payload.error.message === 'string')\n return payload.error.message;\n if (isRecord(payload) && typeof payload.message === 'string' && payload.message.length > 0) return payload.message;\n return typeof payload === 'string' && payload.length > 0 ? payload : 'mengine rejected the entity-state plan';\n}\n\nfunction commitWarnings(result: MedeoCommitResult): MedeoToolWarning[] | undefined {\n return result.kind === 'committed' && 'warnings' in result && result.warnings !== undefined\n ? [...result.warnings]\n : undefined;\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 !== 'preflight') {\n throw new Error('validation must be \"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 document 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 documents = new Map<string, Promise<ManualSyncDoc>>();\n const entityClients = new Map<string, EntityHttpClient>();\n const documentTails = new Map<string, Promise<void>>();\n const pendingPushes = new Map<string, PendingPush>();\n const plans = new Map<string, CachedPlan>();\n const modelContextVersions = new Map<string, string>();\n const maxPlans = options.maxPlans ?? DEFAULT_MAX_PLANS;\n const maxModelContexts = options.maxModelContexts ?? DEFAULT_MAX_MODEL_CONTEXTS;\n let closed = false;\n\n async function getDocument(docId: string): Promise<ManualSyncDoc> {\n if (closed) throw new Error('medeo tool is closed');\n const existing = documents.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 ManualSyncDocOptions['peerId'] | undefined;\n return await getOrCreateDocument(client, docId, peerId);\n })();\n\n documents.set(docId, created);\n try {\n return await created;\n } catch (error) {\n if (documents.get(docId) === created) documents.delete(docId);\n throw error;\n }\n }\n\n function getEntityClient(docId: string): EntityHttpClient {\n if (closed) throw new Error('medeo tool is closed');\n const existing = entityClients.get(docId);\n if (existing != null) return existing;\n const client = new EntityHttpClient({\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 entityClients.set(docId, client);\n return client;\n }\n\n async function runExclusive<T>(docId: string, use: (doc: ManualSyncDoc) => Promise<T>): Promise<T> {\n const previous = documentTails.get(docId) ?? Promise.resolve();\n let release!: () => void;\n const gate = new Promise<void>((resolve) => {\n release = resolve;\n });\n const tail = previous.catch(() => {}).then(() => gate);\n documentTails.set(docId, tail);\n\n await previous.catch(() => {});\n try {\n return await use(await getDocument(docId));\n } finally {\n release();\n if (documentTails.get(docId) === tail) documentTails.delete(docId);\n }\n }\n\n async function getOrCreateDocument(\n client: MengineHttpClient,\n docId: string,\n peerId: ManualSyncDocOptions['peerId'] | undefined,\n ): Promise<ManualSyncDoc> {\n try {\n return await ManualSyncDoc.open({ client, ...(peerId !== undefined ? { peerId } : {}) });\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 if (Object.keys(document.part_library ?? {}).length > 0) {\n throw new Error('Legacy content cannot bootstrap a Loro entity project');\n }\n const seed = createMirrorVideoDocument(document, {\n ...(peerId !== undefined ? { peerId } : {}),\n origin: 'mengine.medeo_tool.bootstrap',\n });\n const foundation = ensureEditorFoundation({ entities: [], relations: [] });\n const entities = LoroEntityDocument.create(foundation.rows, {\n timelineEntityId: foundation.timelineEntityId,\n audioScriptEntityId: foundation.audioScriptEntityId,\n });\n seed.import(entities.doc.export({ mode: 'snapshot' }));\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 // The open below is the authenticated proof that the winner exists.\n }\n return await ManualSyncDoc.open({ client, ...(peerId !== undefined ? { peerId } : {}) });\n }\n\n function rememberPlan(docId: string, plan: ChangePlan, baseState: EntityStoreSnapshot | undefined): string {\n const planId = randomUUID();\n plans.set(planId, {\n docId,\n plan,\n ...(plan.plan_kind === 'entities' ? { baseState: baseState && structuredClone(baseState) } : {}),\n });\n while (plans.size > maxPlans) {\n const protectedPlanIds = new Set([...pendingPushes.values()].map((pending) => pending.planId));\n protectedPlanIds.add(planId);\n const oldestEvictable = [...plans.keys()].find((candidate) => !protectedPlanIds.has(candidate));\n // Pending plans are recovery state, and the plan just returned by this\n // call must remain usable. Let the cache exceed its nominal bound until a\n // later insertion can evict an older, non-pending plan.\n if (oldestEvictable === undefined) break;\n plans.delete(oldestEvictable);\n }\n return planId;\n }\n\n function assertNoPendingPush(docId: string): void {\n const pending = pendingPushes.get(docId);\n if (pending != null) {\n throw new Error(`doc ${docId} has an unconfirmed push; retry plan_id ${pending.planId} before continuing`);\n }\n }\n\n function recordPushResult(\n docId: string,\n planId: string,\n plan: ChangePlan,\n result: MedeoCommitResult,\n baseState: EntityStoreSnapshot | undefined,\n ): void {\n if (result.kind === 'unconfirmed') {\n pendingPushes.set(\n docId,\n plan.plan_kind === 'timeline'\n ? { kind: 'timeline', planId, plan, opsApplied: result.ops_applied }\n : { kind: 'entities', planId, plan, ...(baseState !== undefined ? { baseState } : {}) },\n );\n return;\n }\n pendingPushes.delete(docId);\n if (plan.plan_kind === 'timeline' && result.kind === 'rejected' && result.reason === 'push_rejected') {\n documents.delete(docId);\n }\n }\n\n async function fetchEntityStateForSandbox(\n docId: string,\n _doc: ManualSyncDoc,\n _pull: PullObservation,\n ): Promise<EntityStoreSnapshot> {\n const state = await getEntityClient(docId).fetchState();\n if (!state.loroSnapshot) throw new Error('Project requires the Loro entity contract');\n return state;\n }\n\n async function commitCachedPlan(\n docId: string,\n _doc: ManualSyncDoc,\n plan: ChangePlan,\n validation?: 'preflight',\n baseState?: EntityStoreSnapshot,\n ) {\n if (plan.plan_kind === 'timeline') {\n throw new Error('Legacy timeline plans are not editable; use an Entity/Relation plan');\n }\n // Every plan was preflighted on its causal Loro fork before publication.\n void validation;\n if (plan.entity_rows === undefined) throw new Error('entity plan is missing its authoritative rows');\n const client = getEntityClient(docId);\n // The generation diff must use the same causal baseline as the compiled update.\n if (options.loadGenerationFacts !== undefined && baseState === undefined)\n throw new Error('Generation synchronization is missing the cached causal plan baseline');\n const result = await commitEntityPlan(client, plan);\n const synced = await attachGenerationSync(docId, plan, result, baseState);\n if (synced.kind !== 'committed' || options.loadCaptionAssets === undefined) return synced;\n const assembly = await assembleCaptionAssets({ client, docId, loadAssets: options.loadCaptionAssets });\n return {\n ...synced,\n asset_assembly: assembly,\n ...(assembly.status === 'failed'\n ? {\n warnings: [\n ...(synced.warnings ?? []),\n {\n kind: 'asset_assembly_failed' as const,\n message: assembly.message ?? 'Caption Asset assembly failed',\n },\n ],\n }\n : {}),\n };\n }\n\n /**\n * After a confirmed entity commit, connect fact-matched generated Relations\n * from host-recalled lineage. The commit is already durable, so a sync\n * failure never fails the op; it is attached to the result and surfaced as a\n * warning instead. The plan's diff against `baseState` scopes the sync:\n * newly created media Asset identities — not untouched pairs or placement-only edits.\n * One-sided facts are skipped silently inside the sync.\n */\n async function attachGenerationSync(\n docId: string,\n plan: ChangePlan,\n result: EntityCommitResult,\n baseState: EntityStoreSnapshot | undefined,\n ): Promise<EntityCommitResult> {\n if (result.kind !== 'committed' || options.loadGenerationFacts === undefined || baseState === undefined) {\n return result;\n }\n let outcome: GenerationSyncOutcome;\n try {\n outcome = await syncGeneratedRelations({\n client: getEntityClient(docId),\n docId,\n baseState,\n entityCommands: plan.entity_commands,\n loadFacts: options.loadGenerationFacts,\n });\n } catch (error) {\n outcome = { status: 'failed', message: error instanceof Error ? error.message : String(error) };\n }\n const warnings: MedeoToolWarning[] | undefined =\n outcome.status === 'failed'\n ? [{ kind: 'generation_sync_failed', message: outcome.message ?? 'generation lineage sync failed' }]\n : undefined;\n return {\n ...result,\n generation_sync: outcome,\n ...(warnings !== undefined ? { warnings } : {}),\n };\n }\n\n async function observePull(doc: ManualSyncDoc): Promise<PullObservation> {\n const result = await doc.pull();\n if (result.ok) return { collaborated: result.changed };\n return {\n collaborated: false,\n warnings: [{ kind: 'pull_failed', message: result.error.message }],\n };\n }\n\n function mergeWarnings(\n ...groups: readonly (readonly MedeoToolWarning[] | undefined)[]\n ): MedeoToolWarning[] | undefined {\n const warnings = groups.flatMap((group) => group ?? []);\n return warnings.length > 0 ? warnings : undefined;\n }\n\n async function getModelContext(input: MedeoModelContextInput): Promise<MedeoModelContext> {\n const docId = input.doc_id.trim();\n const contextId = input.context_id.trim();\n if (docId.length === 0) throw new Error('doc_id must be a non-empty string');\n if (contextId.length === 0) throw new Error('context_id must be a non-empty string');\n\n return await runExclusive(docId, async (doc) => {\n // ManualSyncDoc has no background stream. Pull before sampling so remote\n // edits made between model calls participate in the version comparison.\n const pull = await observePull(doc);\n const entityState = await fetchEntityStateForSandbox(docId, doc, pull);\n const documentVersion = `${encodeDocVersionMark(doc.versionMark())}:entities:${entityState.revision}`;\n const baselineKey = `${contextId}\\u0000${docId}`;\n const previousVersion = modelContextVersions.get(baselineKey);\n const updatedSincePreviousModelCall = previousVersion == null ? null : previousVersion !== documentVersion;\n\n // Refresh insertion order so the bounded map behaves as an LRU.\n modelContextVersions.delete(baselineKey);\n modelContextVersions.set(baselineKey, documentVersion);\n while (modelContextVersions.size > maxModelContexts) {\n const oldest = modelContextVersions.keys().next().value;\n if (oldest === undefined) break;\n modelContextVersions.delete(oldest);\n }\n\n return {\n prompt: renderMedeoModelContext({ documentVersion, updatedSincePreviousModelCall }),\n document_version: documentVersion,\n updated_since_previous_model_call: updatedSincePreviousModelCall,\n };\n });\n }\n\n async function snapshot(input: Extract<MedeoToolInput, { op: 'snapshot' }>): Promise<MedeoToolResult> {\n return runExclusive(input.doc_id, async (doc) => {\n assertNoPendingPush(input.doc_id);\n const pull = await observePull(doc);\n const entityState = await fetchEntityStateForSandbox(input.doc_id, doc, pull);\n return {\n ok: true,\n op: 'snapshot',\n doc_id: input.doc_id,\n version: `${encodeDocVersionMark(doc.versionMark())}:entities:${entityState.revision}`,\n preview: renderEntitySnapshot(entityState),\n collaborated: pull.collaborated,\n ...(pull.warnings !== undefined ? { warnings: pull.warnings } : {}),\n };\n });\n }\n\n async function run(input: Extract<MedeoToolInput, { op: 'run-edit-script' }>): Promise<MedeoToolResult> {\n return runExclusive(input.doc_id, async (doc) => {\n assertNoPendingPush(input.doc_id);\n const pull = await observePull(doc);\n const entityState = await fetchEntityStateForSandbox(input.doc_id, doc, pull);\n const document: VideoDocument = doc.snapshot();\n const baseVersion = encodeDocVersionMark(doc.versionMark());\n const result = await runEditScript({\n document,\n baseVersion,\n entityState,\n loadEntityAsset: options.loadEntityAsset\n ? (entity) => options.loadEntityAsset!(input.doc_id, entity)\n : undefined,\n script: input.script,\n ...(input.inputs !== undefined ? { inputs: input.inputs } : {}),\n timeoutMs: input.timeout_ms ?? options.sandbox?.timeoutMs ?? 30_000,\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: {\n ops_count: result.partial.ops.length + result.partial.entityCommands.length,\n logs: result.partial.logs,\n },\n };\n }\n\n // The host-selected mapping is authoritative. A legacy document snapshot\n // may omit meta.draft_id, so never derive an entity route from it.\n const plan = { ...result.plan, doc_id: input.doc_id };\n const planId = rememberPlan(input.doc_id, plan, entityState);\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 plan_kind: plan.plan_kind,\n base_version: baseVersion,\n entity_base_revision: plan.entity_base_revision,\n ops_count: plan.ops.length + plan.entity_commands.length,\n preview: plan.preview,\n logs: plan.logs,\n duration_ms: result.durationMs,\n collaborated: pull.collaborated,\n ...(pull.warnings !== undefined ? { warnings: pull.warnings } : {}),\n };\n if (input.auto_commit !== true) return base;\n\n const commit = await commitCachedPlan(input.doc_id, doc, plan, undefined, entityState);\n recordPushResult(input.doc_id, planId, plan, commit, entityState);\n const warnings = mergeWarnings(pull.warnings, commitWarnings(commit));\n return {\n ...base,\n committed: commit.kind === 'committed',\n commit_result: commit,\n collaborated: pull.collaborated || (commit.kind === 'committed' && commit.collaborated),\n ...(warnings !== undefined ? { warnings } : {}),\n };\n });\n }\n\n async function commit(input: Extract<MedeoToolInput, { op: 'commit-plan' }>): Promise<MedeoToolResult> {\n return runExclusive(input.doc_id, async (doc) => {\n const pending = pendingPushes.get(input.doc_id);\n if (pending != null) {\n if (pending.planId !== input.plan_id) {\n throw new Error(\n `doc ${input.doc_id} has an unconfirmed push for plan_id ${pending.planId}; retry it before ${input.plan_id}`,\n );\n }\n const result =\n pending.kind === 'timeline'\n ? await retryPlanPush(doc, pending.opsApplied)\n : await commitCachedPlan(input.doc_id, doc, pending.plan, input.validation, pending.baseState);\n recordPushResult(\n input.doc_id,\n input.plan_id,\n pending.plan,\n result,\n pending.kind === 'entities' ? pending.baseState : undefined,\n );\n const warnings = commitWarnings(result);\n return {\n ok: true,\n op: 'commit-plan',\n doc_id: input.doc_id,\n plan_id: input.plan_id,\n plan_kind: pending.plan.plan_kind,\n committed: result.kind === 'committed',\n result,\n collaborated: result.kind === 'committed' && result.collaborated,\n ...(warnings !== undefined ? { warnings } : {}),\n };\n }\n\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 pull = cached.plan.plan_kind === 'timeline' ? await observePull(doc) : { collaborated: false };\n const result = await commitCachedPlan(input.doc_id, doc, cached.plan, input.validation, cached.baseState);\n recordPushResult(input.doc_id, input.plan_id, cached.plan, result, cached.baseState);\n const warnings = mergeWarnings(pull.warnings, commitWarnings(result));\n return {\n ok: true,\n op: 'commit-plan',\n doc_id: input.doc_id,\n plan_id: input.plan_id,\n plan_kind: cached.plan.plan_kind,\n committed: result.kind === 'committed',\n result,\n collaborated: pull.collaborated || (result.kind === 'committed' && result.collaborated),\n ...(warnings !== undefined ? { warnings } : {}),\n };\n });\n }\n\n return {\n name: MEDEO_TOOL_NAME,\n description: MEDEO_TOOL_DESCRIPTION,\n parameters: MEDEO_TOOL_PARAMETERS,\n getModelContext,\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 await Promise.allSettled(documentTails.values());\n const opening = [...documents.values()];\n documents.clear();\n entityClients.clear();\n documentTails.clear();\n pendingPushes.clear();\n plans.clear();\n modelContextVersions.clear();\n const errors: unknown[] = [];\n for (const documentPromise of opening) {\n try {\n await documentPromise;\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 documents');\n },\n };\n}\n","import { createHash } from 'node:crypto';\n\nimport type { MediaAssetFact } from '@mengine/medeo-client';\n\nimport type { JsonObject } from './entity-contract.ts';\nimport { EntityHttpClient, type EntityHttpClientOptions } from './entity-http-client.ts';\nimport { EntitySandbox } from './entity-sandbox.ts';\nimport { planGeneratedRelations, parseGenerationFacts, type GenerationFactsLoader } from './generation-sync.ts';\n\n/** Host facts only. This contract is never included in the model's sandbox API. */\nexport type GeneratedResource =\n | MediaAssetFact\n | {\n kind: 'caption';\n assetId: string;\n storageKey: string;\n segments: readonly {\n text: string;\n startMs: number;\n endMs: number;\n /** ASR word timing is available as an annotation for model segmentation. */\n words?: readonly { text: string; startMs: number; endMs: number }[];\n }[];\n };\n\n/** Persist resources before model consumption. The host serializes repeated imports of the same generation task. */\nexport async function materializeResources(\n options: EntityHttpClientOptions & { loadGenerationFacts?: GenerationFactsLoader },\n resources: readonly GeneratedResource[],\n): Promise<readonly string[]> {\n const client = new EntityHttpClient(options);\n const state = await client.fetchState();\n let resourceKey = '';\n const sandbox = new EntitySandbox({ state, idFactory: (prefix) => stableId(prefix, options.docId, resourceKey) });\n const ids: string[] = [];\n for (const resource of resources) {\n resourceKey = `${resource.kind}:${resource.assetId}`;\n if (resource.kind !== 'caption') {\n ids.push(sandbox.entities.ensureMedia(resource).contentEntityId);\n continue;\n }\n const existingCaptions = sandbox.entities\n .list()\n .filter(\n (row) =>\n row.entity_kind === 'caption' && (row.payload.external as JsonObject | undefined)?.key === resource.assetId,\n );\n if (existingCaptions.length) {\n if (existingCaptions.some((caption) => caption.payload.storageKey !== resource.storageKey))\n throw new Error('Conflicting Caption resource identity');\n ids.push(...existingCaptions.map((caption) => caption.entity_id));\n continue;\n }\n if (!resource.assetId.trim() || !resource.storageKey.trim() || !resource.segments.length)\n throw new Error('Caption resource requires a physical locator and timed segments');\n for (const segment of resource.segments) {\n if (\n typeof segment.text !== 'string' ||\n !Number.isFinite(segment.startMs) ||\n !Number.isFinite(segment.endMs) ||\n segment.startMs < 0 ||\n segment.endMs <= segment.startMs\n )\n throw new Error('Caption resource has invalid ASR text or timing');\n for (const word of segment.words ?? []) {\n if (\n typeof word.text !== 'string' ||\n !Number.isFinite(word.startMs) ||\n !Number.isFinite(word.endMs) ||\n word.startMs < segment.startMs ||\n word.endMs > segment.endMs ||\n word.endMs < word.startMs\n )\n throw new Error('Caption resource has invalid ASR word timing');\n }\n }\n const scriptId = stableId('entity', 'audio-script', resource.assetId);\n const segments = resource.segments.map((segment, index) => ({\n segmentId: stableId('segment', resource.assetId, String(index)),\n text: segment.text,\n }));\n const start = Math.min(...resource.segments.map((segment) => segment.startMs));\n const end = Math.max(...resource.segments.map((segment) => segment.endMs));\n // Each transcription is a complete independent script, not appended to the panel selection.\n sandbox.entities.create({ entity_id: scriptId, entity_kind: 'audio-script', payload: { segments } });\n const ranges = resource.segments.map((segment, index) => ({\n segmentId: segments[index]!.segmentId,\n startMs: segment.startMs,\n endMs: segment.endMs,\n }));\n for (const range of ranges) {\n const captionId = stableId('entity', 'caption', resource.assetId, range.segmentId);\n sandbox.entities.create({\n entity_id: captionId,\n entity_kind: 'caption',\n payload: {\n baseEntityIds: [scriptId],\n external: { system: 'memota', key: resource.assetId },\n storageKey: resource.storageKey,\n selection: { segmentId: range.segmentId },\n segmentRanges: [range],\n extent: { kind: 'bounded', start: range.startMs, end: range.endMs },\n sampling: 'native',\n coordinateSpace: 'milliseconds',\n },\n });\n ids.push(captionId);\n }\n const markerId = sandbox.entities.create({\n entity_id: stableId('entity', 'asr-marker', resource.assetId),\n entity_kind: 'sequence-marker',\n payload: {\n sourceRange: { start, end },\n duration: { mode: 'from-source' },\n segmentRanges: resource.segments.map((segment, index) => ({\n segmentId: segments[index]!.segmentId,\n startMs: segment.startMs,\n endMs: segment.endMs,\n })),\n wordRanges: resource.segments.flatMap((segment, index) =>\n (segment.words ?? []).map((word) => ({ ...word, segmentIndex: index })),\n ),\n },\n });\n sandbox.relations.link({\n relation_id: stableId('relation', 'asr-marker', resource.assetId),\n relation_kind: 'audio-script-marker',\n endpoint_0_entity_id: scriptId,\n endpoint_1_entity_id: markerId,\n });\n }\n const candidate = sandbox.buildPlan();\n if (candidate.commands.length && options.loadGenerationFacts) {\n const newIds = new Set(ids.filter((id) => !state.entities.some((row) => row.entity_id === id)));\n const facts = parseGenerationFacts(\n await options.loadGenerationFacts(\n options.docId,\n resources.map((item) => item.assetId),\n ),\n );\n const relations = planGeneratedRelations({\n baseState: state,\n state: candidate.rows,\n scopedMediaIds: newIds,\n facts,\n newRelationId: () => `relation_${globalThis.crypto.randomUUID()}`,\n });\n for (const relation of relations)\n sandbox.relations.linkGenerated({\n relation_id: relation.relation_id,\n output_entity_id: relation.endpoint_0_entity_id,\n input_entity_id: relation.endpoint_1_entity_id,\n trace: relation.trace,\n });\n }\n const plan = sandbox.buildPlan();\n if (!plan.commands.length) return ids;\n const committed = await client.commit(state.revision, plan.rows);\n for (const id of ids) {\n if (!committed.entities.some((entity) => entity.entity_id === id))\n throw new Error(`Resource entity ${id} was not confirmed by the merged document`);\n }\n return ids;\n}\n\nfunction stableId(prefix: string, ...parts: string[]): string {\n return `${prefix}_${createHash('sha256').update(JSON.stringify(parts)).digest('hex')}`;\n}\n"],"mappings":"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ACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;C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"}
@@ -200,7 +200,7 @@ type ScriptTextSegment = JsonObject & {
200
200
  language?: string;
201
201
  };
202
202
  /** Stored own fields; a variant may obtain required content fields from its declared bases. */
203
- type StoredEntityPayload<K extends KnownEntityKind> = EntityPayloadByKind[K] | (K extends 'caption' ? JsonObject & Pick<MediaAssetPayload, 'external'> : never) | (JsonObject & Partial<EntityPayloadByKind[K]> & {
203
+ type StoredEntityPayload<K extends KnownEntityKind> = EntityPayloadByKind[K] | (K extends 'caption' | 'voice' ? JsonObject & Pick<MediaAssetPayload, 'external'> : never) | (JsonObject & Partial<EntityPayloadByKind[K]> & {
204
204
  baseEntityIds: string[];
205
205
  });
206
206
  interface UnboundedConstantSequencePayload extends JsonObject {
@@ -221,7 +221,7 @@ interface UpdateEntityInput {
221
221
  }
222
222
  declare const entities: BusinessEntityFacade;
223
223
  declare const relations: BusinessRelationFacade;
224
- /** Resolve this Entity's attached resource through the host; await before using an uninitialized Caption. */
224
+ /** Resolve this Entity's attached resource through the host; await before using an uninitialized Caption or Voice. */
225
225
  declare function rgetAssetFromEntity(entityId: string): Promise<EntityAssetContent>;
226
226
  declare function checkpoint(): EntitySandboxCheckpoint;
227
227
  declare function rollbackTo(cp: EntitySandboxCheckpoint): void;
@@ -1,4 +1,4 @@
1
- import { l as EntityStoreSnapshot } from "./entity-contract-DlmUSouB.mjs";
1
+ import { l as EntityStoreSnapshot } from "./entity-contract-G4HxwNXl.mjs";
2
2
  import { VideoDocument } from "@mengine/medeo-client";
3
3
 
4
4
  //#region src/sandbox/worker-entry.d.ts
@@ -17,6 +17,34 @@ function captionAssetSegments(content) {
17
17
  };
18
18
  });
19
19
  }
20
+ /** Persisted Speech facts, resolved by the host rather than inferred from transcript timing. */
21
+ function speechAssetFields(content) {
22
+ if (!content || typeof content !== "object" || Array.isArray(content) || typeof content.storageKey !== "string" || !content.storageKey.trim() || !Number.isSafeInteger(content.durationMs) || content.durationMs <= 0) throw new Error("Speech Asset requires factual storageKey and positive millisecond duration");
23
+ const voice = content.voice;
24
+ if (voice !== void 0 && (!voice || typeof voice !== "object" || Array.isArray(voice) || voice.system !== "voice-library" || typeof voice.key !== "string" || !voice.key.trim())) throw new Error("Speech Asset has an invalid voice-library identity");
25
+ return {
26
+ storageKey: content.storageKey,
27
+ extent: {
28
+ kind: "bounded",
29
+ start: 0,
30
+ end: content.durationMs
31
+ },
32
+ sampling: "native",
33
+ coordinateSpace: "milliseconds",
34
+ ...voice === void 0 ? {} : { voice }
35
+ };
36
+ }
37
+ /** Only resource facts participate; user placement and other fields remain untouched. */
38
+ function speechAssetSignature(payload) {
39
+ return JSON.stringify([
40
+ "external",
41
+ "storageKey",
42
+ "extent",
43
+ "sampling",
44
+ "coordinateSpace",
45
+ "voice"
46
+ ].map((key) => payload[key]));
47
+ }
20
48
  //#endregion
21
49
  //#region src/sandbox/entity-script-session.ts
22
50
  const LOG_LINE_MAX = 2e3;
@@ -35,6 +63,7 @@ var EntityEditSandboxSession = class {
35
63
  logBytes = 0;
36
64
  resolvedCaptionAssets = /* @__PURE__ */ new Set();
37
65
  logCapped = false;
66
+ resolvedSpeechAssets = /* @__PURE__ */ new Map();
38
67
  entities;
39
68
  relations;
40
69
  console;
@@ -90,6 +119,21 @@ var EntityEditSandboxSession = class {
90
119
  if (result.assetId !== external.key) throw new Error("Host returned a different Entity Asset");
91
120
  const current = this.entitySandbox.entities.get(entityId);
92
121
  if (!current || JSON.stringify(current.payload.external) !== JSON.stringify(external)) throw new Error("Entity resource changed during its read");
122
+ if (entity.entity_kind === "voice" && external.system === "memota-speech") {
123
+ const fields = speechAssetFields(result.content);
124
+ if (Object.entries(fields).some(([key, value]) => JSON.stringify(current.payload[key]) !== JSON.stringify(value))) this.entitySandbox.entities.declareFields({
125
+ entity_id: entityId,
126
+ payload: fields
127
+ });
128
+ if (fields.voice === void 0 && current.payload.voice !== void 0) this.entitySandbox.entities.changeFields({
129
+ entity_id: entityId,
130
+ changes: [{
131
+ op: "unset",
132
+ path: ["voice"]
133
+ }]
134
+ });
135
+ this.resolvedSpeechAssets.set(entityId, speechAssetSignature(this.entitySandbox.entities.get(entityId).payload));
136
+ }
93
137
  if (entity.entity_kind === "caption" && !this.initializedAsset(entityId, external.key)) {
94
138
  const timed = captionAssetSegments(result.content);
95
139
  const segments = timed.map((segment, index) => ({
@@ -167,11 +211,17 @@ var EntityEditSandboxSession = class {
167
211
  const external = this.baseRows.entities.find((row) => row.entityId === entityId)?.payload.external;
168
212
  return !!external && typeof external === "object" && !Array.isArray(external) && "key" in external && external.key === assetId;
169
213
  }
170
- /** Finish unawaited Caption initialization before validation; no partial rows are published. */
214
+ initializedSpeech(entity) {
215
+ const signature = speechAssetSignature(entity.payload);
216
+ if (this.resolvedSpeechAssets.get(entity.entity_id) === signature) return true;
217
+ const baseline = this.baseRows.entities.find((row) => row.entityId === entity.entity_id);
218
+ return baseline !== void 0 && speechAssetSignature(baseline.payload) === signature;
219
+ }
220
+ /** Finish resource initialization before validation; no partial rows are published. */
171
221
  async prepareEntityAssets(load) {
172
222
  for (const entity of this.entitySandbox.entities.list()) {
173
223
  const external = entity.payload.external;
174
- if (entity.entity_kind === "caption" && external && typeof external === "object" && !Array.isArray(external) && typeof external.key === "string" && !this.initializedAsset(entity.entity_id, external.key)) await this.rgetAssetFromEntity(entity.entity_id, load);
224
+ if (external && typeof external === "object" && !Array.isArray(external) && typeof external.key === "string" && (entity.entity_kind === "caption" && !this.initializedAsset(entity.entity_id, external.key) || entity.entity_kind === "voice" && external.system === "memota-speech" && !this.initializedSpeech(entity))) await this.rgetAssetFromEntity(entity.entity_id, load);
175
225
  }
176
226
  }
177
227
  buildPlan(baseVersion) {
@@ -1 +1 @@
1
- {"version":3,"file":"worker-entry.mjs","names":[],"sources":["../src/entity/entity-asset.ts","../src/sandbox/entity-script-session.ts","../src/sandbox/worker-entry.ts"],"sourcesContent":["import type { JsonValue, SandboxEntity } from './entity-contract.ts';\n\n/** Immutable resource content resolved by the host for a document Entity. */\nexport interface EntityAssetContent {\n assetId: string;\n content: JsonValue;\n}\n\n/** Host-only I/O. The sandbox supplies an Entity, never an arbitrary Asset query. */\nexport type EntityAssetLoader = (docId: string, entity: SandboxEntity) => Promise<EntityAssetContent>;\n\nexport interface CaptionAssetSegment {\n text: string;\n start_time_ms: number;\n end_time_ms: number;\n}\n\n/** MCAP's output_caption JSON contract; unknown formats never become invented captions. */\nexport function captionAssetSegments(content: JsonValue): CaptionAssetSegment[] {\n if (!content || typeof content !== 'object' || Array.isArray(content) || !Array.isArray(content.segments))\n throw new Error('Caption Asset must contain an output_caption object with segments');\n if (!content.segments.length) throw new Error('Caption Asset contains no speech segments');\n return content.segments.map((value) => {\n if (\n !value ||\n typeof value !== 'object' ||\n Array.isArray(value) ||\n typeof value.text !== 'string' ||\n !value.text.trim() ||\n !Number.isSafeInteger(value.start_time_ms) ||\n !Number.isSafeInteger(value.end_time_ms) ||\n (value.start_time_ms as number) < 0 ||\n (value.end_time_ms as number) <= (value.start_time_ms as number)\n )\n throw new Error('Caption Asset has invalid text or millisecond timing');\n return { text: value.text, start_time_ms: value.start_time_ms as number, end_time_ms: value.end_time_ms as number };\n });\n}\n","import {\n LoroEntityDocument,\n projectEntityTimeline,\n base64ToBytes,\n bytesToBase64,\n assertCanonicalEditorResources,\n assertMediaAssetWritePolicy,\n type VideoDocument,\n} from '@mengine/medeo-client';\nimport { isJsonObject, type EntityRelationRows } from '@mengine/medeo-dsl';\n\nimport { captionAssetSegments, type EntityAssetContent } from '../entity/entity-asset.ts';\nimport type {\n BusinessEntityFacade,\n BusinessRelationFacade,\n EntitySandboxCheckpoint,\n SandboxEntity,\n JsonObject,\n} from '../entity/entity-contract.ts';\nimport { EntitySandbox, toDslRows, type DomainIdFactory } from '../entity/entity-sandbox.ts';\nimport { businessFacades } from './business-facades.ts';\nimport type { ChangePlan, ConsoleShim, EditSandboxSessionOptions } from './script-session.ts';\n\nconst LOG_LINE_MAX = 2000;\nconst LOG_LINE_CAP = 1000;\nconst LOG_BYTE_CAP = 64 * 1024;\nconst TRUNCATE_MARK = '[truncated]';\nconst LOG_TRUNCATED = '[log truncated]';\n\n/** Entity/relation script session; compilation retains the ordered operation journal. */\nexport class EntityEditSandboxSession {\n private readonly document: VideoDocument;\n private readonly entitySandbox: EntitySandbox;\n private readonly baseRows: EntityRelationRows;\n private readonly domainIdFactory: DomainIdFactory;\n private readonly logs: string[] = [];\n private readonly onLog: ((line: string) => void) | undefined;\n private logBytes = 0;\n private readonly resolvedCaptionAssets = new Set<string>();\n private logCapped = false;\n\n readonly entities: BusinessEntityFacade;\n readonly relations: BusinessRelationFacade;\n readonly console: ConsoleShim;\n readonly checkpoint: () => EntitySandboxCheckpoint;\n readonly rollbackTo: (cp: EntitySandboxCheckpoint) => void;\n\n constructor(document: VideoDocument, options?: EditSandboxSessionOptions) {\n this.document = structuredClone(document);\n this.baseRows = toDslRows(\n options?.entityState ?? { revision: 0, audioScriptEntityId: null, entities: [], relations: [] },\n );\n this.domainIdFactory =\n options?.domainIdFactory ??\n (() => {\n throw new Error('Entity id factory is unavailable in this sandbox host');\n });\n this.onLog = options?.onLog;\n this.entitySandbox = new EntitySandbox({\n state: options?.entityState,\n idFactory: this.domainIdFactory,\n onCommand: options?.onEntityCommand,\n onTruncate: options?.onEntityTruncate,\n });\n\n const business = businessFacades(this.entitySandbox.entities, this.entitySandbox.relations);\n this.entities = business.entities;\n this.relations = business.relations;\n this.console = this.buildConsoleShim();\n const checkpoints = new Map<EntitySandboxCheckpoint, number>();\n this.checkpoint = () => {\n const token = Object.freeze({}) as EntitySandboxCheckpoint;\n checkpoints.set(token, this.entitySandbox.commandCount);\n return token;\n };\n this.rollbackTo = (cp) => {\n const index = checkpoints.get(cp);\n if (index === undefined) throw new Error('Invalid or expired sandbox checkpoint');\n this.entitySandbox.rollbackTo(index);\n let later = false;\n for (const token of checkpoints.keys()) {\n if (later) checkpoints.delete(token);\n if (token === cp) later = true;\n }\n };\n }\n\n /** Resolve only the resource attached to this Entity; I/O remains in the parent host. */\n async rgetAssetFromEntity(\n entityId: string,\n load: (entity: SandboxEntity) => Promise<EntityAssetContent>,\n ): Promise<EntityAssetContent> {\n const entity = this.entitySandbox.entities.get(entityId);\n if (!entity || entity.entity_kind === 'asset') throw new Error(`Business Entity not found: ${entityId}`);\n const external = entity.payload.external;\n if (!external || typeof external !== 'object' || Array.isArray(external) || typeof external.key !== 'string')\n throw new Error(`Entity ${entityId} has no attached Asset`);\n const assetId = external.key;\n const result = await load(entity);\n if (result.assetId !== external.key) throw new Error('Host returned a different Entity Asset');\n const current = this.entitySandbox.entities.get(entityId);\n if (!current || JSON.stringify(current.payload.external) !== JSON.stringify(external))\n throw new Error('Entity resource changed during its read');\n if (entity.entity_kind === 'caption' && !this.initializedAsset(entityId, external.key)) {\n const timed = captionAssetSegments(result.content);\n const segments = timed.map((segment, index) => ({\n segmentId: `asset:${assetId}:${index}`,\n text: segment.text,\n }));\n // An explicit composition determines the owner, never the panel selection.\n // Resource-only captions establish their own independent complete script.\n const bases = current.payload.baseEntityIds as string[] | undefined;\n const scriptId = bases?.length\n ? this.entitySandbox.captionAudioScriptId(entityId)\n : this.entitySandbox.entities.create({ entity_kind: 'audio-script', payload: { segments: [] } });\n const script = this.entitySandbox.entities.get(scriptId)!;\n const existing = script.payload.segments as { segmentId: string; text: string }[];\n const additions = segments.filter((segment) => !existing.some((item) => item.segmentId === segment.segmentId));\n this.entitySandbox.entities.update({ entity_id: scriptId, payload: { segments: [...existing, ...additions] } });\n const ranges = timed.map((segment, index) => ({\n segmentId: segments[index]!.segmentId,\n startMs: segment.start_time_ms,\n endMs: segment.end_time_ms,\n }));\n // One resource retains one complete script, but each Caption quotes only one segment.\n const selection = current.payload.selection;\n if (selection !== undefined && (!isJsonObject(selection) || typeof selection.segmentId !== 'string'))\n throw new Error('Caption selection must be one segment selection object');\n const selected =\n selection === undefined ? ranges : ranges.filter((range) => range.segmentId === selection.segmentId);\n if (!selected.length) throw new Error('Caption selection does not name a segment of its resource');\n for (const [index, range] of selected.entries()) {\n const payload: JsonObject & { baseEntityIds: string[] } = {\n baseEntityIds: bases?.length ? bases : [scriptId],\n external,\n ...(current.payload.style === undefined ? {} : { style: current.payload.style }),\n selection: selection ?? { segmentId: range.segmentId },\n extent: { kind: 'bounded', start: range.startMs, end: range.endMs },\n sampling: 'native',\n coordinateSpace: 'milliseconds',\n segmentRanges: [range],\n };\n const id = index === 0 ? entityId : this.entitySandbox.entities.create({ entity_kind: 'caption', payload });\n if (index === 0) this.entitySandbox.entities.update({ entity_id: id, payload });\n this.resolvedCaptionAssets.add(`${id}:${assetId}`);\n }\n const markerId = this.entitySandbox.entities.create({\n entity_kind: 'sequence-marker',\n payload: {\n sourceRange: {\n start: Math.min(...ranges.map((r) => r.startMs)),\n end: Math.max(...ranges.map((r) => r.endMs)),\n },\n duration: { mode: 'from-source' },\n segmentRanges: ranges,\n },\n });\n this.entitySandbox.relations.link({\n relation_kind: 'audio-script-marker',\n endpoint_0_entity_id: scriptId,\n endpoint_1_entity_id: markerId,\n });\n }\n this.resolvedCaptionAssets.add(`${entityId}:${assetId}`);\n return result;\n }\n\n private initializedAsset(entityId: string, assetId: string): boolean {\n const current = this.entitySandbox.entities.get(entityId);\n if (\n this.resolvedCaptionAssets.has(`${entityId}:${assetId}`) &&\n isJsonObject(current?.payload.selection) &&\n Array.isArray(current?.payload.baseEntityIds)\n )\n return true;\n const baseline = this.baseRows.entities.find((row) => row.entityId === entityId);\n const external = baseline?.payload.external;\n return (\n !!external &&\n typeof external === 'object' &&\n !Array.isArray(external) &&\n 'key' in external &&\n external.key === assetId\n );\n }\n\n /** Finish unawaited Caption initialization before validation; no partial rows are published. */\n async prepareEntityAssets(load: (entity: SandboxEntity) => Promise<EntityAssetContent>): Promise<void> {\n for (const entity of this.entitySandbox.entities.list()) {\n const external = entity.payload.external;\n if (\n entity.entity_kind === 'caption' &&\n external &&\n typeof external === 'object' &&\n !Array.isArray(external) &&\n typeof external.key === 'string' &&\n !this.initializedAsset(entity.entity_id, external.key)\n )\n await this.rgetAssetFromEntity(entity.entity_id, load);\n }\n }\n\n buildPlan(baseVersion: string): ChangePlan {\n const entityPlan = this.entitySandbox.buildPlan();\n assertCanonicalEditorResources(toDslRows(entityPlan.rows));\n assertMediaAssetWritePolicy(this.baseRows, toDslRows(entityPlan.rows));\n if (entityPlan.rows.loroSnapshot) projectEntityTimeline(toDslRows(entityPlan.rows), this.document.meta);\n return {\n ...(entityPlan.rows.loroSnapshot\n ? {\n loro_update: bytesToBase64(this.compileJournal(entityPlan)),\n }\n : {}),\n plan_kind: 'entities',\n doc_id: this.document.meta.draft_id ?? '',\n base_version: baseVersion,\n ops: [],\n entity_base_revision: entityPlan.base_revision,\n entity_commands: entityPlan.commands,\n entity_rows: entityPlan.rows,\n deleted_entity_ids: entityPlan.deleted_entity_ids,\n deleted_relation_ids: entityPlan.deleted_relation_ids,\n preview: this.entitySandbox.renderPreview(),\n logs: this.logs.slice(),\n };\n }\n\n private compileJournal(plan: ReturnType<EntitySandbox['buildPlan']>): Uint8Array {\n const editor = LoroEntityDocument.fromSnapshot(base64ToBytes(plan.rows.loroSnapshot!), (state) => {\n assertCanonicalEditorResources(state.rows);\n projectEntityTimeline(state.rows, this.document.meta);\n });\n return editor.transact((draft) => {\n for (const command of plan.commands) {\n switch (command.kind) {\n case 'create-entity': {\n const rows = toDslRows({\n revision: 0,\n audioScriptEntityId: null,\n entities: [command.entity],\n relations: [],\n });\n draft.create(rows.entities[0]!);\n if (\n command.entity.entity_kind === 'audio-script' &&\n command.entity.entity_id === plan.rows.audioScriptEntityId\n )\n draft.attach('audioScriptEntityId', command.entity.entity_id);\n break;\n }\n case 'update-entity':\n draft.replaceOwned(command.entity_id, command.payload);\n break;\n case 'change-entity':\n draft.change(command.entity_id, command.changes);\n break;\n case 'delete-entity':\n draft.delete(command.entity_id);\n break;\n case 'link-relation': {\n const rows = toDslRows({\n revision: 0,\n audioScriptEntityId: null,\n entities: [],\n relations: [command.relation],\n });\n draft.link(rows.relations[0]!);\n break;\n }\n case 'change-relation':\n draft.changeRelation(command.relation_id, command.changes);\n break;\n case 'unlink-relation':\n draft.unlink(command.relation_id);\n break;\n }\n }\n draft.reconcileOrder(toDslRows(plan.rows));\n });\n }\n\n getLogs(): readonly string[] {\n return this.logs;\n }\n\n private appendLog(line: string): void {\n if (this.logCapped) return;\n if (this.logs.length >= LOG_LINE_CAP || this.logBytes >= LOG_BYTE_CAP) {\n this.logs.push(LOG_TRUNCATED);\n this.logCapped = true;\n this.onLog?.(LOG_TRUNCATED);\n return;\n }\n const out =\n line.length > LOG_LINE_MAX ? `${line.slice(0, LOG_LINE_MAX - TRUNCATE_MARK.length)}${TRUNCATE_MARK}` : line;\n this.logs.push(out);\n this.logBytes += out.length;\n this.onLog?.(out);\n }\n\n private buildConsoleShim(): ConsoleShim {\n const write = (...args: unknown[]) => this.appendLog(args.map(formatLogArg).join(' '));\n return { log: write, info: write, warn: write, error: write };\n }\n}\n\nfunction formatLogArg(value: unknown): string {\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean' || value === null || value === undefined) {\n return String(value);\n }\n try {\n return JSON.stringify(value);\n } catch {\n return '[unstringifiable]';\n }\n}\n","/// <reference types=\"node\" />\nimport { randomUUID } from 'node:crypto';\nimport vm from 'node:vm';\nimport { parentPort, workerData } from 'node:worker_threads';\n\nimport type { JournalEntry, PartIdFactory, VideoDocument } from '@mengine/medeo-client';\n\nimport type { EntityAssetContent } from '../entity/entity-asset.ts';\nimport type { SandboxEntity } from '../entity/entity-contract.ts';\nimport type { EntityCommand, EntityStoreSnapshot } from '../entity/entity-contract.ts';\nimport type { DomainIdFactory } from '../entity/entity-sandbox.ts';\nimport { EntityEditSandboxSession } from './entity-script-session.ts';\nimport { type EditSandboxSessionOptions } from './script-session.ts';\n\n/**\n * Node worker entry for trusted edit scripts.\n *\n * Spawns the requested sandbox session, runs the agent script in a bare `vm`\n * context (no fetch/process/setTimeout), and streams journals + logs to the\n * host so hard timeout / OOM termination still preserves partial products.\n */\n\nexport interface WorkerData {\n document: VideoDocument;\n script: string;\n inputs?: Record<string, unknown>;\n entityState?: EntityStoreSnapshot;\n idLabel?: string;\n}\n\ntype HostMessage =\n | { t: 'entity-asset'; requestId: number; entity: SandboxEntity }\n | { t: 'ready' }\n | { t: 'entry'; entry: JournalEntry }\n | { t: 'entity-entry'; command: EntityCommand }\n | { t: 'log'; line: string }\n | { t: 'truncate'; index: number }\n | { t: 'entity-truncate'; index: number }\n | {\n t: 'done';\n preview: string;\n opsCount: number;\n entityCommandsCount: number;\n loroUpdate?: string;\n entityBaseRevision: number;\n entityRows?: EntityStoreSnapshot;\n deletedEntityIds: readonly string[];\n deletedRelationIds: readonly string[];\n planKind: 'timeline' | 'entities';\n }\n | {\n t: 'fail';\n phase: 'parse' | 'runtime';\n error: { message: string; line?: number; column?: number; stack?: string };\n };\n\nconst data = workerData as WorkerData;\nif (parentPort == null) {\n throw new Error('worker-entry must run inside a worker_threads Worker');\n}\nconst port = parentPort;\nlet requestId = 0;\nconst pending = new Map<number, { resolve: (result: EntityAssetContent) => void; reject: (error: Error) => void }>();\nport.on('message', (message: { t: string; requestId: number; result: EntityAssetContent; error?: string }) => {\n if (message.t !== 'entity-asset-result') return;\n const waiter = pending.get(message.requestId);\n pending.delete(message.requestId);\n if (message.error) waiter?.reject(new Error(message.error));\n else waiter?.resolve(message.result);\n});\nfunction loadEntityAsset(entity: SandboxEntity): Promise<EntityAssetContent> {\n return new Promise((resolve, reject) => {\n const id = ++requestId;\n pending.set(id, { resolve, reject });\n port.postMessage({ t: 'entity-asset', requestId: id, entity });\n });\n}\n\nfunction post(message: HostMessage): void {\n port.postMessage(message);\n}\n\nfunction countingFactory(label: string): PartIdFactory {\n let n = 0;\n return (prefix) => `${prefix}_${label}${++n}`;\n}\n\nfunction domainIdFactory(label?: string): DomainIdFactory {\n let n = 0;\n return (prefix) => `${prefix}_${label == null ? randomUUID() : `${label}${++n}`}`;\n}\n\n/** Extract script line/column from the first `agent-script.js` stack frame. */\nfunction positionFromError(\n error: unknown,\n script?: string,\n phase?: 'parse' | 'runtime',\n): { line?: number; column?: number; stack?: string; message: string } {\n // Duck-type: vm SyntaxError in a worker may fail `instanceof Error` across realms.\n const obj = error != null && typeof error === 'object' ? (error as Record<string, unknown>) : null;\n const message =\n obj != null && typeof obj.message === 'string'\n ? obj.message\n : error instanceof Error\n ? error.message\n : String(error);\n const stack = obj != null && typeof obj.stack === 'string' ? obj.stack : undefined;\n\n let line = typeof obj?.lineNumber === 'number' ? obj.lineNumber : undefined;\n let column = typeof obj?.columnNumber === 'number' ? obj.columnNumber : undefined;\n\n if (stack != null) {\n // Prefer the header form `agent-script.js:N` (SyntaxError) or `agent-script.js:N:M`.\n const match = /agent-script\\.js:(\\d+)(?::(\\d+))?/.exec(stack);\n if (match != null) {\n line = Number(match[1]);\n if (match[2] != null) column = Number(match[2]);\n }\n }\n\n // Parse-phase refinement: V8 often points at the token after an unclosed\n // `{`/`(`/`[`; walk back one line when the previous line ends that way so\n // the reported line matches the agent-authored incomplete construct.\n if (phase === 'parse' && script != null && line != null && line >= 2) {\n const lines = script.split('\\n');\n const prev = lines[line - 2];\n if (prev != null && /[{([]\\s*$/.test(prev)) {\n line = line - 1;\n column = prev.length;\n }\n }\n\n return { message, line, column, stack };\n}\n\nasync function main(): Promise<void> {\n const idFactory = data.idLabel != null ? countingFactory(data.idLabel) : undefined;\n const options: EditSandboxSessionOptions = {\n idFactory,\n entityState: data.entityState,\n domainIdFactory: domainIdFactory(data.idLabel),\n onEntry: (entry) => post({ t: 'entry', entry }),\n onEntityCommand: (command) => post({ t: 'entity-entry', command }),\n onLog: (line) => post({ t: 'log', line }),\n onTruncate: (index) => post({ t: 'truncate', index }),\n onEntityTruncate: (index) => post({ t: 'entity-truncate', index }),\n };\n const session = new EntityEditSandboxSession(data.document, options);\n\n // Prelude stays on the same physical line as script line 1 so stack line\n // numbers map 1:1 onto the agent script (no leading newline).\n const wrapped = `(async (entities, relations, checkpoint, rollbackTo, inputs, console, rgetAssetFromEntity) => {${data.script}\\n})`;\n\n const ctx = vm.createContext(Object.create(null) as Record<string, unknown>);\n\n let run: unknown;\n try {\n run = vm.runInContext(wrapped, ctx, { filename: 'agent-script.js' });\n } catch (error) {\n const pos = positionFromError(error, data.script, 'parse');\n post({ t: 'fail', phase: 'parse', error: pos });\n return;\n }\n\n if (typeof run !== 'function') {\n post({\n t: 'fail',\n phase: 'runtime',\n error: { message: 'agent script wrapper did not evaluate to a function' },\n });\n return;\n }\n\n try {\n const invoke = run as (\n entities: typeof session.entities,\n relations: typeof session.relations,\n checkpoint: typeof session.checkpoint,\n rollbackTo: typeof session.rollbackTo,\n inputs: Record<string, unknown>,\n console: typeof session.console,\n rgetAssetFromEntity: (entityId: string) => Promise<EntityAssetContent>,\n ) => Promise<unknown>;\n // Signal host that cold start is done; timeout wall-clock starts here.\n post({ t: 'ready' });\n await invoke(\n session.entities,\n session.relations,\n session.checkpoint,\n session.rollbackTo,\n data.inputs ?? {},\n session.console,\n (entityId) => {\n return session.rgetAssetFromEntity(entityId, loadEntityAsset);\n },\n );\n await session.prepareEntityAssets(loadEntityAsset);\n } catch (error) {\n const pos = positionFromError(error, data.script, 'runtime');\n post({ t: 'fail', phase: 'runtime', error: pos });\n return;\n }\n\n const plan = session.buildPlan('');\n post({\n t: 'done',\n ...(plan.loro_update ? { loroUpdate: plan.loro_update } : {}),\n preview: plan.preview,\n opsCount: plan.ops.length,\n entityCommandsCount: plan.entity_commands.length,\n entityBaseRevision: plan.entity_base_revision,\n ...(plan.entity_rows !== undefined ? { entityRows: plan.entity_rows } : {}),\n deletedEntityIds: plan.deleted_entity_ids ?? [],\n deletedRelationIds: plan.deleted_relation_ids ?? [],\n planKind: plan.plan_kind,\n });\n}\n\nmain().catch((error: unknown) => {\n const pos = positionFromError(error);\n post({ t: 'fail', phase: 'runtime', error: pos });\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"worker-entry.mjs","names":[],"sources":["../src/entity/entity-asset.ts","../src/sandbox/entity-script-session.ts","../src/sandbox/worker-entry.ts"],"sourcesContent":["import type { JsonObject, JsonValue, SandboxEntity } from './entity-contract.ts';\n\n/** Immutable resource content resolved by the host for a document Entity. */\nexport interface EntityAssetContent {\n assetId: string;\n content: JsonValue;\n}\n\n/** Host-only I/O. The sandbox supplies an Entity, never an arbitrary Asset query. */\nexport type EntityAssetLoader = (docId: string, entity: SandboxEntity) => Promise<EntityAssetContent>;\n\nexport interface CaptionAssetSegment {\n text: string;\n start_time_ms: number;\n end_time_ms: number;\n}\n\n/** MCAP's output_caption JSON contract; unknown formats never become invented captions. */\nexport function captionAssetSegments(content: JsonValue): CaptionAssetSegment[] {\n if (!content || typeof content !== 'object' || Array.isArray(content) || !Array.isArray(content.segments))\n throw new Error('Caption Asset must contain an output_caption object with segments');\n if (!content.segments.length) throw new Error('Caption Asset contains no speech segments');\n return content.segments.map((value) => {\n if (\n !value ||\n typeof value !== 'object' ||\n Array.isArray(value) ||\n typeof value.text !== 'string' ||\n !value.text.trim() ||\n !Number.isSafeInteger(value.start_time_ms) ||\n !Number.isSafeInteger(value.end_time_ms) ||\n (value.start_time_ms as number) < 0 ||\n (value.end_time_ms as number) <= (value.start_time_ms as number)\n )\n throw new Error('Caption Asset has invalid text or millisecond timing');\n return { text: value.text, start_time_ms: value.start_time_ms as number, end_time_ms: value.end_time_ms as number };\n });\n}\n\n/** Persisted Speech facts, resolved by the host rather than inferred from transcript timing. */\nexport function speechAssetFields(content: JsonValue): JsonObject {\n if (\n !content ||\n typeof content !== 'object' ||\n Array.isArray(content) ||\n typeof content.storageKey !== 'string' ||\n !content.storageKey.trim() ||\n !Number.isSafeInteger(content.durationMs) ||\n (content.durationMs as number) <= 0\n )\n throw new Error('Speech Asset requires factual storageKey and positive millisecond duration');\n const voice = content.voice;\n if (\n voice !== undefined &&\n (!voice ||\n typeof voice !== 'object' ||\n Array.isArray(voice) ||\n voice.system !== 'voice-library' ||\n typeof voice.key !== 'string' ||\n !voice.key.trim())\n )\n throw new Error('Speech Asset has an invalid voice-library identity');\n return {\n storageKey: content.storageKey,\n extent: { kind: 'bounded', start: 0, end: content.durationMs },\n sampling: 'native',\n coordinateSpace: 'milliseconds',\n ...(voice === undefined ? {} : { voice }),\n };\n}\n\n/** Only resource facts participate; user placement and other fields remain untouched. */\nexport function speechAssetSignature(payload: JsonObject): string {\n return JSON.stringify(\n ['external', 'storageKey', 'extent', 'sampling', 'coordinateSpace', 'voice'].map((key) => payload[key]),\n );\n}\n","import {\n LoroEntityDocument,\n projectEntityTimeline,\n base64ToBytes,\n bytesToBase64,\n assertCanonicalEditorResources,\n assertMediaAssetWritePolicy,\n type VideoDocument,\n} from '@mengine/medeo-client';\nimport { isJsonObject, type EntityRelationRows } from '@mengine/medeo-dsl';\n\nimport {\n captionAssetSegments,\n speechAssetFields,\n speechAssetSignature,\n type EntityAssetContent,\n} from '../entity/entity-asset.ts';\nimport type {\n BusinessEntityFacade,\n BusinessRelationFacade,\n EntitySandboxCheckpoint,\n SandboxEntity,\n JsonObject,\n} from '../entity/entity-contract.ts';\nimport { EntitySandbox, toDslRows, type DomainIdFactory } from '../entity/entity-sandbox.ts';\nimport { businessFacades } from './business-facades.ts';\nimport type { ChangePlan, ConsoleShim, EditSandboxSessionOptions } from './script-session.ts';\n\nconst LOG_LINE_MAX = 2000;\nconst LOG_LINE_CAP = 1000;\nconst LOG_BYTE_CAP = 64 * 1024;\nconst TRUNCATE_MARK = '[truncated]';\nconst LOG_TRUNCATED = '[log truncated]';\n\n/** Entity/relation script session; compilation retains the ordered operation journal. */\nexport class EntityEditSandboxSession {\n private readonly document: VideoDocument;\n private readonly entitySandbox: EntitySandbox;\n private readonly baseRows: EntityRelationRows;\n private readonly domainIdFactory: DomainIdFactory;\n private readonly logs: string[] = [];\n private readonly onLog: ((line: string) => void) | undefined;\n private logBytes = 0;\n private readonly resolvedCaptionAssets = new Set<string>();\n private logCapped = false;\n private readonly resolvedSpeechAssets = new Map<string, string>();\n\n readonly entities: BusinessEntityFacade;\n readonly relations: BusinessRelationFacade;\n readonly console: ConsoleShim;\n readonly checkpoint: () => EntitySandboxCheckpoint;\n readonly rollbackTo: (cp: EntitySandboxCheckpoint) => void;\n\n constructor(document: VideoDocument, options?: EditSandboxSessionOptions) {\n this.document = structuredClone(document);\n this.baseRows = toDslRows(\n options?.entityState ?? { revision: 0, audioScriptEntityId: null, entities: [], relations: [] },\n );\n this.domainIdFactory =\n options?.domainIdFactory ??\n (() => {\n throw new Error('Entity id factory is unavailable in this sandbox host');\n });\n this.onLog = options?.onLog;\n this.entitySandbox = new EntitySandbox({\n state: options?.entityState,\n idFactory: this.domainIdFactory,\n onCommand: options?.onEntityCommand,\n onTruncate: options?.onEntityTruncate,\n });\n\n const business = businessFacades(this.entitySandbox.entities, this.entitySandbox.relations);\n this.entities = business.entities;\n this.relations = business.relations;\n this.console = this.buildConsoleShim();\n const checkpoints = new Map<EntitySandboxCheckpoint, number>();\n this.checkpoint = () => {\n const token = Object.freeze({}) as EntitySandboxCheckpoint;\n checkpoints.set(token, this.entitySandbox.commandCount);\n return token;\n };\n this.rollbackTo = (cp) => {\n const index = checkpoints.get(cp);\n if (index === undefined) throw new Error('Invalid or expired sandbox checkpoint');\n this.entitySandbox.rollbackTo(index);\n let later = false;\n for (const token of checkpoints.keys()) {\n if (later) checkpoints.delete(token);\n if (token === cp) later = true;\n }\n };\n }\n\n /** Resolve only the resource attached to this Entity; I/O remains in the parent host. */\n async rgetAssetFromEntity(\n entityId: string,\n load: (entity: SandboxEntity) => Promise<EntityAssetContent>,\n ): Promise<EntityAssetContent> {\n const entity = this.entitySandbox.entities.get(entityId);\n if (!entity || entity.entity_kind === 'asset') throw new Error(`Business Entity not found: ${entityId}`);\n const external = entity.payload.external;\n if (!external || typeof external !== 'object' || Array.isArray(external) || typeof external.key !== 'string')\n throw new Error(`Entity ${entityId} has no attached Asset`);\n const assetId = external.key;\n const result = await load(entity);\n if (result.assetId !== external.key) throw new Error('Host returned a different Entity Asset');\n const current = this.entitySandbox.entities.get(entityId);\n if (!current || JSON.stringify(current.payload.external) !== JSON.stringify(external))\n throw new Error('Entity resource changed during its read');\n if (entity.entity_kind === 'voice' && external.system === 'memota-speech') {\n const fields = speechAssetFields(result.content);\n // Host declarations initialize nested facts; native compilation writes only\n // their changed leaves against this session's original causal baseline.\n if (Object.entries(fields).some(([key, value]) => JSON.stringify(current.payload[key]) !== JSON.stringify(value)))\n this.entitySandbox.entities.declareFields({ entity_id: entityId, payload: fields });\n if (fields.voice === undefined && current.payload.voice !== undefined)\n this.entitySandbox.entities.changeFields({ entity_id: entityId, changes: [{ op: 'unset', path: ['voice'] }] });\n this.resolvedSpeechAssets.set(entityId, speechAssetSignature(this.entitySandbox.entities.get(entityId)!.payload));\n }\n if (entity.entity_kind === 'caption' && !this.initializedAsset(entityId, external.key)) {\n const timed = captionAssetSegments(result.content);\n const segments = timed.map((segment, index) => ({\n segmentId: `asset:${assetId}:${index}`,\n text: segment.text,\n }));\n // An explicit composition determines the owner, never the panel selection.\n // Resource-only captions establish their own independent complete script.\n const bases = current.payload.baseEntityIds as string[] | undefined;\n const scriptId = bases?.length\n ? this.entitySandbox.captionAudioScriptId(entityId)\n : this.entitySandbox.entities.create({ entity_kind: 'audio-script', payload: { segments: [] } });\n const script = this.entitySandbox.entities.get(scriptId)!;\n const existing = script.payload.segments as { segmentId: string; text: string }[];\n const additions = segments.filter((segment) => !existing.some((item) => item.segmentId === segment.segmentId));\n this.entitySandbox.entities.update({ entity_id: scriptId, payload: { segments: [...existing, ...additions] } });\n const ranges = timed.map((segment, index) => ({\n segmentId: segments[index]!.segmentId,\n startMs: segment.start_time_ms,\n endMs: segment.end_time_ms,\n }));\n // One resource retains one complete script, but each Caption quotes only one segment.\n const selection = current.payload.selection;\n if (selection !== undefined && (!isJsonObject(selection) || typeof selection.segmentId !== 'string'))\n throw new Error('Caption selection must be one segment selection object');\n const selected =\n selection === undefined ? ranges : ranges.filter((range) => range.segmentId === selection.segmentId);\n if (!selected.length) throw new Error('Caption selection does not name a segment of its resource');\n for (const [index, range] of selected.entries()) {\n const payload: JsonObject & { baseEntityIds: string[] } = {\n baseEntityIds: bases?.length ? bases : [scriptId],\n external,\n ...(current.payload.style === undefined ? {} : { style: current.payload.style }),\n selection: selection ?? { segmentId: range.segmentId },\n extent: { kind: 'bounded', start: range.startMs, end: range.endMs },\n sampling: 'native',\n coordinateSpace: 'milliseconds',\n segmentRanges: [range],\n };\n const id = index === 0 ? entityId : this.entitySandbox.entities.create({ entity_kind: 'caption', payload });\n if (index === 0) this.entitySandbox.entities.update({ entity_id: id, payload });\n this.resolvedCaptionAssets.add(`${id}:${assetId}`);\n }\n const markerId = this.entitySandbox.entities.create({\n entity_kind: 'sequence-marker',\n payload: {\n sourceRange: {\n start: Math.min(...ranges.map((r) => r.startMs)),\n end: Math.max(...ranges.map((r) => r.endMs)),\n },\n duration: { mode: 'from-source' },\n segmentRanges: ranges,\n },\n });\n this.entitySandbox.relations.link({\n relation_kind: 'audio-script-marker',\n endpoint_0_entity_id: scriptId,\n endpoint_1_entity_id: markerId,\n });\n }\n this.resolvedCaptionAssets.add(`${entityId}:${assetId}`);\n return result;\n }\n\n private initializedAsset(entityId: string, assetId: string): boolean {\n const current = this.entitySandbox.entities.get(entityId);\n if (\n this.resolvedCaptionAssets.has(`${entityId}:${assetId}`) &&\n isJsonObject(current?.payload.selection) &&\n Array.isArray(current?.payload.baseEntityIds)\n )\n return true;\n const baseline = this.baseRows.entities.find((row) => row.entityId === entityId);\n const external = baseline?.payload.external;\n return (\n !!external &&\n typeof external === 'object' &&\n !Array.isArray(external) &&\n 'key' in external &&\n external.key === assetId\n );\n }\n\n private initializedSpeech(entity: SandboxEntity): boolean {\n const signature = speechAssetSignature(entity.payload);\n if (this.resolvedSpeechAssets.get(entity.entity_id) === signature) return true;\n const baseline = this.baseRows.entities.find((row) => row.entityId === entity.entity_id);\n return baseline !== undefined && speechAssetSignature(baseline.payload as JsonObject) === signature;\n }\n\n /** Finish resource initialization before validation; no partial rows are published. */\n async prepareEntityAssets(load: (entity: SandboxEntity) => Promise<EntityAssetContent>): Promise<void> {\n for (const entity of this.entitySandbox.entities.list()) {\n const external = entity.payload.external;\n if (\n external &&\n typeof external === 'object' &&\n !Array.isArray(external) &&\n typeof external.key === 'string' &&\n ((entity.entity_kind === 'caption' && !this.initializedAsset(entity.entity_id, external.key)) ||\n (entity.entity_kind === 'voice' && external.system === 'memota-speech' && !this.initializedSpeech(entity)))\n )\n await this.rgetAssetFromEntity(entity.entity_id, load);\n }\n }\n\n buildPlan(baseVersion: string): ChangePlan {\n const entityPlan = this.entitySandbox.buildPlan();\n assertCanonicalEditorResources(toDslRows(entityPlan.rows));\n assertMediaAssetWritePolicy(this.baseRows, toDslRows(entityPlan.rows));\n if (entityPlan.rows.loroSnapshot) projectEntityTimeline(toDslRows(entityPlan.rows), this.document.meta);\n return {\n ...(entityPlan.rows.loroSnapshot\n ? {\n loro_update: bytesToBase64(this.compileJournal(entityPlan)),\n }\n : {}),\n plan_kind: 'entities',\n doc_id: this.document.meta.draft_id ?? '',\n base_version: baseVersion,\n ops: [],\n entity_base_revision: entityPlan.base_revision,\n entity_commands: entityPlan.commands,\n entity_rows: entityPlan.rows,\n deleted_entity_ids: entityPlan.deleted_entity_ids,\n deleted_relation_ids: entityPlan.deleted_relation_ids,\n preview: this.entitySandbox.renderPreview(),\n logs: this.logs.slice(),\n };\n }\n\n private compileJournal(plan: ReturnType<EntitySandbox['buildPlan']>): Uint8Array {\n const editor = LoroEntityDocument.fromSnapshot(base64ToBytes(plan.rows.loroSnapshot!), (state) => {\n assertCanonicalEditorResources(state.rows);\n projectEntityTimeline(state.rows, this.document.meta);\n });\n return editor.transact((draft) => {\n for (const command of plan.commands) {\n switch (command.kind) {\n case 'create-entity': {\n const rows = toDslRows({\n revision: 0,\n audioScriptEntityId: null,\n entities: [command.entity],\n relations: [],\n });\n draft.create(rows.entities[0]!);\n if (\n command.entity.entity_kind === 'audio-script' &&\n command.entity.entity_id === plan.rows.audioScriptEntityId\n )\n draft.attach('audioScriptEntityId', command.entity.entity_id);\n break;\n }\n case 'update-entity':\n draft.replaceOwned(command.entity_id, command.payload);\n break;\n case 'change-entity':\n draft.change(command.entity_id, command.changes);\n break;\n case 'delete-entity':\n draft.delete(command.entity_id);\n break;\n case 'link-relation': {\n const rows = toDslRows({\n revision: 0,\n audioScriptEntityId: null,\n entities: [],\n relations: [command.relation],\n });\n draft.link(rows.relations[0]!);\n break;\n }\n case 'change-relation':\n draft.changeRelation(command.relation_id, command.changes);\n break;\n case 'unlink-relation':\n draft.unlink(command.relation_id);\n break;\n }\n }\n draft.reconcileOrder(toDslRows(plan.rows));\n });\n }\n\n getLogs(): readonly string[] {\n return this.logs;\n }\n\n private appendLog(line: string): void {\n if (this.logCapped) return;\n if (this.logs.length >= LOG_LINE_CAP || this.logBytes >= LOG_BYTE_CAP) {\n this.logs.push(LOG_TRUNCATED);\n this.logCapped = true;\n this.onLog?.(LOG_TRUNCATED);\n return;\n }\n const out =\n line.length > LOG_LINE_MAX ? `${line.slice(0, LOG_LINE_MAX - TRUNCATE_MARK.length)}${TRUNCATE_MARK}` : line;\n this.logs.push(out);\n this.logBytes += out.length;\n this.onLog?.(out);\n }\n\n private buildConsoleShim(): ConsoleShim {\n const write = (...args: unknown[]) => this.appendLog(args.map(formatLogArg).join(' '));\n return { log: write, info: write, warn: write, error: write };\n }\n}\n\nfunction formatLogArg(value: unknown): string {\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean' || value === null || value === undefined) {\n return String(value);\n }\n try {\n return JSON.stringify(value);\n } catch {\n return '[unstringifiable]';\n }\n}\n","/// <reference types=\"node\" />\nimport { randomUUID } from 'node:crypto';\nimport vm from 'node:vm';\nimport { parentPort, workerData } from 'node:worker_threads';\n\nimport type { JournalEntry, PartIdFactory, VideoDocument } from '@mengine/medeo-client';\n\nimport type { EntityAssetContent } from '../entity/entity-asset.ts';\nimport type { SandboxEntity } from '../entity/entity-contract.ts';\nimport type { EntityCommand, EntityStoreSnapshot } from '../entity/entity-contract.ts';\nimport type { DomainIdFactory } from '../entity/entity-sandbox.ts';\nimport { EntityEditSandboxSession } from './entity-script-session.ts';\nimport { type EditSandboxSessionOptions } from './script-session.ts';\n\n/**\n * Node worker entry for trusted edit scripts.\n *\n * Spawns the requested sandbox session, runs the agent script in a bare `vm`\n * context (no fetch/process/setTimeout), and streams journals + logs to the\n * host so hard timeout / OOM termination still preserves partial products.\n */\n\nexport interface WorkerData {\n document: VideoDocument;\n script: string;\n inputs?: Record<string, unknown>;\n entityState?: EntityStoreSnapshot;\n idLabel?: string;\n}\n\ntype HostMessage =\n | { t: 'entity-asset'; requestId: number; entity: SandboxEntity }\n | { t: 'ready' }\n | { t: 'entry'; entry: JournalEntry }\n | { t: 'entity-entry'; command: EntityCommand }\n | { t: 'log'; line: string }\n | { t: 'truncate'; index: number }\n | { t: 'entity-truncate'; index: number }\n | {\n t: 'done';\n preview: string;\n opsCount: number;\n entityCommandsCount: number;\n loroUpdate?: string;\n entityBaseRevision: number;\n entityRows?: EntityStoreSnapshot;\n deletedEntityIds: readonly string[];\n deletedRelationIds: readonly string[];\n planKind: 'timeline' | 'entities';\n }\n | {\n t: 'fail';\n phase: 'parse' | 'runtime';\n error: { message: string; line?: number; column?: number; stack?: string };\n };\n\nconst data = workerData as WorkerData;\nif (parentPort == null) {\n throw new Error('worker-entry must run inside a worker_threads Worker');\n}\nconst port = parentPort;\nlet requestId = 0;\nconst pending = new Map<number, { resolve: (result: EntityAssetContent) => void; reject: (error: Error) => void }>();\nport.on('message', (message: { t: string; requestId: number; result: EntityAssetContent; error?: string }) => {\n if (message.t !== 'entity-asset-result') return;\n const waiter = pending.get(message.requestId);\n pending.delete(message.requestId);\n if (message.error) waiter?.reject(new Error(message.error));\n else waiter?.resolve(message.result);\n});\nfunction loadEntityAsset(entity: SandboxEntity): Promise<EntityAssetContent> {\n return new Promise((resolve, reject) => {\n const id = ++requestId;\n pending.set(id, { resolve, reject });\n port.postMessage({ t: 'entity-asset', requestId: id, entity });\n });\n}\n\nfunction post(message: HostMessage): void {\n port.postMessage(message);\n}\n\nfunction countingFactory(label: string): PartIdFactory {\n let n = 0;\n return (prefix) => `${prefix}_${label}${++n}`;\n}\n\nfunction domainIdFactory(label?: string): DomainIdFactory {\n let n = 0;\n return (prefix) => `${prefix}_${label == null ? randomUUID() : `${label}${++n}`}`;\n}\n\n/** Extract script line/column from the first `agent-script.js` stack frame. */\nfunction positionFromError(\n error: unknown,\n script?: string,\n phase?: 'parse' | 'runtime',\n): { line?: number; column?: number; stack?: string; message: string } {\n // Duck-type: vm SyntaxError in a worker may fail `instanceof Error` across realms.\n const obj = error != null && typeof error === 'object' ? (error as Record<string, unknown>) : null;\n const message =\n obj != null && typeof obj.message === 'string'\n ? obj.message\n : error instanceof Error\n ? error.message\n : String(error);\n const stack = obj != null && typeof obj.stack === 'string' ? obj.stack : undefined;\n\n let line = typeof obj?.lineNumber === 'number' ? obj.lineNumber : undefined;\n let column = typeof obj?.columnNumber === 'number' ? obj.columnNumber : undefined;\n\n if (stack != null) {\n // Prefer the header form `agent-script.js:N` (SyntaxError) or `agent-script.js:N:M`.\n const match = /agent-script\\.js:(\\d+)(?::(\\d+))?/.exec(stack);\n if (match != null) {\n line = Number(match[1]);\n if (match[2] != null) column = Number(match[2]);\n }\n }\n\n // Parse-phase refinement: V8 often points at the token after an unclosed\n // `{`/`(`/`[`; walk back one line when the previous line ends that way so\n // the reported line matches the agent-authored incomplete construct.\n if (phase === 'parse' && script != null && line != null && line >= 2) {\n const lines = script.split('\\n');\n const prev = lines[line - 2];\n if (prev != null && /[{([]\\s*$/.test(prev)) {\n line = line - 1;\n column = prev.length;\n }\n }\n\n return { message, line, column, stack };\n}\n\nasync function main(): Promise<void> {\n const idFactory = data.idLabel != null ? countingFactory(data.idLabel) : undefined;\n const options: EditSandboxSessionOptions = {\n idFactory,\n entityState: data.entityState,\n domainIdFactory: domainIdFactory(data.idLabel),\n onEntry: (entry) => post({ t: 'entry', entry }),\n onEntityCommand: (command) => post({ t: 'entity-entry', command }),\n onLog: (line) => post({ t: 'log', line }),\n onTruncate: (index) => post({ t: 'truncate', index }),\n onEntityTruncate: (index) => post({ t: 'entity-truncate', index }),\n };\n const session = new EntityEditSandboxSession(data.document, options);\n\n // Prelude stays on the same physical line as script line 1 so stack line\n // numbers map 1:1 onto the agent script (no leading newline).\n const wrapped = `(async (entities, relations, checkpoint, rollbackTo, inputs, console, rgetAssetFromEntity) => {${data.script}\\n})`;\n\n const ctx = vm.createContext(Object.create(null) as Record<string, unknown>);\n\n let run: unknown;\n try {\n run = vm.runInContext(wrapped, ctx, { filename: 'agent-script.js' });\n } catch (error) {\n const pos = positionFromError(error, data.script, 'parse');\n post({ t: 'fail', phase: 'parse', error: pos });\n return;\n }\n\n if (typeof run !== 'function') {\n post({\n t: 'fail',\n phase: 'runtime',\n error: { message: 'agent script wrapper did not evaluate to a function' },\n });\n return;\n }\n\n try {\n const invoke = run as (\n entities: typeof session.entities,\n relations: typeof session.relations,\n checkpoint: typeof session.checkpoint,\n rollbackTo: typeof session.rollbackTo,\n inputs: Record<string, unknown>,\n console: typeof session.console,\n rgetAssetFromEntity: (entityId: string) => Promise<EntityAssetContent>,\n ) => Promise<unknown>;\n // Signal host that cold start is done; timeout wall-clock starts here.\n post({ t: 'ready' });\n await invoke(\n session.entities,\n session.relations,\n session.checkpoint,\n session.rollbackTo,\n data.inputs ?? {},\n session.console,\n (entityId) => {\n return session.rgetAssetFromEntity(entityId, loadEntityAsset);\n },\n );\n await session.prepareEntityAssets(loadEntityAsset);\n } catch (error) {\n const pos = positionFromError(error, data.script, 'runtime');\n post({ t: 'fail', phase: 'runtime', error: pos });\n return;\n }\n\n const plan = session.buildPlan('');\n post({\n t: 'done',\n ...(plan.loro_update ? { loroUpdate: plan.loro_update } : {}),\n preview: plan.preview,\n opsCount: plan.ops.length,\n entityCommandsCount: plan.entity_commands.length,\n entityBaseRevision: plan.entity_base_revision,\n ...(plan.entity_rows !== undefined ? { entityRows: plan.entity_rows } : {}),\n deletedEntityIds: plan.deleted_entity_ids ?? [],\n deletedRelationIds: plan.deleted_relation_ids ?? [],\n planKind: plan.plan_kind,\n });\n}\n\nmain().catch((error: unknown) => {\n const pos = positionFromError(error);\n post({ t: 'fail', phase: 'runtime', error: pos });\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.4.1-alpha.5",
3
+ "version": "2.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.4.1-alpha.5"
27
+ "@mengine/medeo-client": "2.0.1-alpha.2"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/node": "^25.9.1",