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.
- package/CHANGELOG.md +53 -0
- package/README.md +1 -1
- package/docs/SKILL.md +38 -2
- package/docs/guides/control-panel.md +8 -1
- package/install.py +1 -1
- package/package.json +1 -1
- package/src/analysis_dashboard.py +128 -1
- package/src/granular/common.py +1 -1
- package/src/server.py +77 -1
- package/src/utils/embeddings.py +668 -0
- package/src/utils/entities.py +579 -0
- package/src/utils/media_analysis.py +44 -0
- package/src/utils/timeline_brain_db.py +80 -1
|
@@ -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 =
|
|
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(
|