davinci-resolve-mcp 2.42.0 → 2.44.0

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.
@@ -29,7 +29,7 @@ from typing import Callable, Dict, Iterator, Optional, Tuple
29
29
 
30
30
  logger = logging.getLogger("resolve-mcp.timeline-brain-db")
31
31
 
32
- SCHEMA_VERSION = 9
32
+ SCHEMA_VERSION = 11
33
33
  DB_FILENAME = "timeline_brain.sqlite"
34
34
  SOUL_DIRNAME = "_soul"
35
35
 
@@ -687,6 +687,85 @@ def _migrate_v9_analysis_core(conn: sqlite3.Connection) -> None:
687
687
  )
688
688
 
689
689
 
690
+ @register_migration(10)
691
+ def _migrate_v10_embeddings(conn: sqlite3.Connection) -> None:
692
+ """C3 — embeddings for similarity search (Phase C of the analysis program).
693
+
694
+ One row per (entity, kind, model). Vectors are float32 BLOBs; similarity
695
+ is brute-force cosine in the app layer (thousands of rows, not millions).
696
+ `content_hash` fingerprints the embedded content so re-runs only re-embed
697
+ entities whose text/frames changed.
698
+ """
699
+ conn.executescript(
700
+ """
701
+ CREATE TABLE IF NOT EXISTS embeddings (
702
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
703
+ entity_type TEXT NOT NULL CHECK(entity_type IN ('clip', 'shot', 'frame', 'segment')),
704
+ entity_uuid TEXT NOT NULL,
705
+ embedding_kind TEXT NOT NULL, -- 'text' | 'visual'
706
+ model_name TEXT NOT NULL,
707
+ dimension INTEGER NOT NULL,
708
+ vector BLOB NOT NULL,
709
+ content_hash TEXT,
710
+ computed_at TEXT NOT NULL,
711
+ UNIQUE(entity_type, entity_uuid, embedding_kind, model_name)
712
+ );
713
+
714
+ CREATE INDEX IF NOT EXISTS ix_embeddings_kind
715
+ ON embeddings(embedding_kind, model_name);
716
+ CREATE INDEX IF NOT EXISTS ix_embeddings_entity
717
+ ON embeddings(entity_type, entity_uuid);
718
+ """
719
+ )
720
+
721
+
722
+ @register_migration(11)
723
+ def _migrate_v11_entities(conn: sqlite3.Connection) -> None:
724
+ """C5 — cross-clip entities (Phase D of the analysis program).
725
+
726
+ `entities` rows start as provisional clusters over the v10 visual
727
+ embeddings (source='clustering', label NULL) and are enriched by one
728
+ host-vision call per cluster representative (source='vision_entity_v1')
729
+ or by humans. `entity_appearances` records every frame an entity was
730
+ seen in, with the clip/shot derivation and the match similarity.
731
+ """
732
+ conn.executescript(
733
+ """
734
+ CREATE TABLE IF NOT EXISTS entities (
735
+ entity_uuid TEXT PRIMARY KEY,
736
+ kind TEXT, -- person|place|object|unknown
737
+ label TEXT,
738
+ description TEXT,
739
+ confidence TEXT,
740
+ source TEXT NOT NULL,
741
+ representative_frame_ref TEXT, -- 'clip_uuid:frame_index'
742
+ representative_frame_path TEXT,
743
+ cluster_size INTEGER,
744
+ created_at TEXT NOT NULL,
745
+ updated_at TEXT NOT NULL
746
+ );
747
+
748
+ CREATE INDEX IF NOT EXISTS ix_entities_kind ON entities(kind);
749
+
750
+ CREATE TABLE IF NOT EXISTS entity_appearances (
751
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
752
+ entity_uuid TEXT NOT NULL,
753
+ clip_uuid TEXT NOT NULL,
754
+ shot_uuid TEXT,
755
+ frame_ref TEXT NOT NULL, -- 'clip_uuid:frame_index'
756
+ similarity REAL,
757
+ UNIQUE(entity_uuid, frame_ref),
758
+ FOREIGN KEY (entity_uuid) REFERENCES entities(entity_uuid) ON DELETE CASCADE
759
+ );
760
+
761
+ CREATE INDEX IF NOT EXISTS ix_entity_appearances_entity
762
+ ON entity_appearances(entity_uuid);
763
+ CREATE INDEX IF NOT EXISTS ix_entity_appearances_clip
764
+ ON entity_appearances(clip_uuid);
765
+ """
766
+ )
767
+
768
+
690
769
  def latest_version(conn: sqlite3.Connection, timeline_name: str) -> Optional[int]:
691
770
  """Return the highest archived version number for `timeline_name`, or None."""
692
771
  row = conn.execute(