feat(simulation): voice pipeline integration — Factual bypass, observer wiring, tell iteration (#650 #652 #651)

ContentType::Factual bypasses LLM for fact-bearing lines (numbers,
denials). Observer enrichment systems rewrite dialogue/conversation
text with voiced versions before snapshot assembly. Friendly and
RoutineDeviation tells get concrete surface-pattern examples.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-13 09:11:44 +01:00
co-authored by Claude Opus 4.6
parent ce0df2f320
commit 1a4fd578cc
8 changed files with 316 additions and 12 deletions
+8 -1
View File
@@ -16,7 +16,7 @@ use crossbeam_channel::Receiver;
use crate::npc::blueprint::CultureProfile;
use crate::voice::cache::{CacheKey, VoiceCacheStore};
use crate::voice::prompt_builder;
use crate::voice::prompt_builder::{self, ContentType};
use crate::voice::queue::VoiceRequest;
/// Minimum token count for a valid response. Below this, retry once.
@@ -326,6 +326,13 @@ fn process_request(
request: &VoiceRequest,
ctx: &WorkerContext,
) {
// Factual lines bypass the LLM entirely — serve base text directly.
// 2B models corrupt numbers and invert denials (Spike 2 finding, D-138).
if request.content_type == ContentType::Factual {
cache_base_text(request, ctx);
return;
}
let culture = match ctx.cultures.get(&request.culture_id) {
Some(c) => c,
None => {