Commit graph

5115 commits

Author SHA1 Message Date
nesquena-hermes
d13da425e9
Release WN (v0.51.633): collapsed tool cards preview result not call args (#4851, closes #4752)
Release WN (v0.51.633): collapsed tool cards preview result not call args (#4851, closes #4752)
2026-06-24 13:49:19 -07:00
nesquena-hermes
2de2599e8c Release WN (v0.51.633): collapsed tool cards preview result not call args (#4851, closes #4752) 2026-06-24 20:45:30 +00:00
Rod Boev
2ca65abefa fix: use JSON.parse for bracket-prefixed lines instead of blanket suppression 2026-06-24 20:35:04 +00:00
Rod Boev
4bf659e433 fix: harden test drivers against extractFunc brace-counter overrun 2026-06-24 20:35:04 +00:00
Rod Boev
32d171c1a1 fix: add _toolResultOneLiner to sibling test extractors and pin error-snippet behavior 2026-06-24 20:35:04 +00:00
Rod Boev
29604e5e7b fix: fall back to tc.snippet for cold-loaded tool results 2026-06-24 20:35:04 +00:00
Rod Boev
c19aaae27f fix(#4752): show tool result instead of call args in collapsed card preview 2026-06-24 20:35:04 +00:00
nesquena-hermes
159d362750
Release WM (v0.51.632): new conversations use configured default model (#4867, closes #4728)
Release WM (v0.51.632): new conversations use configured default model (#4867, closes #4728)
2026-06-24 13:32:08 -07:00
nesquena-hermes
7cd6cd7235 Release WM (v0.51.632): new conversations use configured default model (#4867, closes #4728) 2026-06-24 20:27:57 +00:00
nesquena-hermes
57a78e9284 fix(#4728): clear stale custom:* base_url + default wins without loaded session (gate findings)
Two gate-found CORE/SILENT edges fixed on-branch:
- api/config.py: switching the main default to a different custom:* provider kept
  the OLD provider's base_url, routing New Chat to the wrong endpoint. The
  base_url-clear on provider-change now covers custom:* too (was exempted).
- static/sessions.js: newSession() skipped the configured default when S.session
  was null but the picker held stale state (e.g. after deleting the last session),
  inheriting the stale model. Default now wins over legacy picker regardless of
  loaded-session state (explicit empty-composer override still takes priority).
- Updated 2 stale source-grep precedence assertions + widened a brittle 6000-char
  newSession() slice window to 7000 (assignment block grew; intent unchanged).
- 2 new non-vacuous regression tests (custom base_url clear; precedence).

Co-authored-by: Rod Boev <rod.boev@gmail.com>
2026-06-24 20:17:29 +00:00
Rod Boev
897322eac3 fix(#4728): keep main default-model routes from persisting auto provider 2026-06-24 20:09:30 +00:00
Rod Boev
23b3206f83 fix(#4728): guard settings default-model capture when no option is selected 2026-06-24 20:09:30 +00:00
Rod Boev
c388d15f2b fix(#4728): clear stale base URLs when default provider changes 2026-06-24 20:09:30 +00:00
Rod Boev
bede035a5e fix(#4728): persist provider-only default-model changes end to end 2026-06-24 20:09:30 +00:00
Rod Boev
69d202b94a fix(#4728): treat provider-only default changes as settings edits 2026-06-24 20:09:30 +00:00
Rod Boev
eba089fd90 fix(#4728): preserve fallback-order guarantees for default-model routing 2026-06-24 20:09:30 +00:00
Rod Boev
cdb44fb7e0 fix(#4728): sync saved default model provider into new chat state 2026-06-24 20:09:30 +00:00
Rod Boev
dde3845171 fix(#4728): keep default-model requests on the configured provider 2026-06-24 20:09:30 +00:00
Rod Boev
d8b58da018 fix(#4728): use configured default for new conversations 2026-06-24 20:09:30 +00:00
nesquena-hermes
b553c2d084
Release WL (v0.51.631): reconnect chronology keeps prior content ordered (#4849, closes #4811)
Release WL (v0.51.631): reconnect chronology keeps prior content ordered (#4849, closes #4811)
2026-06-24 13:02:17 -07:00
nesquena-hermes
27e259660c Release WL (v0.51.631): reconnect chronology keeps prior content ordered (#4849, closes #4811) 2026-06-24 19:58:18 +00:00
nesquena-hermes
3c8cfdc589 fix(#4811): regenerate row_id/seq from final order index so anonymous tool rows don't collide (gate finding)
Codex gate found a SILENT drop: reconnect scene rows are built with orderIndex=0,
so two tools WITHOUT a tool id at the same message index both got row_id
'...:tool:<idx>:0'; _completeSettledAnchorSceneForTurn dedupes by row_id, silently
dropping the second. Now the emit loop rewrites order_index AND regenerates the
index-derived row_id + seq + identity.seq from the final per-bucket position
(tid-based tool row_ids, already unique, are left untouched). Regression test
added + proven non-vacuous.

Co-authored-by: Rod Boev <rod.boev@gmail.com>
2026-06-24 19:48:56 +00:00
Rod Boev
f330fa7f44 perf(reconnect): pre-index toolCalls and remove unreachable guard (#4811) 2026-06-24 19:39:40 +00:00
Rod Boev
e86ebb6379 fix: remove unused textwrap import 2026-06-24 19:39:40 +00:00
Rod Boev
173014ae0e fix: update stale string-snapshot assertions for refactored anchor loop 2026-06-24 19:39:40 +00:00
Rod Boev
057b878136 fix(#4811): sort reconnect scene rows by phase and started_at chronology 2026-06-24 19:39:40 +00:00
nesquena-hermes
9a8b353239
Release WK (v0.51.630): surface real git fetch errors on update failure (#4862, closes #4694)
Release WK (v0.51.630): surface real git fetch errors on update failure (#4862, closes #4694)
2026-06-24 12:34:57 -07:00
nesquena-hermes
4c1c7d8938 Release WK (v0.51.630): surface real git fetch errors on update failure (#4862, closes #4694) 2026-06-24 19:30:49 +00:00
nesquena-hermes
8d2689ccc0 harden(#4694): broaden query-secret redaction before surfacing fetch diagnostics (gate finding)
Codex gate: the apply path now surfaces sanitized non-network fetch stderr, but
_QUERY_SECRET_RE only redacted access_token/token/password/auth/key — leaving
client_secret, private_token, oauth_token, api_key in a remote URL exposed in
the user-facing error. Broadened the pattern to cover those + app_secret/secret
+ api[_-]?key. Regression test added + proven non-vacuous.

Co-authored-by: Rod Boev <rod.boev@gmail.com>
2026-06-24 19:29:06 +00:00
Rod Boev
e88e4ecefc fix(#4694): treat fetch timeout diagnostics as network failures 2026-06-24 19:29:06 +00:00
Rod Boev
a3eac6a538 fix(#4694): surface non-network git fetch failures in updates 2026-06-24 19:29:06 +00:00
nesquena-hermes
25dc1dcd2a
Release WJ (v0.51.629): macOS workspace drag-drop now lands (#4845, closes #4757)
Release WJ (v0.51.629): macOS workspace drag-drop now lands (#4845, closes #4757)
2026-06-24 12:27:36 -07:00
nesquena-hermes
d313a899fc Release WJ (v0.51.629): macOS workspace drag-drop now lands (#4845, closes #4757) 2026-06-24 19:23:32 +00:00
nesquena-hermes
c21d30e02b fix(#4757): defer window-drop cleanup a tick so target ondrop runs first (gate finding)
Codex re-gate: the capture-phase window 'drop' listener fired BEFORE the target
el.ondrop, clearing _wsActiveDragPath before _isWorkspaceTreeMoveDrag/_wsDragSrcPath
ran — re-breaking the macOS stripped-MIME move it set out to fix. setTimeout(_clearWsDragData,0)
lets the real drop handler complete, then clears the lingering flag.

Co-authored-by: Rod Boev <rod.boev@gmail.com>
2026-06-24 19:13:59 +00:00
nesquena-hermes
63e3f91654 harden(#4757): gate stripped-MIME drop on text/plain===tracked path + robust drag-flag cleanup (gate finding)
Codex gate found a SILENT hazard: if a workspace drag is abandoned without
ondragend firing (cancel/drop-outside/blur), _wsActiveDragPath lingered and a
later FOREIGN text/plain drag could be misread as a workspace move. Hardening:
- _wsDragSrcPath now only trusts the active flag when the drop's own text/plain
  EQUALS _wsActiveDragPath (a foreign/empty text drag resolves to '' -> no move).
- Shared _clearWsDragData() called from ondragend, a drop finally, and
  window-level dragend/drop/pagehide/blur fallbacks (lost-dragend cleanup).
- 2 regression tests (stale-flag foreign-text -> empty; _clearWsDragData resets),
  proven non-vacuous.

Co-authored-by: Rod Boev <rod.boev@gmail.com>
2026-06-24 19:06:30 +00:00
Rod Boev
30c9f5e52a fix(test): use regex for let-declaration extraction resilience (#4757) 2026-06-24 18:58:33 +00:00
Rod Boev
2ef8a5f827 fix: add node portability guard to drag-drop test 2026-06-24 18:58:33 +00:00
Rod Boev
36fee0c6a4 fix(#4757): add active-drag flags so macOS workspace drag-drop lands 2026-06-24 18:58:33 +00:00
nesquena-hermes
f61de2a178
Release WI (v0.51.628): no ghost messages after edit/retry/undo (#4772, closes #4767)
Release WI (v0.51.628): no ghost messages after edit/retry/undo (#4772, closes #4767)
2026-06-24 11:53:00 -07:00
nesquena-hermes
4816f0a38e Release WI (v0.51.628): no ghost messages after edit/retry/undo (#4772, closes #4767) 2026-06-24 18:48:39 +00:00
nesquena-hermes
6a7fe93e10 fix(#4767): gate boundary-advanced bypass on checkpoint consumption (no stale-suffix resurrection)
Codex final-gate found the boundary<watermark advanced signal made
sidecar_advanced_past_watermark globally true, so a stale ts>watermark suffix
row appearing in state.db BEFORE the edited checkpoint bypassed the skip and
resurrected. Gate the bypass on state_replay_idx >= len(sidecar_visible_sequence)
(checkpoint consumed); apply the same gate to the same-second CORE-B exception.
Regression test added + proven non-vacuous. All legit cases (state-only reply
after checkpoint, CORE-B same-second) still pass.

Co-authored-by: AlexeyDsov <alexeydsov@gmail.com>
2026-06-24 18:39:02 +00:00
nesquena-hermes
695d9ab814 fix(#4767): keep state-only post-edit reply when sidecar tail equals advanced watermark (Codex final gate)
Final-gate Codex repro found a non-empty-sidecar drop: when the post-edit USER
turn is checkpointed into the sidecar (ts == advanced watermark) but its
ASSISTANT reply exists only in state.db (ts > watermark), the
sidecar_advanced_past_watermark guard was False (max_sidecar_timestamp ==
watermark, not >), so the 'timestamp > watermark' skip dropped the legitimate
reply. GET /api/session returned ['first','first reply','edited prompt'] and
omitted the assistant.

Fix: treat truncation_boundary < watermark (genuinely advanced) as advanced too,
so post-watermark state-only rows merge through even when the sidecar tail only
EQUALS the watermark. Conservative skip preserved for boundary None / == watermark.
Hoisted the loop-invariant boundary check out of the per-message loop. Regression
test added + proven non-vacuous.

Co-authored-by: AlexeyDsov <alexeydsov@gmail.com>
2026-06-24 18:21:34 +00:00
nesquena-hermes
7317e29d82 fix(#4767): guard empty-sidecar reconstruction against not-advanced watermark (Opus gate)
Opus deep-gate found a latent data-loss the Codex harnesses missed: the
empty-sidecar branch kept at_or_after (ts>=watermark) UNCONDITIONALLY, which is
only valid once the watermark was ADVANCED strictly past the original cutoff
(a new turn committed -> boundary < watermark). In the not-advanced states the
content above the watermark is the deleted suffix, so it got resurrected — the
same data-loss class this fix exists to kill. Reachable via crash/cold-load
metadata-vs-sidecar divergence.

- Keep at_or_after ONLY when boundary < watermark (genuinely advanced).
- boundary == watermark (just truncated) OR boundary is None (legacy: a positive
  watermark always meant 'frozen at cutoff' pre-#4767) -> conservative ts<=watermark
  filter; never resurrects.
- Replaced the backward-scan heuristic with the provable boundary guard.
- Removed the now-dead 'or (not sidecar_messages and watermark>0)' clause in the
  non-empty-sidecar path (unreachable; empty sidecar returns earlier).
- Added 2 regression tests (boundary==watermark, legacy None-boundary), both proven
  non-vacuous; updated 2 contributor tests that assumed advanced-watermark-without-boundary
  (an unreachable state) to pass the boundary the real persistence path always writes.

Co-authored-by: AlexeyDsov <alexeydsov@gmail.com>
2026-06-24 18:08:50 +00:00
nesquena-hermes
6ce9533d53 test(#4767): route-level CORE-A regression — /api/session full reload honors truncation_boundary
Co-authored-by: AlexeyDsov <alexeydsov@gmail.com>
2026-06-24 18:08:50 +00:00
nesquena-hermes
aac220b625 fix(#4767): thread truncation_boundary through remaining full-load merge call sites (CORE-A)
The contributor's empty-sidecar recovery uses the persisted truncation_boundary
to distinguish a legitimate prefix from a deleted suffix, but two production
call sites still passed only truncation_watermark — the default /api/session
full reload (routes.py ~9504) and _merged_session_messages_for_display
(routes.py ~6098) — so a normal full reload fell back to the old 'drop one
turn pair' heuristic and resurrected deleted suffix turns when an OLDER message
was edited leaving >=2 later turns. Thread truncation_boundary through both.

Co-authored-by: AlexeyDsov <alexeydsov@gmail.com>
2026-06-24 18:08:50 +00:00
AlexeyDsov
037253e4fc fix(#4767): review fixes - more edge cases 2026-06-24 18:08:50 +00:00
AlexeyDsov
195d53ea90 fix(#4767): review fixes - edge cases 2026-06-24 18:08:50 +00:00
AlexeyDsov
0a1c94e5c8 fix(#4767): review fixes 2026-06-24 18:08:50 +00:00
Alexey Denisov
d76abfb734 Update api/streaming.py
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-06-24 18:08:50 +00:00
AlexeyDsov
e1bbf3e807 fix(#4767): advance truncation_watermark instead of clearing to None after edit/retry/undo (#2914, #3831) 2026-06-24 18:08:50 +00:00