Document Scriptorium session recap integration
This commit is contained in:
245
README.md
245
README.md
@@ -1,136 +1,157 @@
|
|||||||
# narratio
|
# narratio
|
||||||
|
|
||||||
`narratio` is a Go-based orchestration application for processing D&D session audio into transcripts and downstream artifacts.
|
`narratio` is a Go orchestration application for processing D&D session audio into transcripts and generated artifacts.
|
||||||
|
|
||||||
This repository currently contains a **working scaffold** with strict config loading, local workdir/manifest handling, resumable stage control, real WhisperX/Seriatim/Audita adapters, and real `prepare` + `transcribe` + `merge` + `polish` stages.
|
## Current Implementation
|
||||||
|
|
||||||
## Expected Config Files
|
|
||||||
|
|
||||||
`narratio` expects two YAML files:
|
|
||||||
|
|
||||||
- `pipeline.yml`: pipeline/workspace settings (`workspace`, `storage`, `whisperx`, `seriatim`, `audita`, optional `scriptorium`, `analyzer`, `notification`)
|
|
||||||
- `session.yml`: per-session settings (`session_id`, `inputs`, optional metadata)
|
|
||||||
|
|
||||||
WhisperX config contract in `pipeline.yml`:
|
|
||||||
|
|
||||||
- required: `whisperx.transcribe_url`
|
|
||||||
- defaulted when omitted: `whisperx.language` (`en`), `whisperx.timeout` (`30m`), `whisperx.retries` (`3`), `whisperx.retry_delay` (`2s`), `whisperx.concurrency` (`2`)
|
|
||||||
|
|
||||||
Seriatim config contract in `pipeline.yml`:
|
|
||||||
|
|
||||||
- required: `seriatim.binary` (name or path; existence is checked at execution time, not config validation time)
|
|
||||||
- defaulted when omitted: `seriatim.timeout` (`10m`), `seriatim.output_schema` (`seriatim-intermediate`), `seriatim.coalesce_gap` (`3.0`), `seriatim.report` (`true`)
|
|
||||||
- allowed `seriatim.output_schema` values: `seriatim-minimal`, `seriatim-intermediate`, `seriatim-full`
|
|
||||||
- optional tuning: `seriatim.env.*` (`overlap_word_run_gap`, `overlap_word_run_reorder_window`, `backchannel_max_duration`, `filler_max_duration`) must be `> 0` when provided
|
|
||||||
|
|
||||||
Audita config contract in `pipeline.yml`:
|
|
||||||
|
|
||||||
- required: `audita.binary` (name or path; existence is checked at execution time, not config validation time)
|
|
||||||
- optional: `audita.llm_api_key_env` (environment variable name holding the API key secret; no automatic default)
|
|
||||||
- defaulted when omitted: `audita.timeout` (`3h`), `audita.modules` (`glossary,homophones,glossary,spoken_word,grammar,homophones,glossary`), `audita.base_url` (`https://openrouter.ai/api/v1`), `audita.model` (`openrouter/google/gemma-4-31b-it`), `audita.llm_concurrency` (`1`), `audita.validation_model` (`""`), `audita.validation_llm_concurrency` (`1`), `audita.report` (`true`)
|
|
||||||
- allowed `audita.modules` values: `glossary`, `homophones`, `spoken_word`, `grammar` (order and repeats are allowed)
|
|
||||||
- `audita.base_url` must be a valid URL when provided
|
|
||||||
- `audita.llm_concurrency` and `audita.validation_llm_concurrency` must be `> 0`
|
|
||||||
|
|
||||||
Audita credentials note:
|
|
||||||
|
|
||||||
- store only the environment variable **name** in config (`audita.llm_api_key_env`), never the API key value itself
|
|
||||||
- API key values must not be written to pipeline config, generated configs, logs, or manifest metadata
|
|
||||||
- if `audita.llm_api_key_env` is configured and the named env var is not set (or is empty), Narratio fails before invocation with a redacted error
|
|
||||||
- if `audita.llm_api_key_env` is omitted/empty, Narratio does not require a credential and omits `AUDITA_LLM_API_KEY` from the subprocess overrides
|
|
||||||
|
|
||||||
Audita runtime note:
|
|
||||||
|
|
||||||
- Narratio currently passes primary LLM concurrency via `AUDITA_LLM_CONCURRENCY` subprocess environment override, not a `--llm-concurrency` flag.
|
|
||||||
|
|
||||||
Scriptorium config contract in `pipeline.yml` (optional until `analyze` is implemented):
|
|
||||||
|
|
||||||
- optional section: `scriptorium` (when omitted, current pipeline behavior is unchanged)
|
|
||||||
- required when `scriptorium` is present: `scriptorium.binary` (name on PATH or full path)
|
|
||||||
- optional: `scriptorium.config_path` (if set, it must be non-empty; file existence is validated at execution time, not basic config validation time)
|
|
||||||
- defaulted when omitted inside present `scriptorium` section: `scriptorium.timeout` (`10m`)
|
|
||||||
- optional: `scriptorium.render_debug` (`false` by default through YAML zero-value behavior)
|
|
||||||
- artifact definitions live under `scriptorium.artifacts.<artifact_name>` and support multiple configured artifacts
|
|
||||||
- enabled artifacts require `prompt_id` and `output_path`
|
|
||||||
- artifact `timeout` values must be valid Go durations when provided
|
|
||||||
- input definitions live under `scriptorium.artifacts.<artifact_name>.inputs.<input_name>` and require non-empty `source`
|
|
||||||
- `vars` values currently accept booleans and strings only
|
|
||||||
- Narratio does not store secrets in Scriptorium config; keep credentials in environment management, not YAML
|
|
||||||
|
|
||||||
Scriptorium initial artifact note:
|
|
||||||
|
|
||||||
- this pass does not auto-create `session_recap`; configure `scriptorium.artifacts.session_recap` explicitly in `pipeline.yml`
|
|
||||||
|
|
||||||
`speakers.yml` note:
|
|
||||||
|
|
||||||
- use Seriatim’s documented `match:` format (not the legacy direct mapping style used by older scripts/scaffolds)
|
|
||||||
- see [`examples/speakers.yml`](examples/speakers.yml) for a concrete `match:` example.
|
|
||||||
|
|
||||||
Prepared inputs note:
|
|
||||||
|
|
||||||
- `prepare` copies session inputs into the session workdir (`work/<session_id>/inputs`), and downstream stages consume those prepared copies, not the original source files.
|
|
||||||
- If you edit `speakers.yml`, `autocorrect.yml`, `glossary.yml`, or session input paths after `prepare` has run, rerun `prepare` with `--force` before rerunning downstream stages.
|
|
||||||
|
|
||||||
Decoding is strict (`KnownFields(true)`), so unknown YAML fields fail fast.
|
|
||||||
|
|
||||||
Example minimal files are available under `examples/`:
|
|
||||||
|
|
||||||
- `examples/pipeline.minimal.yml`
|
|
||||||
- `examples/session.minimal.yml`
|
|
||||||
|
|
||||||
## Current Scaffold Status
|
|
||||||
|
|
||||||
Implemented now:
|
Implemented now:
|
||||||
|
|
||||||
- strict config load + validation
|
- strict config loading/validation (`pipeline.yml` and `session.yml`)
|
||||||
- local artifact/workdir creation and locking
|
- local workspace/session layout, locking, and manifest persistence
|
||||||
- manifest create/load/save and stage status tracking
|
- resumable stage control (`run`, `plan`, `resume`, `run-stage`, `status`)
|
||||||
- stage framework with real `prepare`, `transcribe`, `merge`, and `polish` stages; placeholder downstream stages
|
- real `prepare`, `transcribe`, `merge`, and `polish` stages
|
||||||
- resumable run control (`run`, `resume`, `run-stage`, `plan` with run/skip decisions)
|
- real WhisperX, Seriatim, and Audita adapters
|
||||||
- real WhisperX HTTP adapter plus real Seriatim/Audita subprocess adapters (with fake/no-op adapters for test/scaffold usage)
|
- real Scriptorium subprocess adapter
|
||||||
|
- real `analyze` stage for `session_recap`
|
||||||
|
- optional Scriptorium render diagnostics (`render_debug`)
|
||||||
|
|
||||||
Not implemented yet:
|
Not implemented yet:
|
||||||
|
|
||||||
- real analyzer integration
|
- real `normalize` behavior
|
||||||
- real remote archive/storage backend
|
- real `archive` behavior
|
||||||
- real notification backend
|
- real `notify` behavior
|
||||||
|
- additional analyze artifacts beyond `session_recap`
|
||||||
|
- generic DAG orchestration
|
||||||
|
|
||||||
## Run Tests
|
## Config Files
|
||||||
|
|
||||||
|
Narratio expects two YAML files:
|
||||||
|
|
||||||
|
- `pipeline.yml`: pipeline/workspace settings
|
||||||
|
- `session.yml`: per-session settings
|
||||||
|
|
||||||
|
YAML decoding is strict (`KnownFields(true)`), so unknown fields fail fast.
|
||||||
|
|
||||||
|
## Scriptorium Configuration
|
||||||
|
|
||||||
|
`pipeline.scriptorium` is optional. When present, Narratio validates and uses it for analyze-stage artifact generation.
|
||||||
|
|
||||||
|
Key points:
|
||||||
|
|
||||||
|
- `scriptorium.binary` is required when section is present
|
||||||
|
- `scriptorium.config_path` is optional
|
||||||
|
- `scriptorium.timeout` defaults to `10m` when omitted
|
||||||
|
- `scriptorium.render_debug` enables render diagnostics globally
|
||||||
|
- artifacts are configured under `scriptorium.artifacts` (map shape supports multiple artifacts)
|
||||||
|
- enabled artifacts require `prompt_id` and `output_path`
|
||||||
|
- artifact `render_debug` may override global render setting
|
||||||
|
- `vars` currently support boolean and string values
|
||||||
|
|
||||||
|
Example `session_recap` artifact definition:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
scriptorium:
|
||||||
|
binary: "scriptorium"
|
||||||
|
config_path: "/etc/scriptorium/config.yml"
|
||||||
|
timeout: "10m"
|
||||||
|
render_debug: false
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
session_recap:
|
||||||
|
enabled: true
|
||||||
|
prompt_id: "dnd.session_recap"
|
||||||
|
profile_id: "local-quality" # optional
|
||||||
|
output_path: "artifacts/session_recap.md"
|
||||||
|
timeout: "10m"
|
||||||
|
# render_debug: true # optional per-artifact override
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
transcript:
|
||||||
|
source: "processed_transcript"
|
||||||
|
required: true
|
||||||
|
|
||||||
|
previous_recap:
|
||||||
|
source: "previous_session_artifact"
|
||||||
|
artifact: "session_recap"
|
||||||
|
path: "" # optional; set when available
|
||||||
|
required: false
|
||||||
|
|
||||||
|
vars:
|
||||||
|
session_id: true
|
||||||
|
session_date: true
|
||||||
|
campaign_name: true
|
||||||
|
previous_session_id: true
|
||||||
|
output_kind: "session_recap"
|
||||||
|
```
|
||||||
|
|
||||||
|
Prompt IDs and profile IDs are configuration values. They are not hardcoded in analyze-stage logic.
|
||||||
|
|
||||||
|
Do not put secrets in `pipeline.yml`. If API-key behavior is configured, use env var names only.
|
||||||
|
|
||||||
|
## Scriptorium Runtime Behavior
|
||||||
|
|
||||||
|
Narratio integrates with Scriptorium through the public CLI subprocess contract:
|
||||||
|
|
||||||
|
- generation: `scriptorium run`
|
||||||
|
- diagnostics/testing: `scriptorium render --format json` when `render_debug` is enabled
|
||||||
|
|
||||||
|
For the initial implementation, only `session_recap` generation is supported.
|
||||||
|
|
||||||
|
Analyze-stage session recap behavior:
|
||||||
|
|
||||||
|
- uses processed transcript input (`transcripts/processed.json`)
|
||||||
|
- optionally includes `previous_recap` when configured and resolvable
|
||||||
|
- omits optional previous recap when unavailable
|
||||||
|
- fails if required inputs are missing
|
||||||
|
- validates output file exists and is non-empty
|
||||||
|
|
||||||
|
Expected session output paths:
|
||||||
|
|
||||||
|
- `artifacts/session_recap.md`
|
||||||
|
- `logs/scriptorium.session_recap.stdout.log`
|
||||||
|
- `logs/scriptorium.session_recap.stderr.log`
|
||||||
|
- `config/scriptorium.session_recap.generated.yml`
|
||||||
|
- `artifacts/session_recap.render.json` when render diagnostics are enabled
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
Starter files:
|
||||||
|
|
||||||
|
- `examples/pipeline.minimal.yml`
|
||||||
|
- `examples/session.minimal.yml`
|
||||||
|
- `examples/speakers.yml`
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
Run tests:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go test ./...
|
go test ./...
|
||||||
```
|
```
|
||||||
|
|
||||||
## Run Plan
|
Plan a run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go run ./cmd/narratio plan --config examples/pipeline.minimal.yml --session examples/session.minimal.yml
|
go run ./cmd/narratio plan --config examples/pipeline.minimal.yml --session examples/session.minimal.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
## Run Pipeline (Current State)
|
Run full pipeline:
|
||||||
|
|
||||||
The current `run` command executes `prepare` + real `transcribe` + real `merge` + real `polish` + placeholder downstream stages and records progress in `manifest.json`.
|
|
||||||
|
|
||||||
Default CLI wiring builds and uses:
|
|
||||||
|
|
||||||
- real WhisperX HTTP adapter from `pipeline.whisperx`
|
|
||||||
- real Seriatim subprocess adapter from `pipeline.seriatim`
|
|
||||||
- real Audita subprocess adapter from `pipeline.audita`
|
|
||||||
|
|
||||||
Subprocess runtime note:
|
|
||||||
|
|
||||||
- subprocesses inherit the parent environment by default, then apply Narratio override values (override values win).
|
|
||||||
- non-zero subprocess errors include stdout/stderr log paths and a short redacted stderr tail when available to speed diagnosis.
|
|
||||||
|
|
||||||
Real `polish` stage output paths:
|
|
||||||
|
|
||||||
- `transcripts/processed.json`
|
|
||||||
- `artifacts/audita.report.json` (when `audita.report: true`)
|
|
||||||
- `artifacts/audita-work`
|
|
||||||
- `logs/audita.stdout.log`
|
|
||||||
- `logs/audita.stderr.log`
|
|
||||||
- `config/audita.generated.yml`
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go run ./cmd/narratio run --config examples/pipeline.minimal.yml --session examples/session.minimal.yml
|
go run ./cmd/narratio run --config examples/pipeline.minimal.yml --session examples/session.minimal.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Run analyze only:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go run ./cmd/narratio run-stage --config examples/pipeline.minimal.yml --session examples/session.minimal.yml analyze
|
||||||
|
```
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
|
||||||
|
Near-term roadmap:
|
||||||
|
|
||||||
|
- extend analyze to additional configured artifacts
|
||||||
|
- support workflows where later artifacts consume earlier generated artifacts
|
||||||
|
- keep orchestration explicit without a generic DAG engine
|
||||||
|
- implement archive and notify backends
|
||||||
|
|||||||
1038
architecture.md
1038
architecture.md
File diff suppressed because it is too large
Load Diff
@@ -217,23 +217,40 @@ Narratio should treat non-zero exit codes as failed stage execution, but may rec
|
|||||||
|
|
||||||
## 17. Suggested Narratio Configuration Shape
|
## 17. Suggested Narratio Configuration Shape
|
||||||
|
|
||||||
Illustrative (not required schema):
|
Illustrative `pipeline.yml` shape:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
scriptorium:
|
scriptorium:
|
||||||
|
binary: scriptorium
|
||||||
config_path: /etc/scriptorium/config.yml
|
config_path: /etc/scriptorium/config.yml
|
||||||
stages:
|
timeout: 10m
|
||||||
|
render_debug: false
|
||||||
|
artifacts:
|
||||||
session_recap:
|
session_recap:
|
||||||
|
enabled: true
|
||||||
prompt_id: dnd.session_recap
|
prompt_id: dnd.session_recap
|
||||||
profile_id: local-quality # optional
|
profile_id: local-quality # optional
|
||||||
inputs: [transcript, glossary, previous_recap]
|
output_path: artifacts/session_recap.md
|
||||||
vars: [session_id, session_date, campaign_name]
|
timeout: 10m
|
||||||
output_path_template: artifacts/{session_id}/session_recap.md
|
render_debug: false # optional artifact override
|
||||||
timeout: 2m
|
inputs:
|
||||||
render_debug: false
|
transcript:
|
||||||
|
source: processed_transcript
|
||||||
|
required: true
|
||||||
|
previous_recap:
|
||||||
|
source: previous_session_artifact
|
||||||
|
artifact: session_recap
|
||||||
|
path: "" # optional
|
||||||
|
required: false
|
||||||
|
vars:
|
||||||
|
session_id: true
|
||||||
|
session_date: true
|
||||||
|
campaign_name: true
|
||||||
|
previous_session_id: true
|
||||||
|
output_kind: session_recap
|
||||||
```
|
```
|
||||||
|
|
||||||
The key idea: map Narratio stage/artifact names to prompt ID, optional profile, expected inputs, and output destination.
|
The key idea: map Narratio artifact names to prompt ID, optional profile, expected inputs, vars, and output destination.
|
||||||
|
|
||||||
## 18. Testing Strategy for Narratio Integration
|
## 18. Testing Strategy for Narratio Integration
|
||||||
|
|
||||||
@@ -317,6 +334,6 @@ Possible later extensions:
|
|||||||
|
|
||||||
- HTTP API integration
|
- HTTP API integration
|
||||||
- S3 artifact references if Scriptorium adds S3 reader support
|
- S3 artifact references if Scriptorium adds S3 reader support
|
||||||
- storing render diagnostics alongside generated artifacts
|
- richer render diagnostics and policy controls
|
||||||
- token budgeting/prompt-size checks
|
- token budgeting/prompt-size checks
|
||||||
- batch execution if Scriptorium later adds batch support
|
- batch execution if Scriptorium later adds batch support
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ scriptorium:
|
|||||||
profile_id: "local-quality"
|
profile_id: "local-quality"
|
||||||
output_path: "artifacts/session_recap.md"
|
output_path: "artifacts/session_recap.md"
|
||||||
timeout: "10m"
|
timeout: "10m"
|
||||||
|
# Optional per-artifact override of global scriptorium.render_debug.
|
||||||
|
# render_debug: true
|
||||||
inputs:
|
inputs:
|
||||||
transcript:
|
transcript:
|
||||||
source: "processed_transcript"
|
source: "processed_transcript"
|
||||||
@@ -62,6 +64,7 @@ scriptorium:
|
|||||||
previous_recap:
|
previous_recap:
|
||||||
source: "previous_session_artifact"
|
source: "previous_session_artifact"
|
||||||
artifact: "session_recap"
|
artifact: "session_recap"
|
||||||
|
# Optional: set when previous recap is available.
|
||||||
path: ""
|
path: ""
|
||||||
required: false
|
required: false
|
||||||
vars:
|
vars:
|
||||||
|
|||||||
Reference in New Issue
Block a user