Skip to content

Bugfix/chat send preflight delay - #141

Merged
douglasware merged 15 commits into
Elumenotion:mainfrom
JacksonFalgoust:bugfix/chat-send-preflight-delay
Aug 30, 2026
Merged

Bugfix/chat send preflight delay#141
douglasware merged 15 commits into
Elumenotion:mainfrom
JacksonFalgoust:bugfix/chat-send-preflight-delay

Conversation

@JacksonFalgoust

Copy link
Copy Markdown
Collaborator

Summary

Reduces the delay between a user sending a chat message and the request reaching the LLM (the "preflight" path in ConversationService.SendMessageStreamCoreAsync). The bottlenecks were query-shape/N+1/round-trip issues, not missing indexes — this branch fixes those directly:

  • Create turns already in "streaming" status, dropping a redundant DB round trip
  • Unify assistant-name resolution and load the conversation preflight query with .AsNoTracking() + .AsSplitQuery(), removing a cartesian-product join
  • Batch per-message attachment loading into one query instead of one per message — the main N+1, fixed in both places it occurred (history building and assistant-switch logic)
  • Yield turn_created before preflight history/attachment setup finishes, so the client isn't blocked on it, with proper failure handling if preflight fails after that early yield
  • Render the sent message optimistically on the client before the runtime-status preflight check resolves, with rollback on not-ready/error
  • Cache model reasoning-effort choices for 60s instead of reading them from the DB on every turn (29f1ae9d)
  • Cache chat-ready attachment renderings keyed by (fileId, lastModifiedTicks) instead of re-rendering the same attachment on every send
  • Fix a correctness regression the optimistic-render change opened up: clicking Stop during the preflight window had nowhere to go and was silently dropped

Also: removes a redundant conversation-snapshot GET after sending a message, and adds preflight timing instrumentation.

Measured impact

main (before) this branch (after)
1st message (cold) 1386ms 746ms
2nd message 691ms 28ms
3rd message 866ms 32ms

Reset SET_CANCELLING/SET_STREAMING_ERROR/pendingStopRef/activeStreamTurnId
before the optimistic dispatches (which flip isStreaming true and make the
Stop button clickable) instead of after the runtime preflight resolves.
Previously a Stop click during the preflight queued a pending stop that
clearPendingStop() then wiped out once the preflight finished, before
onTurnIdAssigned ever got to replay it against the real turn id.

Also reset SET_CANCELLING inside rollbackOptimisticSend so a
Stop-then-runtime-not-ready sequence can't leave _isCancelling true.

Closes the stale-active-stream-turn-id gap on the sendMessage success path
as a side effect: setActiveStreamTurnId(null) now runs before the optimistic
dispatches, not just on later error/teardown paths.
@douglasware
douglasware merged commit e4f1e94 into Elumenotion:main Aug 30, 2026
5 of 6 checks passed
@JacksonFalgoust
JacksonFalgoust deleted the bugfix/chat-send-preflight-delay branch September 2, 2026 20:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants