Implemented optional concurrency for the LLM backend
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
from audita.core.config import AuditaConfig
|
||||
import threading
|
||||
|
||||
from audita.core.chunking import IndexedSegment, TranscriptSection
|
||||
from audita.core.config import AuditaConfig, ConfigOverrides
|
||||
from audita.core.errors import AuditaLLMError
|
||||
from audita.core.schemas import parse_glossary_yaml, parse_transcript_json
|
||||
from audita.framework.models import CorrectionProposal, ModuleContext, ModuleRunSpec
|
||||
@@ -76,6 +79,35 @@ class RecordingModule:
|
||||
return list(self._proposals)
|
||||
|
||||
|
||||
class ConcurrentRecordingModule:
|
||||
replacement_policy = "require_unique"
|
||||
|
||||
def __init__(self, recorder, barrier):
|
||||
self.module_key = "concurrent"
|
||||
self._recorder = recorder
|
||||
self._barrier = barrier
|
||||
|
||||
def validators(self):
|
||||
return []
|
||||
|
||||
def propose(self, transcript_section, context: ModuleContext):
|
||||
texts = [item.segment.text for item in transcript_section.segments]
|
||||
self._recorder.append(("start", transcript_section.section_index, texts))
|
||||
self._barrier.wait()
|
||||
segment = transcript_section.segments[0].segment
|
||||
return [
|
||||
CorrectionProposal(
|
||||
proposal_index=0,
|
||||
module_instance=context.run_spec.instance_name,
|
||||
module_key=context.run_spec.module_key,
|
||||
id=segment.id,
|
||||
original_text=segment.text.rstrip("."),
|
||||
corrected_text=f"{segment.text.rstrip('.')} revised",
|
||||
confidence=0.9,
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
def test_pipeline_runner_applies_modules_sequentially(tmp_path):
|
||||
transcript = parse_transcript_json(
|
||||
"""
|
||||
@@ -382,3 +414,54 @@ def test_pipeline_runner_uses_real_protected_glossary_validator(tmp_path):
|
||||
assert result.transcript[0].text == "Hrank moves."
|
||||
assert result.skipped_corrections[0].source == "validator:protected_glossary_guard"
|
||||
assert result.skipped_corrections[0].reason == "correction changes protected glossary term usage"
|
||||
|
||||
|
||||
def test_pipeline_runner_collects_section_proposals_concurrently_and_preserves_section_order(tmp_path, monkeypatch):
|
||||
transcript = parse_transcript_json(
|
||||
"""
|
||||
[
|
||||
{"id": 1, "speaker": "A", "start": 0.0, "end": 1.0, "text": "Alpha."},
|
||||
{"id": 2, "speaker": "A", "start": 1.0, "end": 2.0, "text": "Beta."}
|
||||
]
|
||||
"""
|
||||
)
|
||||
glossary = parse_glossary_yaml(
|
||||
"""
|
||||
glossary:
|
||||
- name: "Alpha"
|
||||
category: noun
|
||||
summary: "Alpha."
|
||||
"""
|
||||
)
|
||||
sections = [
|
||||
TranscriptSection(
|
||||
section_index=0,
|
||||
start_index=0,
|
||||
segments=[IndexedSegment(index=0, segment=transcript[0])],
|
||||
token_count=1,
|
||||
),
|
||||
TranscriptSection(
|
||||
section_index=1,
|
||||
start_index=1,
|
||||
segments=[IndexedSegment(index=1, segment=transcript[1])],
|
||||
token_count=1,
|
||||
),
|
||||
]
|
||||
seen = []
|
||||
module = ConcurrentRecordingModule(seen, threading.Barrier(2, timeout=1.0))
|
||||
monkeypatch.setattr("audita.framework.runner.chunk_transcript", lambda working, max_tokens: sections)
|
||||
|
||||
runner = PipelineRunner()
|
||||
result = runner.run(
|
||||
transcript=transcript,
|
||||
glossary=glossary,
|
||||
module_specs=[ModuleRunSpec(instance_name="concurrent", module_key="concurrent", module=module)],
|
||||
config=AuditaConfig.from_sources(env={}, overrides=ConfigOverrides(llm_concurrency=2)),
|
||||
run_dir=tmp_path / "run",
|
||||
)
|
||||
|
||||
assert [change.id for change in result.applied_changes] == [1, 2]
|
||||
assert result.applied_changes[0].corrected_text == "Alpha revised"
|
||||
assert result.applied_changes[1].corrected_text == "Beta revised"
|
||||
assert result.transcript[0].text == "Alpha revised."
|
||||
assert result.transcript[1].text == "Beta revised."
|
||||
|
||||
Reference in New Issue
Block a user