Sfoglia il codice sorgente

Updated documentation

Efren Yevale Varela 3 settimane fa
parent
commit
90f760cbc4
9 ha cambiato i file con 26 aggiunte e 16 eliminazioni
  1. 5 4
      AGENTS.md
  2. 0 4
      README.md
  3. 3 3
      docs/ASSISTANT.md
  4. 4 0
      docs/CLI.md
  5. 4 1
      docs/DEVELOPMENT.md
  6. 4 0
      docs/OUTPUT.md
  7. 2 1
      docs/TRIAGE.md
  8. 3 2
      docs/TROUBLESHOOTING.md
  9. 1 1
      src/stt_daemon/assistant/brief_file.py

+ 5 - 4
AGENTS.md

@@ -77,9 +77,10 @@ publish-only.
   `confirm_s`, `max_prototypes`, `provisional_ttl_h`, `store_dir`, `join_timeout_s`). Needs
   `uv sync --extra speaker` plus a model under `models/`. Full reference: `docs/SPEAKERS.md`.
 - `[brief]` is opt-in durable-brief persistence, backed by the `BriefConfig` dataclass (13th
-  known section; 3 keys: `write` (default `false`, gates disk persistence only), `dir`,
-  `filename`). The default writes `brief/brief.md` (cwd-relative, gitignored); with `write =
-  false` the brief stays in the TUI only. Full reference: `docs/TRIAGE.md`.
+  known section; 1 key: `write` (default `false`, gates disk persistence only)). The writer
+  defaults to `brief/brief.md` (cwd-relative, gitignored; `directory`/`filename` are `BriefFile`
+  ctor defaults, not config keys) and `set_directory()` repoints it at the active session folder;
+  with `write = false` the brief stays in the TUI only. Full reference: `docs/TRIAGE.md`.
 - Never treat the live `config.toml` as a source of defaults; it is gitignored user state.
 
 ## Transcription backends
@@ -93,7 +94,7 @@ publish-only.
 
 ## Testing
 
-- `tests/` has 1028 tests, all hardware- and network-free. Preserve that: inject fakes instead of
+- `tests/` has 1038 tests, all hardware- and network-free. Preserve that: inject fakes instead of
   touching real `pactl`, audio devices, an LLM, or `sherpa_onnx` (the speaker lane uses a fake
   embedder; no ONNX in tests).
 - Key seams: `Daemon(...)` accepts `capture_factory`, `vad_factory`, `transcriber_factory`,

+ 0 - 4
README.md

@@ -169,7 +169,3 @@ See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for what the tests cover.
 ## License
 
 This project is ISC-licensed. See [`LICENSE.md`](LICENSE.md).
-
----
-
-Made with ❤️ for Efren. Questions? Open an issue or reach out.

+ 3 - 3
docs/ASSISTANT.md

@@ -184,9 +184,9 @@ brief. Off by default; enable `[triage]` and install the extra to use it (see
 
 The classifier runs **in-process** in the assistant on its own background thread (one worker plus a
 loader), never on the tick thread and never on the `InferenceQueue`. The Laya **multilingual**
-checkpoint is pinned for every call. This is the third single-worker lane: transcription
-(faster-whisper, not thread-safe), the LLM `InferenceQueue`, and the Laya triage lane. None of the
-three may be parallelized.
+checkpoint is pinned for every call. This is the fourth single-worker lane: transcription
+(faster-whisper, not thread-safe), the daemon-side speaker embedding lane, the LLM `InferenceQueue`,
+and the Laya triage lane. None of the four may be parallelized.
 
 On each settled turn in any mode (idle, chat, or command; `turn_ended()`), independent of chat,
 the lane classifies the last `window` transcribed utterances from the STT stream (not the chat

+ 4 - 0
docs/CLI.md

@@ -22,6 +22,10 @@ Non-interactive setup (specify sources directly):
 uv run stt-daemon setup --sources "alsa_input.usb-Foo,alsa_output.pci-0000.monitor"
 ```
 
+`setup` also accepts `--yes` to skip the confirmation prompt. Like every subcommand, it
+accepts the common overrides `--config`, `--device`, `--backend`, `--model`, `--language`,
+and `-v/--verbose`.
+
 This creates:
 - A null sink (by default `VirtualMicSink`)
 - A remap-source to expose the sink's monitor as a microphone (by default `VirtualMic`)

+ 4 - 1
docs/DEVELOPMENT.md

@@ -41,6 +41,8 @@ src/stt_daemon/
 ├── picker.py            - Interactive device picker (questionary / numbered menu)
 ├── segmenter.py         - VAD + pre-roll buffer + utterance segmentation (core)
 ├── transcriber.py       - Faster-Whisper wrapper
+├── pywhispercpp_transcriber.py - whisper.cpp GPU backend (vendored wheel)
+├── session.py           - Session folder lifecycle (gap rollover, current id)
 ├── speakers.py          - Speaker prototype store, matcher, mint/adapt guards
 ├── embedder.py          - sherpa-onnx embedding extractor (lazy import, build_embedder)
 ├── enroll.py            - Offline pre-enrollment from WAV files (`speaker-enroll`)
@@ -48,6 +50,7 @@ src/stt_daemon/
 ├── evaluate.py          - Labeled-clip accuracy scorer (`speaker-eval`)
 ├── output.py            - Sinks (stdout, JSONL, optional WAV)
 ├── daemon.py            - Orchestrator (threads, queues, event emission)
+├── supervisor.py        - Supervised child processes (`up`, incl. mandatory TUI + ISIG restore)
 ├── events.py            - NDJSON event envelope + codec
 ├── bus.py               - Publish-only event bus (socket, ring replay)
 ├── debug.py             - Structured health-signal log (`DebugSink`, `troubleshoot/debug/YYYY-MM-DD.jsonl`)
@@ -71,7 +74,7 @@ src/stt_daemon/
     ├── client.py        - Control-socket client
     └── app.py           - Textual app + `stt-tui` entry point
 
-tests/                    - 1028 tests, no audio hardware or live LLM required
+tests/                    - 1038 tests, no audio hardware or live LLM required
 
 scripts/
 ├── audio-sink.sh        - Thin wrapper over `stt-daemon setup|clear|list`

+ 4 - 0
docs/OUTPUT.md

@@ -52,6 +52,10 @@ speaker fields (always present; `null` when unknown):
   unknown/none -> `"?"`.
 - `speaker_score` — the winning cosine similarity, rounded to 4 dp (`null` when unknown).
 
+Note: `"?"` above is the stored JSONL `speaker` value. The assistant resolves the same turn
+to the literal `"Unknown"` before relaying it to viewers, so the TUI header shows `Unknown`
+(bold red) where the JSONL record holds `"?"`.
+
 Existing tooling that ignores unknown JSON keys keeps working unchanged.
 
 **Audio files** — when `save_audio = true`, each transcribed utterance is also

+ 2 - 1
docs/TRIAGE.md

@@ -156,12 +156,13 @@ the oldest deltas are dropped, so a long quiet stretch can't grow it without lim
 
 ## Lanes: nothing is parallelized
 
-The assistant has exactly three single-worker lanes, and you should not parallelize any of
+The assistant has exactly four single-worker lanes, and you should not parallelize any of
 them:
 
 | lane | what runs on it |
 |---|---|
 | transcription | one worker; faster-whisper is not thread-safe |
+| speaker embedding | one worker in-process in the daemon; owns the `SpeakerStore` |
 | LLM `InferenceQueue` | one worker; all chat, command, and `brief-update` calls |
 | Laya | one worker plus one loader thread; one `predict` at a time |
 

+ 3 - 2
docs/TROUBLESHOOTING.md

@@ -11,10 +11,11 @@ To create VirtualMicSink, run: scripts/audio-sink.sh start
 
 **Fix:**
 ```bash
-scripts/audio-sink.sh start
+uv run stt-daemon setup
 ```
 
-Then route audio into VirtualMicSink and try again.
+Then route audio into VirtualMicSink and try again. (`scripts/audio-sink.sh start` is a thin
+wrapper over the same subcommand.)
 
 ## "Can't select or copy text in the TUI"
 

+ 1 - 1
src/stt_daemon/assistant/brief_file.py

@@ -1,7 +1,7 @@
 """Best-effort atomic writer for the durable brief markdown snapshot.
 
 Enabled via `[brief].write = true` (off by default). When enabled, each brief
-update replaces `<session_dir>/brief.md` with the exact text supplied by the
+update replaces `<session_dir>/<id>/brief.md` with the exact text supplied by the
 assistant, using the same `tempfile.mkstemp` + `os.replace` atomic pattern as
 the rest of the codebase. `set_directory()` points the writer at the current
 conversation's session folder; until then it defaults to `brief/brief.md`.