Add observable-behavior baseline coverage for Group Chat sockets, REST routes, mention routing, chat-run, coding-agent dispatch, and client store state.
Keep the PR source diff focused on code/tests only; architecture context belongs in the PR body.
* fix: preserve archive state in history sessions
* docs: record PR number for archive state fragment
* test: cover api server archive history merge
* fix archive only chat session
---------
Co-authored-by: ekko <fqsy1416@gmail.com>
When a run.failed event fires while the assistant message is still
streaming, addAgentErrorMessage previously unconditionally overwrote
the message with an error — losing the assistant reply even if it had
already produced meaningful output. This commonly happened during
Socket.IO disconnects in long tool-use runs.
The fix checks whether the streaming message has substantial content
(>100 chars). If so, it only closes the stream and appends a separate
error message instead of overwriting. For empty/trivial messages,
the original overwrite behavior is preserved since the run failed
before producing useful output.
Fixes#1644
Co-authored-by: Andy365-365 <andy365-365@users.noreply.github.com>
* feat(chat): add message fork action
Use a Y-shaped repo-forked icon in fork UI and expose the current-tail /fork action in the last message meta action row instead of the input toolbar. Keep terminal fork commands out of optimistic run/thinking state so no model activity is implied.
* fix(chat): debounce fork message action
* fix chat session click after fork
---------
Co-authored-by: Zhicheng Han <zhicheng.han@mathematik.uni-goettingen.de>
* feat: add local chat fork command
* docs: add chat chain fragment for fork command
* feat(chat): persist fork point metadata
Record the copied child message that marks the fork boundary and surface it through resume/session client state.
* feat(chat): show fork timeline divider
Render fork lineage inline after the copied fork point and link back to the original session with in-app switching.
* fix(chat): use branch title and trim fork divider
Default fork titles now use branch: <original title>; the fork divider uses a branch icon and relies on the parent title link instead of a duplicate view-original button.
* fix(chat): preserve fork divider hydration metadata
* test(chat): accept fork command alias in registry contract
---------
Co-authored-by: ekko <152005280+EKKOLearnAI@users.noreply.github.com>
* fix(group-chat): stable message ordering via firstSeenAt
Multi-agent replies jumped positions because sortedMessages used
the mutable timestamp field, which gets overwritten when the server
persists the final message. Fix: add read-once firstSeenAt field
captured at stream_start and use it (with ?? fallback) as sort key.
Closes#1546
* fix group chat ordering PR validation
---------
Co-authored-by: kimbluerain <kimbluerain@gmail.com>
Co-authored-by: ekko <fqsy1416@gmail.com>