* 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>
* feat(jobs): add sort toggle for cron jobs by name or creation time
* feat(jobs): improve sort UI with separator, rename labels, toggle direction, default to name sort
* fix(jobs): use scalar props for sort to fix Vue reactivity on time toggle
* docs: add chat chain change fragment for jobs sort toggle (#1716)
* fix: remove unused onOutlineMessagesLoaded imported from outline-qa branch
* add jobs sort tooltip i18n
---------
Co-authored-by: WenhuaXia <wenhua_xia@163.com>
* fix(goal): increase goal evaluate timeout from 5s to 120s
5s timeout from #1580 is too aggressive for users with remote/slow LLM
services. Goal judge calls silently fail causing goal continuation to
never enqueue, leaving the goal stuck at 1 turn.
Align with auxiliary.goal_judge.timeout default (120s) in config.yaml.
* docs: note goal evaluate timeout change
---------
Co-authored-by: WenhuaXia <wenhua_xia@163.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(context-compressor): guard token counting against quadratic BPE hang on long CJK runs
js-tiktoken's BPE merge loop is O(n^2) over the bytes of a single
pre-tokenizer piece. The GPT pat_str groups contiguous \p{L} characters
into one piece, and CJK text has no spaces, so a long CJK run becomes a
single huge piece. A ~14k-char CJK message (~42k bytes) produced ~1.8B
operations, pinning the Node event loop at 100% CPU. encode() never
throws in this case — it just hangs — so the existing catch-based
heuristic fallback never fired, and the whole server became unresponsive
(local HTTP requests timed out, nginx returned 504).
Detect a pathological contiguous letter/CJK run (>2000 chars) up front in
countTokens and countTokensForModel and use the cheap CJK-aware heuristic
instead. Normal text, even very long but space-separated, still takes the
exact tiktoken path.
Adds regression tests covering the CJK hang, normal text, and long
space-separated text.
* docs: add chat-chain-changes fragment for CJK token-counting guard
---------
Co-authored-by: paulocavallari <paulocavallari@users.noreply.github.com>