Skip to content

fix(chat-flow): serialize per-chat processing, end flow on dead-leaf nodes (v1.0.3)#4

Merged
rmyndharis merged 2 commits into
mainfrom
chat-flow-harden
Jun 23, 2026
Merged

fix(chat-flow): serialize per-chat processing, end flow on dead-leaf nodes (v1.0.3)#4
rmyndharis merged 2 commits into
mainfrom
chat-flow-harden

Conversation

@rmyndharis

Copy link
Copy Markdown
Owner

Summary

Two robustness fixes to chat-flow, released as v1.0.3.

Per-(session, chat) serialization

processMessage read flow state, navigated, then wrote it back with awaits in between. Two near-simultaneous messages for the same chat could both read the same state and race the write — a double greeting on first contact, a lost path advance, or a resurrected leaf. Processing is now chained per ${sessionId}__${chatId} through a promise lock (settled tail so a rejection can't wedge the chain; self-evicting when the chain drains). The bounded invalid-path re-process recurses on the locked body, not the public entry, to avoid waiting on its own pending chain entry.

Dead-leaf flow end

If a config edit left an in-flight user parked on a node that no longer has any options, every subsequent message hit the fallback branch, replied "Invalid option", and re-saved the state — an endless loop until the 15-minute expiry. When the resolved node has no options, the flow now ends cleanly (state cleared) so the next trigger starts fresh. The legitimate "typed an option that isn't in the menu" case (node still has options) is unchanged.

Tests

  • New: concurrent messages for the same chat send the greeting exactly once.
  • New: a stored path landing on a now-leaf node ends the flow instead of looping.
  • Full suite green, tsc --noEmit clean, bundle packages cleanly. The public processMessage signature drops the internal depth arg (it was always defaulted; no caller passed it).

…nodes (v1.0.3)

- processMessage now serializes per (session, chat) through a self-evicting promise
  chain, closing a read->write race where two near-simultaneous messages could lose or
  duplicate navigation (double greeting, resurrected leaf). The bounded invalid-path
  re-process recurses on the locked body to avoid self-deadlock.
- When a config edit parks an in-flight user on a node that no longer has options, the
  flow ends cleanly instead of looping "Invalid option" until the 15-minute expiry.
@rmyndharis rmyndharis merged commit 7a95ab4 into main Jun 23, 2026
1 check passed
@rmyndharis rmyndharis deleted the chat-flow-harden branch June 23, 2026 09:38
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.

1 participant