paces 0.0.18__tar.gz → 0.0.19__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.
- {paces-0.0.18 → paces-0.0.19}/PKG-INFO +1 -1
- {paces-0.0.18 → paces-0.0.19}/paces/ask.py +1 -1
- {paces-0.0.18 → paces-0.0.19}/paces/corrections.py +1 -1
- {paces-0.0.18 → paces-0.0.19}/paces/evidence.py +2 -2
- {paces-0.0.18 → paces-0.0.19}/paces/projection.py +1 -1
- paces-0.0.19/paces/segmentation.py +74 -0
- {paces-0.0.18 → paces-0.0.19}/paces/segmenters.py +11 -55
- {paces-0.0.18 → paces-0.0.19}/pyproject.toml +1 -1
- {paces-0.0.18 → paces-0.0.19}/.gitignore +0 -0
- {paces-0.0.18 → paces-0.0.19}/LICENSE +0 -0
- {paces-0.0.18 → paces-0.0.19}/README.md +0 -0
- {paces-0.0.18 → paces-0.0.19}/docs/README.md +0 -0
- {paces-0.0.18 → paces-0.0.19}/docs/alignment/README.md +0 -0
- {paces-0.0.18 → paces-0.0.19}/docs/poc-reference/README.md +0 -0
- {paces-0.0.18 → paces-0.0.19}/docs/poc-reference/artifacts/clips.json +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/__init__.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/__main__.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/bodies/__init__.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/bodies/_base.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/bodies/derivation.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/bodies/document.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/bodies/signal.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/bodies/step.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/cues.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/data/ask/ask.css +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/data/ask/ask.html +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/data/ask/ask.js +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/derivation.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/edits.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/excerpts.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/measure.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/model.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/pose.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/render.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/timed_text.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/paces/tools.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/audio_synth.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/data/body_schemas.json +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/data/routine.json +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/poc_fixture.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/test_ask.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/test_chapters.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/test_cli_surface.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/test_corrections.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/test_cues.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/test_derivation.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/test_edit_protection_residuals.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/test_edits.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/test_evidence.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/test_evidence_schemas.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/test_excerpts.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/test_measure.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/test_pose.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/test_render_media.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/test_roundtrip_poc.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/test_segment.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/test_smoke.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/test_vertical_slice.py +0 -0
- {paces-0.0.18 → paces-0.0.19}/tests/video_synth.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: paces
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.19
|
|
4
4
|
Summary: Turn instructional media into structured, interactive learning material
|
|
5
5
|
Project-URL: Homepage, https://github.com/thorwhalen/paces
|
|
6
6
|
Project-URL: Repository, https://github.com/thorwhalen/paces
|
|
@@ -49,7 +49,7 @@ from paces.corrections import (
|
|
|
49
49
|
time_str,
|
|
50
50
|
)
|
|
51
51
|
from paces.model import seconds_per_unit
|
|
52
|
-
from paces.
|
|
52
|
+
from paces.segmentation import Segmentation
|
|
53
53
|
|
|
54
54
|
PROPOSAL_KIND = "PacesAskProposal"
|
|
55
55
|
ANSWERS_KIND = "PacesAskAnswers"
|
|
@@ -144,7 +144,7 @@ from paces.model import (
|
|
|
144
144
|
StepDocument,
|
|
145
145
|
)
|
|
146
146
|
from paces.projection import to_document
|
|
147
|
-
from paces.
|
|
147
|
+
from paces.segmentation import Segmentation
|
|
148
148
|
|
|
149
149
|
#: The namespace every paces annotation id is derived under. Derived from the
|
|
150
150
|
#: repository URL rather than typed as a literal, so it is reproducible from
|
|
@@ -454,7 +454,7 @@ def to_store(
|
|
|
454
454
|
*seg* is the analysis result; the projection arguments (*doc_id*,
|
|
455
455
|
*title*, *source*, *domain*, *lang*) are :func:`paces.to_document`'s,
|
|
456
456
|
unchanged. Everything else is evidence a segmenter does not carry on
|
|
457
|
-
:class:`~paces.
|
|
457
|
+
:class:`~paces.segmentation.Segmentation` but a pipeline may have:
|
|
458
458
|
|
|
459
459
|
Args:
|
|
460
460
|
store: Any ``lacing.IntervalAnnotationStore`` — ``MemoryStore()`` for
|
|
@@ -21,7 +21,7 @@ from paces.model import (
|
|
|
21
21
|
StepDocument,
|
|
22
22
|
seconds_per_unit,
|
|
23
23
|
)
|
|
24
|
-
from paces.
|
|
24
|
+
from paces.segmentation import SegStep, Segmentation
|
|
25
25
|
|
|
26
26
|
#: Decimal places kept when converting computed seconds to wire decimals —
|
|
27
27
|
#: matches the POC's 0.1 s working resolution with headroom.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""What a segmenter returns: :class:`Segmentation`, its :class:`SegStep` records and
|
|
2
|
+
the ``Span`` they cover — the analysis-result types, with nothing else.
|
|
3
|
+
|
|
4
|
+
They live apart from :mod:`paces.segmenters` (the registry and the
|
|
5
|
+
``segment()`` facade) so a module that only consumes or reshapes a result —
|
|
6
|
+
:mod:`paces.corrections`, :mod:`paces.projection`, :mod:`paces.ask`, the
|
|
7
|
+
evidence layer — depends on the types and not on the facade, and the facade
|
|
8
|
+
can import those modules without a cycle. :mod:`paces.segmenters` re-exports
|
|
9
|
+
every name here, so ``from paces.segmenters import Segmentation`` keeps
|
|
10
|
+
working.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from collections.abc import Mapping
|
|
16
|
+
from dataclasses import dataclass, field
|
|
17
|
+
from typing import Any
|
|
18
|
+
|
|
19
|
+
from paces.model import MetricGrid
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"DFLT_CHAPTERS_CONFIDENCE",
|
|
23
|
+
"DFLT_EXPLICIT_CONFIDENCE",
|
|
24
|
+
"DFLT_GRID_CONFIDENCE",
|
|
25
|
+
"SegStep",
|
|
26
|
+
"Segmentation",
|
|
27
|
+
"Span",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
Span = tuple[float, float] # seconds, half-open
|
|
31
|
+
|
|
32
|
+
# Confidence constants: placement from user-supplied inputs is arithmetic, so
|
|
33
|
+
# what these grade is trust in the inputs, not in any inference.
|
|
34
|
+
DFLT_EXPLICIT_CONFIDENCE = 0.95 # a human said so
|
|
35
|
+
DFLT_GRID_CONFIDENCE = 0.9 # exact given the grid; the grid itself may drift
|
|
36
|
+
DFLT_CHAPTERS_CONFIDENCE = 0.9 # the author said so, in metadata
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass(frozen=True, slots=True, kw_only=True)
|
|
40
|
+
class SegStep:
|
|
41
|
+
"""One named piece of the media, as an analysis result.
|
|
42
|
+
|
|
43
|
+
``name=''`` means "found, not named" — a VALID state, not an error.
|
|
44
|
+
``spans`` is a tuple because a step legitimately appears in several places
|
|
45
|
+
(run-through AND breakdown).
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
id: str
|
|
49
|
+
name: str = ""
|
|
50
|
+
spans: tuple[Span, ...] = ()
|
|
51
|
+
confidence: float = 0.0
|
|
52
|
+
children: tuple["SegStep", ...] = ()
|
|
53
|
+
source: str = "" # which capability produced it
|
|
54
|
+
evidence: Mapping[str, Any] = field(default_factory=dict)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dataclass(frozen=True, slots=True, kw_only=True)
|
|
58
|
+
class Segmentation:
|
|
59
|
+
"""What every segmenter returns. Reviewable, re-runnable, arguable.
|
|
60
|
+
|
|
61
|
+
``boundaries`` is separate from ``steps`` and populated even when naming
|
|
62
|
+
failed: nine excellent unnamed cuts are a useful, honest result. ``steps``
|
|
63
|
+
may be empty while ``boundaries`` is not.
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
steps: tuple[SegStep, ...] = () # ordered; MAY be empty while boundaries is not
|
|
67
|
+
boundaries: tuple[float, ...] = () # the raw cut set, always
|
|
68
|
+
unit: str = "seconds" # "eight" | "rep" | "seconds"
|
|
69
|
+
grid: MetricGrid | None = None
|
|
70
|
+
confidence: float = 0.0
|
|
71
|
+
method: str = "" # which capability ran (the ADR's "reported default")
|
|
72
|
+
flags: tuple[str, ...] = () # 'naming-abstained', 'no-signal', 'try: ...'
|
|
73
|
+
elapsed_s: float = 0.0
|
|
74
|
+
spent_usd: float = 0.0
|
|
@@ -44,55 +44,18 @@ from dataclasses import dataclass, field
|
|
|
44
44
|
from pathlib import Path
|
|
45
45
|
from typing import Any, Callable
|
|
46
46
|
|
|
47
|
+
from paces import corrections as corrections_module
|
|
47
48
|
from paces.model import MetricGrid, seconds_per_unit
|
|
49
|
+
from paces.segmentation import ( # noqa: F401 — re-exported; their home is there
|
|
50
|
+
DFLT_CHAPTERS_CONFIDENCE,
|
|
51
|
+
DFLT_EXPLICIT_CONFIDENCE,
|
|
52
|
+
DFLT_GRID_CONFIDENCE,
|
|
53
|
+
SegStep,
|
|
54
|
+
Segmentation,
|
|
55
|
+
Span,
|
|
56
|
+
)
|
|
48
57
|
from paces.timed_text import normalize_timed_text
|
|
49
58
|
|
|
50
|
-
Span = tuple[float, float] # seconds, half-open
|
|
51
|
-
|
|
52
|
-
# Confidence constants: placement from user-supplied inputs is arithmetic, so
|
|
53
|
-
# what these grade is trust in the inputs, not in any inference.
|
|
54
|
-
DFLT_EXPLICIT_CONFIDENCE = 0.95 # a human said so
|
|
55
|
-
DFLT_GRID_CONFIDENCE = 0.9 # exact given the grid; the grid itself may drift
|
|
56
|
-
DFLT_CHAPTERS_CONFIDENCE = 0.9 # the author said so, in metadata
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
@dataclass(frozen=True, slots=True, kw_only=True)
|
|
60
|
-
class SegStep:
|
|
61
|
-
"""One named piece of the media, as an analysis result.
|
|
62
|
-
|
|
63
|
-
``name=''`` means "found, not named" — a VALID state, not an error.
|
|
64
|
-
``spans`` is a tuple because a step legitimately appears in several places
|
|
65
|
-
(run-through AND breakdown).
|
|
66
|
-
"""
|
|
67
|
-
|
|
68
|
-
id: str
|
|
69
|
-
name: str = ""
|
|
70
|
-
spans: tuple[Span, ...] = ()
|
|
71
|
-
confidence: float = 0.0
|
|
72
|
-
children: tuple["SegStep", ...] = ()
|
|
73
|
-
source: str = "" # which capability produced it
|
|
74
|
-
evidence: Mapping[str, Any] = field(default_factory=dict)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
@dataclass(frozen=True, slots=True, kw_only=True)
|
|
78
|
-
class Segmentation:
|
|
79
|
-
"""What every segmenter returns. Reviewable, re-runnable, arguable.
|
|
80
|
-
|
|
81
|
-
``boundaries`` is separate from ``steps`` and populated even when naming
|
|
82
|
-
failed: nine excellent unnamed cuts are a useful, honest result. ``steps``
|
|
83
|
-
may be empty while ``boundaries`` is not.
|
|
84
|
-
"""
|
|
85
|
-
|
|
86
|
-
steps: tuple[SegStep, ...] = () # ordered; MAY be empty while boundaries is not
|
|
87
|
-
boundaries: tuple[float, ...] = () # the raw cut set, always
|
|
88
|
-
unit: str = "seconds" # "eight" | "rep" | "seconds"
|
|
89
|
-
grid: MetricGrid | None = None
|
|
90
|
-
confidence: float = 0.0
|
|
91
|
-
method: str = "" # which capability ran (the ADR's "reported default")
|
|
92
|
-
flags: tuple[str, ...] = () # 'naming-abstained', 'no-signal', 'try: ...'
|
|
93
|
-
elapsed_s: float = 0.0
|
|
94
|
-
spent_usd: float = 0.0
|
|
95
|
-
|
|
96
59
|
|
|
97
60
|
@dataclass(frozen=True, slots=True, kw_only=True)
|
|
98
61
|
class Capability:
|
|
@@ -354,13 +317,6 @@ def _facts(
|
|
|
354
317
|
return frozenset(facts)
|
|
355
318
|
|
|
356
319
|
|
|
357
|
-
def _corrections_api():
|
|
358
|
-
""":mod:`paces.corrections`, imported lazily: it imports this module."""
|
|
359
|
-
from paces import corrections
|
|
360
|
-
|
|
361
|
-
return corrections
|
|
362
|
-
|
|
363
|
-
|
|
364
320
|
def _apply_corrections(
|
|
365
321
|
result: Segmentation, log: tuple, capability: Capability | None
|
|
366
322
|
) -> Segmentation:
|
|
@@ -370,7 +326,7 @@ def _apply_corrections(
|
|
|
370
326
|
unmatched — rather than dropped."""
|
|
371
327
|
if not log or (capability is not None and "corrections" in capability.reads):
|
|
372
328
|
return result
|
|
373
|
-
return
|
|
329
|
+
return corrections_module.replay(result, log)
|
|
374
330
|
|
|
375
331
|
|
|
376
332
|
# ── the facade ──────────────────────────────────────────────────────────────
|
|
@@ -418,7 +374,7 @@ def segment(
|
|
|
418
374
|
transcript_cues = normalize_timed_text(transcript)
|
|
419
375
|
# fail fast: a malformed log raises before any segmenter runs
|
|
420
376
|
correction_log = (
|
|
421
|
-
|
|
377
|
+
corrections_module.normalize_corrections(corrections)
|
|
422
378
|
if corrections is not None
|
|
423
379
|
else ()
|
|
424
380
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|