release: v0.50.246 — 5-PR batch#1343
Conversation
…ns in Session model (#1318 split) From PR #1341. Co-authored-by: fxd-jason <[email protected]>
…single fallback_model dict From PR #1339. Co-authored-by: Jim Dawdy <[email protected]>
… asset URLs on every release From PR #1337. Co-authored-by: Dennis Soong <[email protected]>
From PR #1335. Co-authored-by: bergeouss <[email protected]>
…-panel expand state (#1298) From PR #1338. Already independently APPROVED by nesquena before being absorbed into v0.50.246. CHANGELOG entries from this PR were dropped during squash (the v0.50.245 section is already shipped); they will be re-added under [v0.50.246] in the release commit. Co-authored-by: nesquena-hermes <[email protected]>
…back list - tests/test_issue765_streaming_persistence.py — replace timing-based polling in test_checkpoint_fires_on_activity_counter_increment with deterministic threading.Event-driven sync. The old version used time.sleep(0.15)+(0.25)+(0.25) with a 0.1s polling thread, which under CI scheduling jitter could miss the second increment and complete with only 1 save instead of 2. Now waits up to 3.0s for save_count to advance to the target after each increment. Locally observed flake on Python 3.11 in CI run 25175204451. - tests/test_pr1339_fallback_providers_list.py — new structural test that asserts streaming.py handles both legacy fallback_model (single dict) and new fallback_providers (list form) without calling .get() on a list. Three assertions: both keys consulted, list-form has explicit isinstance check, _fallback_resolved defaults to None.
Combines: - 4 contributor PRs (#1335 user fenced code, #1337 mermaid+cache-bust, #1339 fallback_providers list, #1341 context_length persistence) - Self-built #1338 (cancel data-loss + activity panel) — already independently APPROVED by nesquena before absorption - CONTRIBUTORS.md and markdown refresh from #1340 See CHANGELOG.md for the full list with author credit.
…us review) Pre-release Opus review on v0.50.246 caught a SHOULD-FIX in PR #1338's cancel_stream synthesis: the symmetric substring guard (_pending_user in _last_content OR _last_content in _pending_user) was too loose. Common confirmation replies ("ok", "yes", "go") in the prior turn would match longer follow-up prompts ("ok please continue"), the synthesis would be skipped, and the user's typed text would be lost — exactly the data-loss bug #1298 was supposed to fix. The fix: gate the substring check on a timestamp comparison. Only treat the latest user turn as 'already merged by the streaming thread' if its timestamp is at or after pending_started_at. Earlier turns whose content happens to be a substring of the pending must not short-circuit synthesis. Also drops the symmetric (_last_content in _pending_user) branch — that direction was the false-positive vector. Keeps the equality and prefix match (workspace-prefix tolerance from the streaming thread). Adds tests/test_issue1298_cancel_and_activity.py:: test_cancel_synthesizes_when_prior_turn_content_is_substring_of_pending — regression for the exact 'ok' → 'ok please continue' scenario.
Opus pre-release review — applied in commit
|
| # | Description | Action |
|---|---|---|
| 1 | Duplicate inline from urllib.parse import quote in routes.py |
Hoist to module top in a follow-up |
| 2 | _renderUserFencedBlocks placeholder collision (\x00UF<n>\x00 not escaped by esc()) |
Low-likelihood cosmetic glitch — strip NUL upfront in a follow-up |
| 3 | Lang regex differs slightly between _renderUserFencedBlocks and renderMd |
Cosmetic, no functional impact |
| 4 | fallback_model precedence over fallback_providers is silent |
Add a one-time log warning if both keys present |
| 5 | typeof === 'function' guards on locally-declared functions are dead code |
Drop in a follow-up |
| 6 | _renderUserFencedBlocks XSS surface — verified clean (allowlist regex, esc() everywhere, no HTML injection vector) |
No action |
| 7 | quote(WEBUI_VERSION, safe="") correctness — verified handles all git describe outputs (tags, commits, --dirty, unknown) |
No action |
| 8 | finalizeThinkingCard only respects user-expand, not user-collapse — verified the singleton is cleared between turns |
No action |
Final verification
- ✅ pytest after fix: 3344 passed, 0 failed in 74s (+1 from the regression test)
- ✅
f328f3bpushed torelease/v0.50.246
Ready for review.
Release v0.50.246 — 5-PR batch
Constituent PRs
fallback_providersconfigHeld with feedback (not in this release)
/branchslash command. Real CI failures (60s timeout in own test, Korean locale parity broken) + scope concerns. Held with a 2-path "fix tests + scope discussion or split" comment.Pre-release gate
3343 passed, 2 skipped, 3 xpassed, 0 failed in 83s(up from 3309 baseline, +34 new tests across the batch)test_checkpoint_fires_on_activity_counter_incrementwas failing intermittently on Python 3.11 in CI (timing-based polling). Replacedtime.sleepwindows withthreading.Eventsynchronization. Verified locally over multiple runs.static/ui.js,static/index.html,static/sw.js)CHANGELOG conflict resolution
PR #1338's CHANGELOG entry was originally added under
[v0.50.245]. That section already shipped, so the squash conflict was resolved by keeping HEAD (the shipped v0.50.245 entries unchanged) and re-adding the #1338 entries fresh under the new[v0.50.246]section. No content lost — just relocated.Diff stats
Closes #1298, #1318 (via partial fix), #1325.