Merge remote-tracking branch 'origin/master' into paperclip/pr-6222

This commit is contained in:
Frank Song committed 2026-07-19 02:32:45 +08:00
commit cf66ad659d
2 files changed
+19 -1

No files matched your search

+2
View File
@@ -11,6 +11,8 @@
### Fixed
- **Reopening a WebUI tab after a large active session is fast again, even when the session has few messages but large tool outputs.** The reconnect display-path tail optimization only fired based on message *count*, so a session with a handful of messages but multi-MB tool-call JSON forced a slow full-scan merge (bootstrap could take tens of seconds). The optimization now also fires when the session sidecar file exceeds 500 KB, regardless of message count — the same messages are returned (verified: identical message set, count, offset, and truncation metadata), just via the fast path. Thanks @webtecnica. (#6260)
- **OIDC allowlist values containing spaces (e.g. a group named `Hermes Users`) are no longer split into separate entries.** The allowlist parser split comma-separated values on all whitespace, so a multi-word group/user name became two spurious entries. Allowlist parsing now splits only on commas/newlines (multi-word values stay intact and match their exact signed claim — strictly tightening, no security loosening), while OAuth **scope** parsing keeps its space-delimited behavior per RFC 6749 §3.3. A blank allowlist entry no longer bricks an OIDC-only deployment. Thanks @webtecnica. (#6244)
- **`/sessions` and `/resume` typed in the composer now open the session browser instead of being sent as chat text.** Both commands appeared in the slash-command autocomplete (they're exposed by `/api/commands`) but the WebUI send-time dispatch didn't handle them, so they were posted to the agent as plain text. They now open the native WebUI session browser and clear the composer — on desktop and (via the mobile-aware opener) on phone-width layouts. Thanks @webtecnica. (#6245, #6224)
+17 -1
View File
@@ -8522,6 +8522,10 @@ def _parse_msg_limit(raw):
return max(1, min(value, _MAX_MSG_LIMIT))
# If a sidecar JSON file exceeds this threshold, the display-path tail
# optimization fires regardless of message count. Sessions with few messages
# but large tool outputs (multi-MB JSON) should not force a full-scan merge.
_SIDECAR_BYTE_TAIL_THRESHOLD = 500_000 # 500 KB
# Defensive row backstop for the GET /api/session display path's state.db read.
# This is NOT a semantic window (the display window counts visible rows
# post-reconciliation via _message_window_for_display); it is a safety net so a
@@ -8641,6 +8645,16 @@ def _limited_webui_messages_for_display_with_sidecar(session, sidecar_messages,
)
def _sidecar_file_exceeds_threshold(session_id, threshold_bytes) -> bool:
"""Check if the sidecar JSON file for ``session_id`` exceeds ``threshold_bytes``."""
from api.config import SESSION_DIR
try:
p = SESSION_DIR / f"{session_id}.json"
return os.path.isfile(p) and os.path.getsize(p) > threshold_bytes
except Exception:
return False
def _state_db_since_timestamp_for_limited_display(session, msg_limit, msg_before=None):
"""Return (timestamp floor, sidecar messages) for bounded state.db tail reads.
@@ -8671,7 +8685,9 @@ def _state_db_since_timestamp_for_limited_display(session, msg_limit, msg_before
return None, sidecar_messages
raw_budget = max(300, limit * 10)
if len(sidecar_messages) <= raw_budget:
return None, sidecar_messages
_sid = getattr(session, "session_id", "") or ""
if not _sid or not _sidecar_file_exceeds_threshold(_sid, _SIDECAR_BYTE_TAIL_THRESHOLD):
return None, sidecar_messages
floor = min(sidecar_timestamps[-raw_budget:])
sidecar_before_count = sum(1 for ts in sidecar_timestamps if ts < floor)