open-webui/backend/open_webui/socket
Claude 0a084cbe0c
fix(stream): bind chat_id into the stream key
Adopt the bot's suggested alternative to a DB-level message-in-chat
binding check: put chat_id directly into the Redis key structure
so message-to-chat binding is enforced by key construction.

Key changes:
  stream:{user_id}:{message_id}          ->  stream:{user_id}:{chat_id}:{message_id}
  streamseq:{user_id}:{message_id}       ->  streamseq:{user_id}:{chat_id}:{message_id}

A resume request carrying the wrong chat_id reads a non-existent key
and returns empty — same outcome as a DB binding check but with:
  - no extra DB round-trip
  - no regression on the "stub not yet persisted in DB" case that
    killed the earlier DB binding attempt three rounds ago
  - defense enforced at the data layer, not at a check that could be
    skipped or bypassed

All four helpers (_stream_key, _stream_seq_key, _stream_log_append,
_stream_log_read, _stream_seq_allocate) and both callers (emitter +
resume_stream handler) updated consistently.

Not addressed:
- Truncation fidelity with automatic reload: deferred. Adding a
  deterministic client fallback is invasive and the \`truncated\`
  console warning is sufficient until this shows up in telemetry.
- Prune resumeSeqByMessageId per-message: fifth round on this. The
  current design (no per-message prune) was chosen to avoid
  continuation-reuses-message_id replay duplication; memory is
  int-per-message bounded by chat size.
2026-04-15 09:06:34 +00:00
..
main.py fix(stream): bind chat_id into the stream key 2026-04-15 09:06:34 +00:00
utils.py refac 2026-03-22 05:48:05 -05:00