@mengine/medeo-tool 1.2.1-alpha.7 → 1.2.1-alpha.9

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
@@ -1,14 +1,14 @@
1
1
  # `@mengine/medeo-tool`
2
2
 
3
- Node tool surface for editing a Medeo video document and its explicit
4
- Entity/Relation state through the deterministic edit sandbox.
3
+ Node tool surface for editing the authoritative Medeo Entity/Relation graph
4
+ through the deterministic edit sandbox. Timeline editing is entity editing,
5
+ not a legacy document mutation followed by optional entity registration.
5
6
 
6
7
  The package owns the complete tool path:
7
8
 
8
9
  - compact snapshot projection;
9
10
  - trusted worker execution of an agent-authored JavaScript edit script;
10
- - op-journal `ChangePlan` caching;
11
- - versioned or per-op-preflight commit through `ManualSyncDoc`;
11
+ - entity-command `ChangePlan` caching;
12
12
  - complete Entity/Relation snapshot reads and revision-CAS commits;
13
13
  - per-document serialization, document cache, and shutdown.
14
14
 
@@ -28,7 +28,8 @@ const snapshot = await medeo.handle({ op: 'snapshot', doc_id: docId });
28
28
  const run = await medeo.handle({
29
29
  op: 'run-edit-script',
30
30
  doc_id: docId,
31
- script: 'await edit.deleteBgm({})',
31
+ script: 'edit.updateClip({ clipEntityId: inputs.clip_id, payload: { volume: -6 } })',
32
+ inputs: { clip_id: existingClipEntityId },
32
33
  });
33
34
  if (!run.ok || run.op !== 'run-edit-script') throw new Error('edit script failed');
34
35
  const commit = await medeo.handle({
@@ -38,25 +39,28 @@ const commit = await medeo.handle({
38
39
  });
39
40
 
40
41
  // Generation facts are recalled by the host and passed into the sandbox.
42
+ // This example is text-to-image: there is no invented input-media entity.
41
43
  const entityRun = await medeo.handle({
42
44
  op: 'run-edit-script',
43
45
  doc_id: docId,
44
- inputs: { output_asset_id: 'asset-from-host', generation_id: 'generation-from-host' },
46
+ inputs: { output_asset_id: 'asset-from-host', track_entity_id: existingTrackEntityId },
45
47
  script: `
46
- if (typeof inputs.output_asset_id !== 'string' || typeof inputs.generation_id !== 'string') {
48
+ if (typeof inputs.output_asset_id !== 'string' || typeof inputs.track_entity_id !== 'string') {
47
49
  throw new Error('missing recalled generation facts');
48
50
  }
49
51
  const asset = entities.importAsset({ asset_id: inputs.output_asset_id });
50
- const input = entities.create({
52
+ const output = entities.create({
51
53
  entity_kind: 'image',
52
54
  payload: { extent: { kind: 'unbounded', start: 0 }, sampling: 'constant', coordinateSpace: 'ms' },
53
55
  });
54
- const output = entities.create({
55
- entity_kind: 'video',
56
- payload: { extent: { kind: 'bounded', start: 0, end: 1000 }, sampling: 'native', coordinateSpace: 'ms' },
57
- });
58
56
  relations.link({ relation_kind: 'physical-asset', endpoint_0_entity_id: output, endpoint_1_entity_id: asset });
59
- relations.linkGenerated({ output_entity_id: output, input_entity_id: input, trace: { generation_id: inputs.generation_id } });
57
+ edit.insertClip({
58
+ trackEntityId: inputs.track_entity_id,
59
+ contentEntityId: output,
60
+ sourceRange: { start: 0, end: 1 },
61
+ duration: { mode: 'fixed', value: 5000 },
62
+ targetRange: { start: 0, end: 5000 },
63
+ });
60
64
  `,
61
65
  });
62
66
 
@@ -69,6 +73,57 @@ through `inputs`. There is no automatic Asset→Entity projection: the model
69
73
  selects and imports assets, creates only known typed Entities, and links them
70
74
  explicitly. Assets and media Entities are intentionally not one-to-one.
71
75
 
72
- Timeline mutations and Entity/Relation mutations use different storage and CAS
73
- boundaries. A single script plan cannot mix them; create and commit two plans
74
- when a workflow needs both.
76
+ The production tool exposes native Clip/Marker editing plus visual placement,
77
+ voiceover, caption, and BGM helpers through its generated sandbox interface.
78
+ They preserve structural and anchor relations in the same plan. Timeline targets
79
+ are Entity IDs, never raw asset IDs or URLs. Asset import, media creation, and
80
+ Clip insertion belong in the **same entity plan**.
81
+
82
+ Generation lineage is program-synced, not model-authored. After a confirmed
83
+ entity commit the tool resolves the plan's diff against host-supplied generation
84
+ facts and commits missing `generated` Relations between fact-matched media
85
+ Entities already present in the document (endpoint 0 output, endpoint 1 input;
86
+ lookup can use either endpoint). The diff covers created media Entities, edits
87
+ that re-point an existing physical-asset binding or Asset external key, and
88
+ creations; pairs already fact-resolvable before the plan stay untouched. Models
89
+ do not pass generation history through inputs — the host queries it with
90
+ `loadGenerationFacts(docId, assetIds)`, returning every known generation record
91
+ involving the given asset ids in either role. Each record must carry an explicit
92
+ `inputAssetIds` array: an explicit empty array declares text-only generation
93
+ with no lineage edge, while a missing or non-array field is a malformed record
94
+ that fails the whole query instead of being silently read as text-only.
95
+ One-sided facts are skipped without creating entities or blocking the commit —
96
+ lineage sync never backfills a missing source or output Entity; entity creation
97
+ stays a model decision inside the edit plan. Repeated commits are idempotent,
98
+ and deletions, rebindings, and revision conflicts are respected: a CAS-conflict
99
+ retry re-derives the trigger keys from the fresh bindings and re-queries the
100
+ newly scoped facts, so a backfillable edge is never misreported as current.
101
+ An empty result array means no known lineage; a rejection means the lineage
102
+ query failed and is reported as `generation_sync: {status:'failed'}` plus a
103
+ `generation_sync_failed` warning — never as synced state.
104
+
105
+ Entities own their facts: SequenceMarker owns source/target ranges, duration,
106
+ and time remapping; Clip owns volume; Track owns role/visibility. Cross-entity
107
+ references are Relations. There is no separate orientation or timing profile.
108
+
109
+ The server validates and commits the graph and its read-only Loro projection in
110
+ one database transaction. `deleted_entity_ids` and `deleted_relation_ids` make
111
+ deletion explicit; dropped rows without deletion intent are rejected. After
112
+ cutover, raw Loro `/updates` cannot mutate the document. Legacy standalone
113
+ sandbox exports remain library compatibility APIs, not a production-tool mode.
114
+
115
+ Existing nonempty legacy documents require a separate version-CAS migration
116
+ whose projection preserves existing editing facts. `snapshot` identifies that
117
+ requirement and the media IDs needing factual metadata. Call
118
+ `{op:'migrate-legacy',doc_id,asset_facts}` explicitly, then take a fresh snapshot
119
+ before editing. The package reads the canonical document and current Loro
120
+ version itself; it does not accept a caller-supplied snapshot or version, use a
121
+ stale cached document after a failed pull, or combine migration with a new edit.
122
+ Repeating migration on an entity timeline is read-only. An uncertain submission
123
+ must be inspected and retried, never reported as committed.
124
+
125
+ The compatibility reader covers the existing four lanes: Image/Video, Voice,
126
+ Caption, and background Audio. Coordinates are whole milliseconds for this
127
+ reader. It preserves linear visual remapping (`{kind:'linear',rate:2}`), including
128
+ image display speed, and explicit anchor chains. Nonlinear remapping and multiple
129
+ visual overlay tracks are not existing editor features and remain unsupported.
@@ -5,7 +5,7 @@ interface JsonObject {
5
5
  [key: string]: JsonValue;
6
6
  }
7
7
  type KnownEntityKind = 'axvideo' | 'timeline' | 'track' | 'clip' | 'asset' | 'video' | 'audio' | 'voice' | 'image' | 'sequence-marker' | 'viewport' | 'audio-script' | 'phonetic-script' | 'caption';
8
- type KnownRelationKind = 'timeline-track' | 'track-clip' | 'clip-marker' | 'marker-content' | 'axvideo-marker' | 'marker-timeline' | 'physical-asset' | 'generated' | 'phonetic-script-provenance' | 'caption-provenance' | 'caption-alignment';
8
+ type KnownRelationKind = 'timeline-track' | 'track-clip' | 'clip-marker' | 'marker-content' | 'axvideo-marker' | 'marker-timeline' | 'physical-asset' | 'generated' | 'phonetic-script-provenance' | 'caption-provenance' | 'caption-alignment' | 'clip-anchor' | 'audio-script-render';
9
9
  type AuthorableRelationKind = Exclude<KnownRelationKind, 'generated'>;
10
10
  interface BoundedNativeSequencePayload extends JsonObject {
11
11
  /** Factual coordinates from recalled media metadata; never invent an end/duration. */
@@ -69,6 +69,8 @@ interface EntityPayloadByKind {
69
69
  value: number;
70
70
  };
71
71
  timeRemapping?: JsonValue;
72
+ anchorOffset?: number;
73
+ durationPolicy?: 'timeline';
72
74
  };
73
75
  viewport: JsonObject;
74
76
  'audio-script': JsonObject & {
@@ -102,6 +104,13 @@ type CreateEntityInput = { [K in KnownEntityKind]: {
102
104
  entity_kind: K;
103
105
  payload: EntityPayloadByKind[K];
104
106
  } }[KnownEntityKind];
107
+ interface UpdateEntityInput {
108
+ entity_id: string;
109
+ payload: JsonObject;
110
+ }
111
+ interface DeleteEntityInput {
112
+ entity_id: string;
113
+ }
105
114
  interface ImportAssetInput {
106
115
  asset_id: string;
107
116
  entity_id?: string;
@@ -139,17 +148,44 @@ interface LinkGeneratedRelationInput {
139
148
  input_entity_id: string;
140
149
  trace?: JsonObject;
141
150
  }
151
+ interface LinkClipAnchorRelationInput {
152
+ relation_id?: string;
153
+ child_clip_entity_id: string;
154
+ host_clip_entity_id: string;
155
+ trace?: JsonObject;
156
+ }
157
+ interface LinkAudioScriptRenderRelationInput {
158
+ relation_id?: string;
159
+ output_entity_id: string;
160
+ script_entity_id: string;
161
+ trace?: JsonObject;
162
+ }
163
+ interface UnlinkRelationInput {
164
+ relation_id: string;
165
+ }
142
166
  type EntityCommand = {
143
167
  kind: 'create-entity';
144
168
  entity: SandboxEntity;
169
+ } | {
170
+ kind: 'update-entity';
171
+ entity_id: string;
172
+ payload: JsonObject;
173
+ } | {
174
+ kind: 'delete-entity';
175
+ entity_id: string;
145
176
  } | {
146
177
  kind: 'link-relation';
147
178
  relation: SandboxRelation;
179
+ } | {
180
+ kind: 'unlink-relation';
181
+ relation_id: string;
148
182
  };
149
183
  interface EntityPlanState {
150
184
  base_revision: number;
151
185
  commands: readonly EntityCommand[];
152
186
  rows: EntityStoreSnapshot;
187
+ deleted_entity_ids: readonly string[];
188
+ deleted_relation_ids: readonly string[];
153
189
  }
154
190
  interface EntityFacade {
155
191
  list(): SandboxEntity[];
@@ -157,6 +193,10 @@ interface EntityFacade {
157
193
  /** Return every explicitly imported Asset entity for a Memota asset id. */
158
194
  findByAssetId(assetId: string): SandboxEntity<'asset'>[];
159
195
  create(input: CreateEntityInput): string;
196
+ /** Replace one Entity's owned payload without changing its identity or kind. */
197
+ update(input: UpdateEntityInput): void;
198
+ /** Delete an Entity only after all of its incident Relations have been explicitly unlinked. */
199
+ delete(input: DeleteEntityInput): void;
160
200
  /** Import one physical asset without implying a one-to-one media Entity mapping. */
161
201
  importAsset(input: ImportAssetInput): string;
162
202
  }
@@ -168,7 +208,13 @@ interface RelationFacade {
168
208
  link(input: LinkRelationInput): string;
169
209
  /** Author ordered generated(output,input); generic link() deliberately rejects this kind. */
170
210
  linkGenerated(input: LinkGeneratedRelationInput): string;
211
+ /** Author ordered clip-anchor(child,host) without positional endpoint ambiguity. */
212
+ linkClipAnchor(input: LinkClipAnchorRelationInput): string;
213
+ /** Author ordered audio-script-render(output,script) without positional endpoint ambiguity. */
214
+ linkAudioScriptRender(input: LinkAudioScriptRenderRelationInput): string;
215
+ /** Remove a Relation by identity; endpoint replacement is an explicit unlink plus link. */
216
+ unlink(input: UnlinkRelationInput): void;
171
217
  }
172
218
  //#endregion
173
- export { SandboxRelation as _, EntityPlanState as a, JsonObject as c, KnownEntityKind as d, KnownRelationKind as f, SandboxEntity as g, RelationFacade as h, EntityFacade as i, JsonPrimitive as l, LinkRelationInput as m, CreateEntityInput as n, EntityStoreSnapshot as o, LinkGeneratedRelationInput as p, EntityCommand as r, ImportAssetInput as s, AuthorableRelationKind as t, JsonValue as u };
174
- //# sourceMappingURL=entity-contract-B3txrzTt.d.mts.map
219
+ export { SandboxEntity as _, EntityFacade as a, UpdateEntityInput as b, ImportAssetInput as c, JsonValue as d, KnownEntityKind as f, RelationFacade as g, LinkRelationInput as h, EntityCommand as i, JsonObject as l, LinkGeneratedRelationInput as m, CreateEntityInput as n, EntityPlanState as o, KnownRelationKind as p, DeleteEntityInput as r, EntityStoreSnapshot as s, AuthorableRelationKind as t, JsonPrimitive as u, SandboxRelation as v, UnlinkRelationInput as y };
220
+ //# sourceMappingURL=entity-contract-DycLxdQ5.d.mts.map
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { _ as SandboxRelation, a as EntityPlanState, c as JsonObject, d as KnownEntityKind, f as KnownRelationKind, g as SandboxEntity, h as RelationFacade, i as EntityFacade, l as JsonPrimitive, m as LinkRelationInput, n as CreateEntityInput, o as EntityStoreSnapshot, p as LinkGeneratedRelationInput, r as EntityCommand, s as ImportAssetInput, t as AuthorableRelationKind, u as JsonValue } from "./entity-contract-B3txrzTt.mjs";
2
- import { JournalEntry, ManualSyncDoc, PartIdFactory, SemanticOpName, VideoDocument, VideoDraft, fromVideoDocument } from "@mengine/medeo-client";
1
+ import { _ as SandboxEntity, a as EntityFacade, b as UpdateEntityInput, c as ImportAssetInput, d as JsonValue, f as KnownEntityKind, g as RelationFacade, h as LinkRelationInput, i as EntityCommand, l as JsonObject, m as LinkGeneratedRelationInput, n as CreateEntityInput, o as EntityPlanState, p as KnownRelationKind, r as DeleteEntityInput, s as EntityStoreSnapshot, t as AuthorableRelationKind, u as JsonPrimitive, v as SandboxRelation, y as UnlinkRelationInput } from "./entity-contract-DycLxdQ5.mjs";
2
+ import { JournalEntry, ManualSyncDoc, MediaAssetFact, PartIdFactory, SemanticOpName, VideoDocument, VideoDraft, fromVideoDocument } from "@mengine/medeo-client";
3
3
  import { AddSpeechesInput, AddVideoClipsInput, AdjustBgmVolumeInput, AdjustSpeechVolumeInput, AdjustVideoClipDurationInput, AdjustVideoClipVolumeInput, ChangeSpeechScriptInput, ChangeSpeechVoiceInput, DeleteBgmInput, DeleteSpeechesInput, DeleteVideoClipsInput, MoveSpeechesInput, MoveVideoClipsByAnchorInput, MoveVideoClipsInput, ReplaceVideoClipContentInput, ReplaceVideoClipSequenceInput, SetBgmInput, SetCaptionStyleInput, SetCaptionVisibilityInput, SetVideoClipSpeedShiftInput } from "@mengine/medeo-client/schemas";
4
4
 
5
5
  //#region src/document/compact-projection.d.ts
@@ -56,6 +56,8 @@ interface ChangePlan {
56
56
  entity_base_revision: number;
57
57
  entity_commands: readonly EntityCommand[];
58
58
  entity_rows?: EntityStoreSnapshot;
59
+ deleted_entity_ids?: readonly string[];
60
+ deleted_relation_ids?: readonly string[];
59
61
  preview: string;
60
62
  logs: string[];
61
63
  }
@@ -176,6 +178,8 @@ interface RunEditScriptOptions {
176
178
  entityState?: EntityStoreSnapshot;
177
179
  /** Deterministic id mint label for tests; omit to use the default ULID factory. */
178
180
  idLabel?: string;
181
+ /** @internal Select the graph-native Entity session used by the production host. */
182
+ entityOnly?: boolean;
179
183
  /** Hard wall-clock timeout; default 2000 ms. */
180
184
  timeoutMs?: number;
181
185
  /** V8 old-generation ceiling for the worker; default 256 MB. */
@@ -205,14 +209,46 @@ type EditScriptResult = {
205
209
  /** Run `script` against a forked document snapshot; always resolves (never rejects). */
206
210
  declare function runEditScript(options: RunEditScriptOptions): Promise<EditScriptResult>;
207
211
  //#endregion
212
+ //#region src/entity/generation-sync.d.ts
213
+ /** Factual generation lineage for recalled Memota assets, supplied by the host. */
214
+ interface AssetGenerationFact {
215
+ /** External asset id of the generation output (memota asset or speech result id). */
216
+ readonly outputAssetId: string;
217
+ /** Factual input asset ids; empty for text-only generation. */
218
+ readonly inputAssetIds: readonly string[];
219
+ }
220
+ /**
221
+ * Host callback resolving lineage by external asset id. Implementations return
222
+ * every known generation record involving the given ids in either role; an
223
+ * empty array means no known lineage and a rejection means the lineage query
224
+ * failed. Entity and Relation semantics stay inside this package.
225
+ */
226
+ type GenerationFactsLoader = (docId: string, assetIds: readonly string[]) => Promise<readonly AssetGenerationFact[]>;
227
+ /**
228
+ * Outcome of the post-commit lineage sync. `failed` is always also surfaced as
229
+ * a `generation_sync_failed` warning so an unavailable lineage query is never
230
+ * presented as synced state.
231
+ */
232
+ interface GenerationSyncOutcome {
233
+ /**
234
+ * applied: new generated Relations were committed.
235
+ * current: the query succeeded and nothing was missing (no created asset,
236
+ * single side absent, text-only generation, or pair already linked).
237
+ * failed: the host query or the sync commit failed.
238
+ */
239
+ readonly status: 'applied' | 'current' | 'failed';
240
+ readonly created_relation_ids?: readonly string[];
241
+ readonly message?: string;
242
+ }
243
+ //#endregion
208
244
  //#region src/prompt.d.ts
209
245
  declare const MEDEO_TOOL_DESCRIPTION: string;
210
246
  //#endregion
211
247
  //#region src/schema.d.ts
212
248
  declare const MEDEO_TOOL_NAME = "medeo";
213
- type MedeoToolOp = 'snapshot' | 'run-edit-script' | 'commit-plan';
249
+ type MedeoToolOp = 'snapshot' | 'migrate-legacy' | 'run-edit-script' | 'commit-plan';
214
250
  /**
215
- * JSON Schema for the host-facing three-op `medeo` tool surface.
251
+ * JSON Schema for the host-facing `medeo` tool surface.
216
252
  *
217
253
  * The schema intentionally does not return or accept the full op journal:
218
254
  * journals stay in the tool process and are referenced by `plan_id`. This keeps
@@ -226,7 +262,7 @@ declare const MEDEO_TOOL_PARAMETERS: {
226
262
  readonly properties: {
227
263
  readonly op: {
228
264
  readonly type: 'string';
229
- readonly enum: readonly ['snapshot', 'run-edit-script', 'commit-plan'];
265
+ readonly enum: readonly ['snapshot', 'migrate-legacy', 'run-edit-script', 'commit-plan'];
230
266
  readonly description: 'Which Medeo document operation to run.';
231
267
  };
232
268
  readonly doc_id: {
@@ -237,11 +273,115 @@ declare const MEDEO_TOOL_PARAMETERS: {
237
273
  readonly script: {
238
274
  readonly type: 'string';
239
275
  readonly minLength: 1;
240
- readonly description: 'JavaScript body for run-edit-script. It receives edit, timeline, entities, relations, checkpoint, rollbackTo, inputs, and console. A plan may mutate the timeline or Entity/Relation state, never both.';
276
+ readonly description: '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.';
241
277
  };
242
278
  readonly inputs: {
243
279
  readonly type: 'object';
244
- readonly description: 'Pre-materialized, side-effect-free values passed into the script, including recalled generation lineage and asset facts. Generation and network IO must happen in the host before this call.';
280
+ readonly description: '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.';
281
+ };
282
+ readonly asset_facts: {
283
+ readonly type: 'array';
284
+ readonly description: 'Factual asset metadata recalled by the host for migrate-legacy only. The package reads the canonical legacy snapshot and version itself; never supply a clip trim window as media duration.';
285
+ readonly items: {
286
+ readonly oneOf: readonly [{
287
+ readonly type: 'object';
288
+ readonly additionalProperties: false;
289
+ readonly required: readonly ['assetId', 'kind'];
290
+ readonly properties: {
291
+ readonly assetId: {
292
+ readonly type: 'string';
293
+ readonly minLength: 1;
294
+ };
295
+ readonly kind: {
296
+ readonly const: 'image';
297
+ };
298
+ readonly storageKey: {
299
+ readonly type: 'string';
300
+ readonly minLength: 1;
301
+ };
302
+ };
303
+ }, {
304
+ readonly type: 'object';
305
+ readonly additionalProperties: false;
306
+ readonly required: readonly ['assetId', 'kind', 'durationMs'];
307
+ readonly properties: {
308
+ readonly assetId: {
309
+ readonly type: 'string';
310
+ readonly minLength: 1;
311
+ };
312
+ readonly kind: {
313
+ readonly const: 'video';
314
+ };
315
+ readonly durationMs: {
316
+ readonly type: 'integer';
317
+ readonly minimum: 1;
318
+ };
319
+ readonly storageKey: {
320
+ readonly type: 'string';
321
+ readonly minLength: 1;
322
+ };
323
+ };
324
+ }, {
325
+ readonly type: 'object';
326
+ readonly additionalProperties: false;
327
+ readonly required: readonly ['assetId', 'kind', 'durationMs', 'storageKey'];
328
+ readonly properties: {
329
+ readonly assetId: {
330
+ readonly type: 'string';
331
+ readonly minLength: 1;
332
+ };
333
+ readonly kind: {
334
+ readonly const: 'audio';
335
+ };
336
+ readonly durationMs: {
337
+ readonly type: 'integer';
338
+ readonly minimum: 1;
339
+ };
340
+ readonly storageKey: {
341
+ readonly type: 'string';
342
+ readonly minLength: 1;
343
+ };
344
+ };
345
+ }, {
346
+ readonly type: 'object';
347
+ readonly additionalProperties: false;
348
+ readonly required: readonly ['assetId', 'kind', 'durationMs', 'storageKey', 'voice'];
349
+ readonly properties: {
350
+ readonly assetId: {
351
+ readonly type: 'string';
352
+ readonly minLength: 1;
353
+ };
354
+ readonly durationMs: {
355
+ readonly type: 'integer';
356
+ readonly minimum: 1;
357
+ };
358
+ readonly storageKey: {
359
+ readonly type: 'string';
360
+ readonly minLength: 1;
361
+ };
362
+ readonly voice: {
363
+ readonly type: 'object';
364
+ readonly additionalProperties: false;
365
+ readonly required: readonly ['system', 'key'];
366
+ readonly properties: {
367
+ readonly system: {
368
+ readonly const: 'voice-library';
369
+ };
370
+ readonly key: {
371
+ readonly type: 'string';
372
+ readonly minLength: 1;
373
+ };
374
+ readonly name: {
375
+ readonly type: 'string';
376
+ };
377
+ };
378
+ };
379
+ readonly kind: {
380
+ readonly const: 'voice';
381
+ };
382
+ };
383
+ }];
384
+ };
245
385
  };
246
386
  readonly timeout_ms: {
247
387
  readonly type: 'integer';
@@ -264,11 +404,25 @@ declare const MEDEO_TOOL_PARAMETERS: {
264
404
  };
265
405
  readonly validation: {
266
406
  readonly type: 'string';
267
- readonly enum: readonly ['version', 'preflight'];
268
- readonly description: 'Timeline commit mode: version rejects any concurrent change; preflight revalidates each op. Entity plans always use revision CAS and reject preflight.';
407
+ readonly enum: readonly ['version'];
408
+ readonly description: 'Commit with Entity revision CAS; reject concurrent changes.';
269
409
  };
270
410
  };
271
411
  readonly oneOf: readonly [{
412
+ readonly required: readonly ['op', 'doc_id', 'asset_facts'];
413
+ readonly properties: {
414
+ readonly op: {
415
+ readonly const: 'migrate-legacy';
416
+ };
417
+ readonly doc_id: {
418
+ readonly $ref: '#/properties/doc_id';
419
+ };
420
+ readonly asset_facts: {
421
+ readonly $ref: '#/properties/asset_facts';
422
+ };
423
+ };
424
+ readonly additionalProperties: false;
425
+ }, {
272
426
  readonly required: readonly ['op', 'doc_id'];
273
427
  readonly properties: {
274
428
  readonly op: {
@@ -408,6 +562,15 @@ interface CreateMedeoToolOptions {
408
562
  * snapshot, and tolerates a concurrent creator winning the race.
409
563
  */
410
564
  loadInitialDraft?: (docId: string) => Promise<VideoDraft>;
565
+ /**
566
+ * Resolve factual generation lineage by external asset id after a confirmed
567
+ * entity commit. Return every known generation record involving the given
568
+ * ids in either role; an empty array means no known lineage and a rejection
569
+ * means the lineage query failed (surfaced as a warning, never as synced
570
+ * state). The package owns all Entity/Relation semantics: the host never
571
+ * names entities, relations, or endpoints.
572
+ */
573
+ loadGenerationFacts?: GenerationFactsLoader;
411
574
  fetchImpl?: typeof fetch;
412
575
  /** @deprecated ManualSyncDoc has no SSE or reconnect loop. */
413
576
  sseReconnectDelayMs?: number;
@@ -436,6 +599,10 @@ interface MedeoModelContext {
436
599
  type MedeoToolInput = {
437
600
  op: 'snapshot';
438
601
  doc_id: string;
602
+ } | {
603
+ op: 'migrate-legacy';
604
+ doc_id: string;
605
+ asset_facts: readonly MediaAssetFact[];
439
606
  } | {
440
607
  op: 'run-edit-script';
441
608
  doc_id: string;
@@ -450,15 +617,20 @@ type MedeoToolInput = {
450
617
  plan_id: string;
451
618
  validation?: 'version' | 'preflight';
452
619
  };
453
- interface MedeoToolWarning {
620
+ type MedeoToolWarning = {
454
621
  kind: 'pull_failed';
455
622
  message: string;
456
- }
623
+ } | {
624
+ kind: 'generation_sync_failed';
625
+ message: string;
626
+ };
457
627
  type EntityCommitResult = {
458
628
  kind: 'committed';
459
629
  ops_applied: number;
460
630
  collaborated: false;
461
- entity_revision: number;
631
+ entity_revision: number; /** Present only when the host supplies loadGenerationFacts. */
632
+ generation_sync?: GenerationSyncOutcome;
633
+ warnings?: MedeoToolWarning[];
462
634
  } | {
463
635
  kind: 'unconfirmed';
464
636
  reason: 'push_failed';
@@ -477,6 +649,13 @@ type EntityCommitResult = {
477
649
  };
478
650
  type MedeoCommitResult = CommitPlanResult | EntityCommitResult;
479
651
  type MedeoToolResult = {
652
+ ok: true;
653
+ op: 'migrate-legacy';
654
+ doc_id: string;
655
+ migration_status: 'committed' | 'already_entity';
656
+ entity_revision: number;
657
+ next_action: 'snapshot';
658
+ } | {
480
659
  ok: true;
481
660
  op: 'snapshot';
482
661
  doc_id: string;
@@ -549,5 +728,5 @@ type MedeoInitialDraft = VideoDraft;
549
728
  */
550
729
  declare function createMedeoTool(options: CreateMedeoToolOptions): MedeoTool;
551
730
  //#endregion
552
- export { type AuthorableRelationKind, type ChangePlan, type CommitPlan, type CommitPlanOptions, type CommitPlanResult, type CompactProjectionOptions, type ConsoleShim, type CreateEntityInput, type CreateMedeoToolOptions, type EditFacade, EditSandboxSession, type EditSandboxSessionOptions, type EditScriptResult, type EntityCommand, type EntityCommitResult, type EntityFacade, type EntityPlanState, type EntityStoreSnapshot, type ImportAssetInput, type JsonObject, type JsonPrimitive, type JsonValue, type KnownEntityKind, type KnownRelationKind, type LinkGeneratedRelationInput, type LinkRelationInput, MEDEO_TOOL_DESCRIPTION, MEDEO_TOOL_NAME, MEDEO_TOOL_PARAMETERS, type MedeoCommitResult, type MedeoInitialDraft, type MedeoModelContext, type MedeoModelContextInput, type MedeoTool, type MedeoToolInput, type MedeoToolOp, type MedeoToolResult, type RelationFacade, type RunEditScriptOptions, type SandboxCheckpoint, type SandboxEntity, type SandboxRelation, type TimelineClipDescriptor, type TimelineFacade, type TimelinePartDescriptor, collectAffectedPartIds, commitPlan, createMedeoTool, renderCompactProjection, renderPreview, runEditScript };
731
+ export { type AssetGenerationFact, type AuthorableRelationKind, type ChangePlan, type CommitPlan, type CommitPlanOptions, type CommitPlanResult, type CompactProjectionOptions, type ConsoleShim, type CreateEntityInput, type CreateMedeoToolOptions, type DeleteEntityInput, type EditFacade, EditSandboxSession, type EditSandboxSessionOptions, type EditScriptResult, type EntityCommand, type EntityCommitResult, type EntityFacade, type EntityPlanState, type EntityStoreSnapshot, type GenerationFactsLoader, type GenerationSyncOutcome, type ImportAssetInput, type JsonObject, type JsonPrimitive, type JsonValue, type KnownEntityKind, type KnownRelationKind, type LinkGeneratedRelationInput, type LinkRelationInput, MEDEO_TOOL_DESCRIPTION, MEDEO_TOOL_NAME, MEDEO_TOOL_PARAMETERS, type MedeoCommitResult, type MedeoInitialDraft, type MedeoModelContext, type MedeoModelContextInput, type MedeoTool, type MedeoToolInput, type MedeoToolOp, type MedeoToolResult, type RelationFacade, type RunEditScriptOptions, type SandboxCheckpoint, type SandboxEntity, type SandboxRelation, type TimelineClipDescriptor, type TimelineFacade, type TimelinePartDescriptor, type UnlinkRelationInput, type UpdateEntityInput, collectAffectedPartIds, commitPlan, createMedeoTool, renderCompactProjection, renderPreview, runEditScript };
553
732
  //# sourceMappingURL=index.d.mts.map