Restore changes reverted by accidental PR #566 merge (#564, #565, #568)#608
Merged
Restore changes reverted by accidental PR #566 merge (#564, #565, #568)#608
Conversation
PR #566 squash-merged a stale branch that had resolved merge conflicts by keeping older file versions, reverting 3 previously-merged PRs from main: - PR #564: TOCTOU upload locking security fix - PR #565: Tool execution guardrails with confirmation popup - PR #568: Agent UI overhaul (CSS design system, animations, UX polish) Follow-up PRs #593/#604/#605 partially restored functionality. This PR restores all remaining missing changes while preserving those follow-ups. Changes: - 24 files: clean restore from pre-revert commit (CSS, components, utils) - Security: restore per-file asyncio.Lock upload guard (dependencies.py, documents.py, server.py) - SSE handler: restore <think> block state machine, UUID-scoped confirms, timeout parameter, friendly error messages - Frontend: restore AnimatedPresence, session hash badge, smooth streaming exit, custom model override UI, terminal typing animation, inference stats - Backend: restore custom_model DB override, Lemonade stats fetching, friendlier user-facing error messages - Tests: 497 passing, TypeScript build clean (1845 modules) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
144cf4d to
f36f329
Compare
- Fix DANGEROUS_SHELL_OPERATORS regex to catch trailing > and < edge cases - Add _BLOCKED_PS_FLAGS set blocking -EncodedCommand, -File, -ExecutionPolicy, etc. - Add rehype-sanitize alongside rehypeRaw in MessageBubble to prevent XSS - Unify permission_request handler in ChatView with ALWAYS_ALLOW check and confirm_id - Fix unbound session_id in _chat_helpers except block (moved before try) - Add tests/unit/test_shell_guardrails.py with 39 unit tests for shell guardrails Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ragment filter - PermissionPrompt: add 'Always allow this tool' checkbox with remember state so users can suppress future prompts for trusted tools - sse_handler: apply _TOOL_CALL_JSON_SUB_RE and _THOUGHT_JSON_SUB_RE in print_final_answer to strip embedded JSON artifacts from final responses - sse_handler: fix _TOOL_CALL_JSON_SUB_RE to handle 2 levels of nested braces in tool_args (was leaving }}} fragments when args had nested dicts) - sse_handler: skip flushing end-of-stream buffer content that is only whitespace and closing braces (JSON fragment artifacts) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s format
The model outputs {"thought": "...", "goal": "...", "tool": "...", "tool_args": {...}}
but _TOOL_CALL_JSON_RE only matched JSON starting directly with "tool", causing
the full JSON to be emitted as visible text with a trailing } artifact.
- Extend _TOOL_CALL_JSON_RE with leading .* to match optional thought/goal/plan
fields before "tool" (common Qwen3 output format)
- Add _json_filtered flag: set True when any JSON block is suppressed, so
subsequent bare } tokens (structural remnants) are also suppressed
- Strip thought/tool-call JSON from "before" text in think-block state machine
to prevent pre-<think> JSON from appearing as response content
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
kovtcharov
approved these changes
Mar 23, 2026
The } streaming artifact is a pre-existing issue (present on main). Two prior commits attempted to fix it by extending _TOOL_CALL_JSON_RE with a greedy .* prefix and adding a _json_filtered state flag, but these changes broke answer display (empty responses, suppressed content). Reverting sse_handler.py to the working state from commit 9190980. The } artifact will be addressed in a separate PR. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… size - sse_handler: use time.monotonic() instead of time.time() for confirm timeout deadline (immune to NTP/DST clock jumps) - shell_tools: remove git config from SAFE_GIT_COMMANDS (allows writes to .gitconfig without --get flag) - documents: increase _copy_fd_to_temp block size from 8KB to 64KB (reduces syscall overhead for large uploads) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR #566 was accidentally merged with stale conflict resolutions that reverted 3 previously-merged PRs. Follow-up PRs #593/#604/#605 partially restored functionality. This PR restores all remaining missing changes.
Root cause: During a
git merge origin/maininto the branch (commitf07b932), conflict resolution kept the branch's older file versions, discarding work from 3 PRs. The squash merge then propagated this to main.Reverted PRs restored by this PR:
asyncio.Lockfor document uploads (dependencies.py,routers/documents.py,server.py)<think>block state machine, UUID-scoped confirms, inference stats, custom model override, friendly error messages (sse_handler.py,_chat_helpers.py,models.py)appendThinkingContent,format.tsutilities (App.tsx,ChatView.tsx,AgentActivity.tsx,SettingsModal.tsx/css,WelcomeScreen.tsx/css,Sidebar.tsx/css,MessageBubble.tsx/css,chatStore.ts, 12 other CSS files,shell_tools.py,database.py)Preserved follow-up PR additions:
permission_requestevents,confirmToolAPI,fileListpass-through, PermissionPromptTest plan
python -m pytest tests/unit/chat/ui/ --tb=short— 497 passedpython util/lint.py --black --isort— all checks passnpm run buildinsrc/gaia/apps/webui/— 1,845 modules, no TypeScript errorsgaia chat --ui— verify UI loads, settings modal shows custom model override, welcome screen has typing animation, chat streams correctly🤖 Generated with Claude Code