feat: Auswertung der Sprachnotizen mit Claude (T7 L4 Tasks 14, 15)
Backend E2E / e2e (push) Failing after 7m2s
Backend Image / build-and-push (push) Successful in 8m20s
Manifests / validate (push) Successful in 33s
Frontend Image / build-and-push (push) Failing after 21m23s

Task 14: Port StructuredModel mit Anthropic-Adapter (@anthropic-ai/sdk
0.131.0 exakt, Lieferkette geprüft), fester Endpunkt
https://api.anthropic.com (Umgebungs-Header werden entfernt), feste
Systemregeln ohne Datum/Volk/Person, Transkript als Daten in Tags,
strukturierte Ausgabe per JSON-Schema mit effort low, serverseitiger
Fallback per VOICE_SERVER_FALLBACK abschaltbar. Jeder Vorschlag wird
geprüft: bekanntes Feld, Wert in den Formulargrenzen, Zitat steht
wörtlich im Gesagten (Dezimalzahl als ein Wort), Korrektur gewinnt.
Netzwächter: nur die Worker-Verdrahtung erreicht den Adapter
(transitiv geprüft).

Task 15: Worker-Schleife voice-extractions (LISTEN + 15-s-Abfrage, ein
Lauf zugleich, höchstens 20 Notizen je Lauf), Modellaufruf außerhalb
jeder Transaktion mit 240-s-Obergrenze, Ergebnis versiegelt mit
Ereignis nur bei gehaltenem Claim; ohne Schlüssel EXTRACT_DISABLED ohne
Versuch, Tageslimit zählt jeden bezahlten Aufruf über das neue Journal
VoiceExtractionCall (nur IDs, Modell, Tokens, Ergebnis; 90 Tage, nicht
im Backup). Nur der Worker-Container erhält ANTHROPIC_API_KEY aus dem
Secret apicore-anthropic (optional); API- und Job-Rollen warnen, wenn
der Schlüssel bei ihnen gesetzt ist.

Gates: Backend lint, typecheck, 4589 Unit-Tests, build; e2e 104 Suites
(nur der Wetter-Test gegen die echte API schwankt); Manifest-Policy 55.

Refs #27

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
Nick.RosenloecherandClaude Opus 5.5 committed 2026-10-16 15:38:15 +02:00
1 parent 89a1546f15
commit 6a915aad9c
38 files changed
+3612 -33

No files matched your search

+22
View File
@@ -11,6 +11,20 @@ export type VoiceModel = (typeof VOICE_MODELS)[number];
export const DEFAULT_VOICE_MODEL: VoiceModel = 'claude-sonnet-5-5';
/**
* Models with a server-side fallback when their safety check declines
* (`fallbacks: "default"`). Haiku has none: a declined request stays
* declined there.
*/
export const VOICE_SERVER_FALLBACK_MODELS: readonly string[] = [
'claude-sonnet-5-5',
'claude-opus-5-5',
];
/** VOICE_SERVER_FALLBACK: "default" uses the fallback above, "off" never. */
export const SERVER_FALLBACK_MODES = ['off', 'default'] as const;
export type ServerFallbackMode = (typeof SERVER_FALLBACK_MODES)[number];
export const WHISPER_MODELS = ['small', 'medium'] as const;
export type WhisperModel = (typeof WHISPER_MODELS)[number];
@@ -25,6 +39,8 @@ export interface VoiceConfig {
/** Switch that shows or hides audio recording in the app (ConfigMap). */
recordingEnabled: boolean;
whisperModel: WhisperModel;
/** Whether a declined request may be re-run server-side on another model. */
serverFallback: ServerFallbackMode;
}
function trimmed(value: string | undefined): string | null {
@@ -95,5 +111,11 @@ export function voiceConfig(env: NodeJS.ProcessEnv = process.env): VoiceConfig {
WHISPER_MODELS,
'small',
),
serverFallback: oneOf(
'VOICE_SERVER_FALLBACK',
env.VOICE_SERVER_FALLBACK,
SERVER_FALLBACK_MODES,
'default',
),
};
}