cjm-transcript-decomp-core 0.0.2__tar.gz → 0.0.4__tar.gz
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.
- {cjm_transcript_decomp_core-0.0.2/cjm_transcript_decomp_core.egg-info → cjm_transcript_decomp_core-0.0.4}/PKG-INFO +7 -5
- {cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/README.md +3 -1
- cjm_transcript_decomp_core-0.0.4/cjm_transcript_decomp_core/__init__.py +1 -0
- {cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/cjm_transcript_decomp_core/cli.py +60 -18
- {cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/cjm_transcript_decomp_core/models.py +9 -2
- {cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/cjm_transcript_decomp_core/pipeline.py +17 -2
- {cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4/cjm_transcript_decomp_core.egg-info}/PKG-INFO +7 -5
- cjm_transcript_decomp_core-0.0.4/cjm_transcript_decomp_core.egg-info/entry_points.txt +5 -0
- cjm_transcript_decomp_core-0.0.4/cjm_transcript_decomp_core.egg-info/requires.txt +5 -0
- {cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/pyproject.toml +4 -1
- {cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/tests/test_cli.py +14 -1
- cjm_transcript_decomp_core-0.0.2/cjm_transcript_decomp_core/__init__.py +0 -1
- cjm_transcript_decomp_core-0.0.2/cjm_transcript_decomp_core.egg-info/entry_points.txt +0 -2
- cjm_transcript_decomp_core-0.0.2/cjm_transcript_decomp_core.egg-info/requires.txt +0 -5
- {cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/LICENSE +0 -0
- {cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/MANIFEST.in +0 -0
- {cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/cjm_transcript_decomp_core/alignment.py +0 -0
- {cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/cjm_transcript_decomp_core/graph.py +0 -0
- {cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/cjm_transcript_decomp_core.egg-info/SOURCES.txt +0 -0
- {cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/cjm_transcript_decomp_core.egg-info/dependency_links.txt +0 -0
- {cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/cjm_transcript_decomp_core.egg-info/top_level.txt +0 -0
- {cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/setup.cfg +0 -0
- {cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/tests/test_alignment.py +0 -0
- {cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/tests/test_graph.py +0 -0
- {cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/tests/test_models.py +0 -0
- {cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/tests/test_pipeline.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cjm-transcript-decomp-core
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: A frontend-agnostic core for the transcript decomposition workflow — composes isolated capability workers (forced alignment, VAD, graph storage) into a headless pipeline that decomposes transcription run manifests into a VAD-aligned context-graph spine with traceable provenance, and a CLI as its first driver.
|
|
5
5
|
Author-email: "Christian J. Mills" <9126128+cj-mills@users.noreply.github.com>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -10,10 +10,10 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
10
10
|
Requires-Python: >=3.12
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
License-File: LICENSE
|
|
13
|
-
Requires-Dist: cjm_substrate>=0.0.
|
|
14
|
-
Requires-Dist: cjm_context_graph_primitives>=0.0.
|
|
13
|
+
Requires-Dist: cjm_substrate>=0.0.57
|
|
14
|
+
Requires-Dist: cjm_context_graph_primitives>=0.0.15
|
|
15
15
|
Requires-Dist: cjm_capability_primitives>=0.0.10
|
|
16
|
-
Requires-Dist: cjm-context-graph-layer>=0.0.
|
|
16
|
+
Requires-Dist: cjm-context-graph-layer>=0.0.11
|
|
17
17
|
Requires-Dist: cjm-transcript-graph-schema>=0.0.7
|
|
18
18
|
Dynamic: license-file
|
|
19
19
|
|
|
@@ -45,7 +45,7 @@ A frontend-agnostic core for the transcript decomposition workflow — composes
|
|
|
45
45
|
- `build_parser` _function_ — Build the CLI parser (subcommands: run).
|
|
46
46
|
- `load_capabilities` _function_ — Discover manifests + load each requested capability (default instance).
|
|
47
47
|
- `main` _function_ — CLI entry point (console script: `cjm-transcript-decomp-core`).
|
|
48
|
-
- `run_command` _function_ — Execute the `run` subcommand: extend
|
|
48
|
+
- `run_command` _function_ — Execute the `run` subcommand: extend transcription-run manifest(s) with the fine spine.
|
|
49
49
|
|
|
50
50
|
### `cjm_transcript_decomp_core.graph`
|
|
51
51
|
|
|
@@ -71,6 +71,7 @@ A frontend-agnostic core for the transcript decomposition workflow — composes
|
|
|
71
71
|
- `build_alignment_composition` _function_ — Build the whole-source M×(VAD ∥ T×FA) composition (D8 fan-in, stage-5 variants).
|
|
72
72
|
- `collect_capability_info` _function_ — Record capability identity + data-DB pointers for the run manifest (provenance).
|
|
73
73
|
- `confirm_seam` _function_ — HITL approval seam in its cheapest viable form (log + optional CLI prompt).
|
|
74
|
+
- `decomp_replay_handlers` _function_ — The decomp core's replay vocabulary (DEC 426658f1, replay stays DOMAIN-OWNED).
|
|
74
75
|
- `decompose_source` _function_ — Decompose one source into aligned fine segments with per-transcriber variants.
|
|
75
76
|
- `fa_words_from_result` _function_ — Normalize a typed forced-alignment result into FA words (pure; stage 3).
|
|
76
77
|
- `load_source_manifest` _function_ — Load + lightly validate a transcription-core run manifest.
|
|
@@ -81,3 +82,4 @@ A frontend-agnostic core for the transcript decomposition workflow — composes
|
|
|
81
82
|
## Dependencies
|
|
82
83
|
|
|
83
84
|
**Depends on:** `cjm-capability-primitives`, `cjm-context-graph-layer`, `cjm-context-graph-primitives`, `cjm-substrate`, `cjm-transcript-graph-schema`
|
|
85
|
+
**Used by:** `cjm-transcript-decomp-tui`
|
|
@@ -26,7 +26,7 @@ A frontend-agnostic core for the transcript decomposition workflow — composes
|
|
|
26
26
|
- `build_parser` _function_ — Build the CLI parser (subcommands: run).
|
|
27
27
|
- `load_capabilities` _function_ — Discover manifests + load each requested capability (default instance).
|
|
28
28
|
- `main` _function_ — CLI entry point (console script: `cjm-transcript-decomp-core`).
|
|
29
|
-
- `run_command` _function_ — Execute the `run` subcommand: extend
|
|
29
|
+
- `run_command` _function_ — Execute the `run` subcommand: extend transcription-run manifest(s) with the fine spine.
|
|
30
30
|
|
|
31
31
|
### `cjm_transcript_decomp_core.graph`
|
|
32
32
|
|
|
@@ -52,6 +52,7 @@ A frontend-agnostic core for the transcript decomposition workflow — composes
|
|
|
52
52
|
- `build_alignment_composition` _function_ — Build the whole-source M×(VAD ∥ T×FA) composition (D8 fan-in, stage-5 variants).
|
|
53
53
|
- `collect_capability_info` _function_ — Record capability identity + data-DB pointers for the run manifest (provenance).
|
|
54
54
|
- `confirm_seam` _function_ — HITL approval seam in its cheapest viable form (log + optional CLI prompt).
|
|
55
|
+
- `decomp_replay_handlers` _function_ — The decomp core's replay vocabulary (DEC 426658f1, replay stays DOMAIN-OWNED).
|
|
55
56
|
- `decompose_source` _function_ — Decompose one source into aligned fine segments with per-transcriber variants.
|
|
56
57
|
- `fa_words_from_result` _function_ — Normalize a typed forced-alignment result into FA words (pure; stage 3).
|
|
57
58
|
- `load_source_manifest` _function_ — Load + lightly validate a transcription-core run manifest.
|
|
@@ -62,3 +63,4 @@ A frontend-agnostic core for the transcript decomposition workflow — composes
|
|
|
62
63
|
## Dependencies
|
|
63
64
|
|
|
64
65
|
**Depends on:** `cjm-capability-primitives`, `cjm-context-graph-layer`, `cjm-context-graph-primitives`, `cjm-substrate`, `cjm-transcript-graph-schema`
|
|
66
|
+
**Used by:** `cjm-transcript-decomp-tui`
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.4"
|
|
@@ -10,9 +10,11 @@ Prerequisite runtime (once, from the repo root):
|
|
|
10
10
|
cjm-ctl --cjm-config cjm.yaml setup-runtime
|
|
11
11
|
cjm-ctl --cjm-config cjm.yaml install-all --capabilities capabilities_test.yaml --force
|
|
12
12
|
|
|
13
|
-
Then decompose
|
|
13
|
+
Then decompose transcription-core run manifest(s) — a multi-manifest batch
|
|
14
|
+
shares ONE loaded capability stack (models load once, per-manifest runs):
|
|
14
15
|
|
|
15
16
|
cjm-transcript-decomp-core run path/to/transcription-run.json --yes
|
|
17
|
+
cjm-transcript-decomp-core run runs/run_a.json runs/run_b.json --yes
|
|
16
18
|
# GPU runs: opt into CR-7 GPU subtree attribution
|
|
17
19
|
cjm-transcript-decomp-core run run.json --yes --sysmon-capability cjm-capability-monitor-nvidia
|
|
18
20
|
"""
|
|
@@ -21,11 +23,13 @@ import argparse
|
|
|
21
23
|
import asyncio
|
|
22
24
|
import getpass
|
|
23
25
|
import logging
|
|
26
|
+
import os
|
|
24
27
|
from pathlib import Path
|
|
25
28
|
from typing import Any, Dict, List, Optional
|
|
26
29
|
|
|
27
30
|
from cjm_substrate.core.manager import CapabilityManager
|
|
28
31
|
from cjm_substrate.core.queue import JobQueue
|
|
32
|
+
from cjm_substrate.core.workspace import resolve_workspace
|
|
29
33
|
from cjm_transcript_decomp_core.models import DecompConfig
|
|
30
34
|
from cjm_transcript_decomp_core.pipeline import load_source_manifest, run_decomp
|
|
31
35
|
|
|
@@ -41,7 +45,8 @@ def build_parser() -> argparse.ArgumentParser: # Configured CLI parser
|
|
|
41
45
|
sub = parser.add_subparsers(dest="command", required=True)
|
|
42
46
|
|
|
43
47
|
run = sub.add_parser("run", help="Extend a transcription-emitted graph root with the fine spine")
|
|
44
|
-
run.add_argument("
|
|
48
|
+
run.add_argument("manifests", nargs="+",
|
|
49
|
+
help="Transcription-core run manifest JSON(s) — a batch shares ONE loaded capability stack")
|
|
45
50
|
run.add_argument("--manifests-dir", default=".cjm/manifests", help="Capability manifests directory")
|
|
46
51
|
run.add_argument("--vad-capability", default="cjm-capability-silero-vad", help="VAD capability name")
|
|
47
52
|
run.add_argument("--fa-capability", default="cjm-capability-qwen3-forced-aligner", help="Forced-alignment capability name")
|
|
@@ -56,7 +61,15 @@ def build_parser() -> argparse.ArgumentParser: # Configured CLI parser
|
|
|
56
61
|
run.add_argument("--language", default="English", help="Forced-alignment language")
|
|
57
62
|
run.add_argument("--force", action="store_true", help="Bypass capability-side caches (VAD + FA)")
|
|
58
63
|
run.add_argument("-y", "--yes", action="store_true", help="Auto-accept HITL seams (headless mode)")
|
|
59
|
-
run.add_argument("--output", default=None, help="Decomp-manifest output path (default:
|
|
64
|
+
run.add_argument("--output", default=None, help="Decomp-manifest output path (single-manifest runs only; default: <output-dir>/<run_id>.json)")
|
|
65
|
+
run.add_argument("--output-dir", default=None,
|
|
66
|
+
help="Decomp-manifest output directory (callers with a shared runs dir "
|
|
67
|
+
"pass it so manifests land beside their sources; default: the "
|
|
68
|
+
"workspace's runs/ when one is active, else runs/ under the cwd)")
|
|
69
|
+
run.add_argument("--workspace", default=None,
|
|
70
|
+
help="Workspace root (5daadfc4; default: CJM_WORKSPACE env, else upward walk "
|
|
71
|
+
"from cwd). Supplies the --output-dir default and is exported so "
|
|
72
|
+
"substrate config + capability workers resolve workspace-scoped paths")
|
|
60
73
|
run.add_argument("--actor", default=None,
|
|
61
74
|
help="Journal attribution for who/what initiated this run (default: cli:<username>)")
|
|
62
75
|
run.add_argument("-v", "--verbose", action="store_true", help="DEBUG-level logging")
|
|
@@ -85,11 +98,31 @@ def load_capabilities(
|
|
|
85
98
|
|
|
86
99
|
async def run_command(
|
|
87
100
|
args: argparse.Namespace, # Parsed CLI arguments for the `run` subcommand
|
|
88
|
-
) -> int: # Process exit code (0 =
|
|
89
|
-
"""Execute the `run` subcommand: extend
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
101
|
+
) -> int: # Process exit code (0 = every manifest fully extended + verified)
|
|
102
|
+
"""Execute the `run` subcommand: extend transcription-run manifest(s) with the fine spine.
|
|
103
|
+
|
|
104
|
+
Batch shape (decomp-TUI demand, work item 0ff6bf0f): N manifests ride ONE
|
|
105
|
+
capability stack — the models load once and every manifest reuses them,
|
|
106
|
+
where N CLI invocations would pay N model loads. Each manifest keeps its
|
|
107
|
+
own run_id, decomp manifest, and RUN_STARTED/RUN_FINISHED journal bracket,
|
|
108
|
+
so a batch member is indistinguishable from a solo run downstream. A failed
|
|
109
|
+
member records and the batch continues (unattended queueing must not sink
|
|
110
|
+
the rest); the exit code aggregates across members.
|
|
111
|
+
"""
|
|
112
|
+
# 5daadfc4 workspace: resolve BEFORE any substrate config loads; export so
|
|
113
|
+
# the process tree (substrate config, capability workers) is workspace-scoped.
|
|
114
|
+
ws = resolve_workspace(explicit=getattr(args, "workspace", None))
|
|
115
|
+
if ws is not None:
|
|
116
|
+
os.environ["CJM_WORKSPACE"] = str(ws.root)
|
|
117
|
+
output_dir = (Path(args.output_dir) if args.output_dir
|
|
118
|
+
else (ws.runs_dir if ws is not None else Path("runs")))
|
|
119
|
+
manifest_paths = [str(Path(m).resolve()) for m in args.manifests]
|
|
120
|
+
missing = [m for m in manifest_paths if not Path(m).exists()]
|
|
121
|
+
if missing:
|
|
122
|
+
raise SystemExit(f"source manifest(s) not found: {', '.join(missing)}")
|
|
123
|
+
if args.output and len(manifest_paths) > 1:
|
|
124
|
+
raise SystemExit("--output names ONE decomp manifest — omit it for batch runs "
|
|
125
|
+
"(each lands at runs/<run_id>.json)")
|
|
93
126
|
|
|
94
127
|
cfg = DecompConfig(
|
|
95
128
|
vad_capability=args.vad_capability,
|
|
@@ -118,11 +151,28 @@ async def run_command(
|
|
|
118
151
|
|
|
119
152
|
queue = JobQueue(deps=manager, sysmon_capability_name=args.sysmon_capability)
|
|
120
153
|
await queue.start()
|
|
154
|
+
all_ok = True
|
|
121
155
|
try:
|
|
122
156
|
# CR-14 follow-up: actor attribution (operator identity by default;
|
|
123
157
|
# agents/services pass --actor explicitly).
|
|
124
158
|
actor = args.actor or f"cli:{getpass.getuser()}"
|
|
125
|
-
|
|
159
|
+
for mp in manifest_paths:
|
|
160
|
+
try:
|
|
161
|
+
manifest = await run_decomp(manager, queue, cfg, mp, actor=actor)
|
|
162
|
+
except Exception as e: # One member's failure must not sink the batch
|
|
163
|
+
logger.error(f"decomp failed for {mp}: {e}")
|
|
164
|
+
print(f"FAILED {mp}: {e}")
|
|
165
|
+
all_ok = False
|
|
166
|
+
continue
|
|
167
|
+
out = (Path(args.output) if args.output
|
|
168
|
+
else output_dir / f"{manifest.run_id}.json")
|
|
169
|
+
manifest.save(out, workspace=ws)
|
|
170
|
+
n_manifest_sources = len(load_source_manifest(mp).get("sources", []) or [])
|
|
171
|
+
n_sources = len(manifest.sources)
|
|
172
|
+
n_segs = sum(s.segment_count for s in manifest.sources)
|
|
173
|
+
print(f"decomp manifest: {out}")
|
|
174
|
+
print(f"sources extended: {n_sources}/{n_manifest_sources} segment nodes: {n_segs}")
|
|
175
|
+
all_ok = all_ok and (n_sources == n_manifest_sources)
|
|
126
176
|
finally:
|
|
127
177
|
await queue.stop()
|
|
128
178
|
for iid in reversed(load_order): # Reverse load order; the monitor unloads last
|
|
@@ -130,15 +180,7 @@ async def run_command(
|
|
|
130
180
|
manager.unload_capability(iid)
|
|
131
181
|
except Exception as e: # Best-effort teardown; never mask the run's outcome
|
|
132
182
|
logger.warning(f"unload {iid} failed: {e}")
|
|
133
|
-
|
|
134
|
-
out = Path(args.output) if args.output else Path("runs") / f"{manifest.run_id}.json"
|
|
135
|
-
manifest.save(out)
|
|
136
|
-
n_manifest_sources = len(load_source_manifest(manifest_path).get("sources", []) or [])
|
|
137
|
-
n_sources = len(manifest.sources)
|
|
138
|
-
n_segs = sum(s.segment_count for s in manifest.sources)
|
|
139
|
-
print(f"decomp manifest: {out}")
|
|
140
|
-
print(f"sources extended: {n_sources}/{n_manifest_sources} segment nodes: {n_segs}")
|
|
141
|
-
return 0 if n_sources == n_manifest_sources else 1
|
|
183
|
+
return 0 if all_ok else 1
|
|
142
184
|
|
|
143
185
|
|
|
144
186
|
def main(
|
|
@@ -7,6 +7,8 @@ from dataclasses import asdict, dataclass, field
|
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from typing import Any, Dict, List, Optional, Union
|
|
9
9
|
|
|
10
|
+
from cjm_substrate.core.workspace import relativize_recorded
|
|
11
|
+
|
|
10
12
|
|
|
11
13
|
@dataclass
|
|
12
14
|
class FAWord:
|
|
@@ -173,11 +175,16 @@ class DecompManifest:
|
|
|
173
175
|
def save(
|
|
174
176
|
self,
|
|
175
177
|
path: Union[str, Path], # Destination JSON file (parent dirs created)
|
|
178
|
+
workspace=None, # Active Workspace; owned paths record as ${WS}/<rel> (5daadfc4 rung f)
|
|
176
179
|
) -> Path: # The written path
|
|
177
|
-
"""Write the manifest as pretty-printed JSON.
|
|
180
|
+
"""Write the manifest as pretty-printed JSON.
|
|
181
|
+
|
|
182
|
+
With `workspace`, recorded paths under its root take the ${WS}/ token
|
|
183
|
+
form (relativize_recorded), so the manifest relocates with the
|
|
184
|
+
workspace; readers resolve via resolve_recorded_tree at load."""
|
|
178
185
|
out = Path(path)
|
|
179
186
|
out.parent.mkdir(parents=True, exist_ok=True)
|
|
180
|
-
out.write_text(json.dumps(self.to_dict(), indent=2))
|
|
187
|
+
out.write_text(json.dumps(relativize_recorded(self.to_dict(), workspace), indent=2))
|
|
181
188
|
return out
|
|
182
189
|
|
|
183
190
|
|
|
@@ -10,13 +10,14 @@ from typing import Any, Dict, List, Optional, Tuple
|
|
|
10
10
|
from cjm_capability_primitives.forced_alignment import ForcedAlignResult
|
|
11
11
|
from cjm_capability_primitives.vad import VADResult
|
|
12
12
|
from cjm_context_graph_layer.declare import Derivation, derivation_to_graph
|
|
13
|
-
from cjm_context_graph_layer.journal import journal_extend, sidecar_journal_path
|
|
13
|
+
from cjm_context_graph_layer.journal import journal_extend, sidecar_journal_path, wires_handlers
|
|
14
14
|
from cjm_context_graph_layer.ops import graph_task
|
|
15
15
|
from cjm_substrate.core.empirical_store import compute_config_hash
|
|
16
16
|
from cjm_substrate.core.journal_store import JournalEvent, SubstrateEventType
|
|
17
17
|
from cjm_substrate.core.manager import CapabilityManager
|
|
18
18
|
from cjm_substrate.core.ports import Composition, CompositionNode, NodeState
|
|
19
19
|
from cjm_substrate.core.queue import JobQueue, JobStatus
|
|
20
|
+
from cjm_substrate.core.workspace import resolve_recorded_tree
|
|
20
21
|
from cjm_transcript_decomp_core.alignment import (assign_words_to_chunks,
|
|
21
22
|
build_segments_from_alignment,
|
|
22
23
|
map_fa_words_to_text, tier1_alignment_checks)
|
|
@@ -59,8 +60,11 @@ def load_source_manifest(
|
|
|
59
60
|
|
|
60
61
|
Consumed as untyped JSON — the format/version tags are the only interchange
|
|
61
62
|
contract (no shared schema type across cores; manifest-as-interchange, CR-20).
|
|
63
|
+
${WS}/ recorded paths (5daadfc4 rung f) resolve to absolute here, anchored
|
|
64
|
+
at the manifest's own location (active workspace as fallback), so all
|
|
65
|
+
downstream consumers keep seeing absolute paths.
|
|
62
66
|
"""
|
|
63
|
-
data = json.loads(Path(path).read_text())
|
|
67
|
+
data = resolve_recorded_tree(json.loads(Path(path).read_text()), Path(path))
|
|
64
68
|
fmt = data.get("format", "")
|
|
65
69
|
if "transcription-core" not in fmt:
|
|
66
70
|
logger.warning(f"unexpected source manifest format: {fmt!r} (continuing)")
|
|
@@ -486,3 +490,14 @@ async def run_decomp(
|
|
|
486
490
|
"segments": sum(s.segment_count for s in manifest.sources),
|
|
487
491
|
})
|
|
488
492
|
return manifest
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
def decomp_replay_handlers() -> Dict[str, Any]: # verb -> async handler(queue, graph_id, op)
|
|
496
|
+
"""The decomp core's replay vocabulary (DEC 426658f1, replay stays DOMAIN-OWNED).
|
|
497
|
+
|
|
498
|
+
Exported through the `cjm_context_graph_layer.replay` entry-point group and
|
|
499
|
+
unioned by `composed_replay_handlers`. Both verbs are `journal_extend` ops —
|
|
500
|
+
wire-carrying by construction — so they register the layer's shared
|
|
501
|
+
`apply_wires` (identity-comparable across cores: transcription also emits
|
|
502
|
+
`derivation`, and the shared handler keeps that collision legal)."""
|
|
503
|
+
return wires_handlers("spine-extension", "derivation")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cjm-transcript-decomp-core
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: A frontend-agnostic core for the transcript decomposition workflow — composes isolated capability workers (forced alignment, VAD, graph storage) into a headless pipeline that decomposes transcription run manifests into a VAD-aligned context-graph spine with traceable provenance, and a CLI as its first driver.
|
|
5
5
|
Author-email: "Christian J. Mills" <9126128+cj-mills@users.noreply.github.com>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -10,10 +10,10 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
10
10
|
Requires-Python: >=3.12
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
License-File: LICENSE
|
|
13
|
-
Requires-Dist: cjm_substrate>=0.0.
|
|
14
|
-
Requires-Dist: cjm_context_graph_primitives>=0.0.
|
|
13
|
+
Requires-Dist: cjm_substrate>=0.0.57
|
|
14
|
+
Requires-Dist: cjm_context_graph_primitives>=0.0.15
|
|
15
15
|
Requires-Dist: cjm_capability_primitives>=0.0.10
|
|
16
|
-
Requires-Dist: cjm-context-graph-layer>=0.0.
|
|
16
|
+
Requires-Dist: cjm-context-graph-layer>=0.0.11
|
|
17
17
|
Requires-Dist: cjm-transcript-graph-schema>=0.0.7
|
|
18
18
|
Dynamic: license-file
|
|
19
19
|
|
|
@@ -45,7 +45,7 @@ A frontend-agnostic core for the transcript decomposition workflow — composes
|
|
|
45
45
|
- `build_parser` _function_ — Build the CLI parser (subcommands: run).
|
|
46
46
|
- `load_capabilities` _function_ — Discover manifests + load each requested capability (default instance).
|
|
47
47
|
- `main` _function_ — CLI entry point (console script: `cjm-transcript-decomp-core`).
|
|
48
|
-
- `run_command` _function_ — Execute the `run` subcommand: extend
|
|
48
|
+
- `run_command` _function_ — Execute the `run` subcommand: extend transcription-run manifest(s) with the fine spine.
|
|
49
49
|
|
|
50
50
|
### `cjm_transcript_decomp_core.graph`
|
|
51
51
|
|
|
@@ -71,6 +71,7 @@ A frontend-agnostic core for the transcript decomposition workflow — composes
|
|
|
71
71
|
- `build_alignment_composition` _function_ — Build the whole-source M×(VAD ∥ T×FA) composition (D8 fan-in, stage-5 variants).
|
|
72
72
|
- `collect_capability_info` _function_ — Record capability identity + data-DB pointers for the run manifest (provenance).
|
|
73
73
|
- `confirm_seam` _function_ — HITL approval seam in its cheapest viable form (log + optional CLI prompt).
|
|
74
|
+
- `decomp_replay_handlers` _function_ — The decomp core's replay vocabulary (DEC 426658f1, replay stays DOMAIN-OWNED).
|
|
74
75
|
- `decompose_source` _function_ — Decompose one source into aligned fine segments with per-transcriber variants.
|
|
75
76
|
- `fa_words_from_result` _function_ — Normalize a typed forced-alignment result into FA words (pure; stage 3).
|
|
76
77
|
- `load_source_manifest` _function_ — Load + lightly validate a transcription-core run manifest.
|
|
@@ -81,3 +82,4 @@ A frontend-agnostic core for the transcript decomposition workflow — composes
|
|
|
81
82
|
## Dependencies
|
|
82
83
|
|
|
83
84
|
**Depends on:** `cjm-capability-primitives`, `cjm-context-graph-layer`, `cjm-context-graph-primitives`, `cjm-substrate`, `cjm-transcript-graph-schema`
|
|
85
|
+
**Used by:** `cjm-transcript-decomp-tui`
|
|
@@ -14,7 +14,7 @@ classifiers = [
|
|
|
14
14
|
"Programming Language :: Python :: 3",
|
|
15
15
|
"Programming Language :: Python :: 3 :: Only",
|
|
16
16
|
]
|
|
17
|
-
dependencies = ['cjm_substrate>=0.0.
|
|
17
|
+
dependencies = ['cjm_substrate>=0.0.57', 'cjm_context_graph_primitives>=0.0.15', 'cjm_capability_primitives>=0.0.10', 'cjm-context-graph-layer>=0.0.11', 'cjm-transcript-graph-schema>=0.0.7']
|
|
18
18
|
|
|
19
19
|
[project.urls]
|
|
20
20
|
Repository = "https://github.com/cj-mills/cjm-transcript-decomp-core"
|
|
@@ -22,6 +22,9 @@ Repository = "https://github.com/cj-mills/cjm-transcript-decomp-core"
|
|
|
22
22
|
[project.scripts]
|
|
23
23
|
cjm-transcript-decomp-core = "cjm_transcript_decomp_core.cli:main"
|
|
24
24
|
|
|
25
|
+
[project.entry-points."cjm_context_graph_layer.replay"]
|
|
26
|
+
decomp = "cjm_transcript_decomp_core.pipeline:decomp_replay_handlers"
|
|
27
|
+
|
|
25
28
|
[tool.setuptools.dynamic]
|
|
26
29
|
version = {attr = "cjm_transcript_decomp_core.__version__"}
|
|
27
30
|
|
|
@@ -8,12 +8,16 @@ def test_run_defaults():
|
|
|
8
8
|
p = build_parser()
|
|
9
9
|
args = p.parse_args(["run", "m.json", "--yes", "--language", "English"])
|
|
10
10
|
assert args.command == "run"
|
|
11
|
-
assert args.
|
|
11
|
+
assert args.manifests == ["m.json"] # single manifest = a batch of one
|
|
12
12
|
assert args.yes is True
|
|
13
13
|
assert args.fa_capability == "cjm-capability-qwen3-forced-aligner"
|
|
14
14
|
assert args.graph_capability == "cjm-capability-graph-sqlite"
|
|
15
15
|
assert args.text_from is None # authority defaults to the manifest's sole transcriber
|
|
16
16
|
assert args.sysmon_capability is None
|
|
17
|
+
# 5daadfc4: None sentinel — run_command resolves the workspace's runs/ when
|
|
18
|
+
# one is active, else the legacy cwd-relative runs/; TUIs pin their browsed dir
|
|
19
|
+
assert args.output_dir is None
|
|
20
|
+
assert args.workspace is None
|
|
17
21
|
|
|
18
22
|
|
|
19
23
|
def test_text_from_and_sysmon_flags():
|
|
@@ -22,3 +26,12 @@ def test_text_from_and_sysmon_flags():
|
|
|
22
26
|
"--sysmon-capability", "cjm-capability-monitor-nvidia"])
|
|
23
27
|
assert args.text_from == "cjm-capability-voxtral-hf"
|
|
24
28
|
assert args.sysmon_capability == "cjm-capability-monitor-nvidia"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def test_batch_manifests():
|
|
32
|
+
# Batch shape (work item 0ff6bf0f): N manifests, one invocation, one stack.
|
|
33
|
+
p = build_parser()
|
|
34
|
+
args = p.parse_args(["run", "a.json", "b.json", "c.json", "--yes",
|
|
35
|
+
"--text-from", "cjm-capability-voxtral-hf"])
|
|
36
|
+
assert args.manifests == ["a.json", "b.json", "c.json"]
|
|
37
|
+
assert args.text_from == "cjm-capability-voxtral-hf"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.0.2"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/tests/test_alignment.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cjm_transcript_decomp_core-0.0.2 → cjm_transcript_decomp_core-0.0.4}/tests/test_pipeline.py
RENAMED
|
File without changes
|