fix(anthropic): suppress stream-json log spam for system/* and user events

The NDJSON event parser matched only `system/init` and treated every
other system subtype as "unknown event type" — logged via console.error,
once per event. During the 2026-05-28 OAuth-expiry 401 cascade this
produced 2 spam lines per failed request (PI231 server log was
~50% noise).

Also caught: claude echoes {type:'user'} events back in some stream-json
modes (analogous to --replay-user-messages); these were also spammed
as unknown.

Both are now consumed silently — neither maps to an IR chunk.

Authority:
- empirical PI231 v2.1.104 transcripts 2026-05-28 (server log shows
  '[anthropic] unknown stream_json event type: system' and
  '[anthropic] unknown stream_json event type: user')
- ADR 0009 Amendment 1 § "NDJSON event handling" — generic "future-proof
  for unknown events" intent; the table was incomplete

Tests: 795 → 797
- 41e-5b: regression guard for system/<non-init-subtype>
- 41e-5c: user (echo) event consumption

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-28 16:56:52 +10:00
co-authored by Claude Opus 4.7
parent dbac5f5521
commit e5cfc696da
2 changed files with 33 additions and 2 deletions
+13 -2
View File
@@ -703,8 +703,19 @@ export function parseStreamJsonLines(buffered) {
export function anthropicStreamJsonEventToIR(event, isFirstDelta = false) {
const t = event?.type;
// system/init — first event always; consumed (no yield)
if (t === 'system' && event.subtype === 'init') {
// system/* — first-event init plus any other system meta (api_retry, etc.)
// emitted during error paths. None map to IR chunks; all consumed silently.
// Originally we matched only `subtype === 'init'`, which caused noisy
// "unknown stream_json event type: system" logs during 401 cascades when
// claude emits other system subtypes. (Observed PI231 2026-05-28.)
if (t === 'system') {
return null;
}
// user — claude echoes the user-message back as a confirmation event in
// some stream-json modes (analogous to --replay-user-messages). Always
// consumed; never an IR chunk.
if (t === 'user') {
return null;
}