refactor: browser chat frontend#1
Open
sskmlm wants to merge 78 commits into
Open
Conversation
Add the Green Screen palette, improve Purple Puppy contrast, paginate the theme picker, and make prompts plus Termflow markdown and syntax highlighting follow the active theme. Also align shutdown callbacks with their awaited async contract.
…rashing (mpfaffenberger#546) A gateway 502 from custom_anthropic (e.g. puppy-backend) surfaces as an anthropic.APIStatusError(502) raised mid-stream. pydantic-ai runs the model stream inside an anyio task group, so it reaches run_agent_task wrapped in an ExceptionGroup (hence the except* handler). should_retry_streaming only walked __cause__/__context__ and never descended into ExceptionGroup.exceptions, so the retryable 5xx looked opaque -> no retry -> 60-line REPL traceback. - should_retry_streaming now traverses ExceptionGroup members too (cycle-safe, per-chain depth cap preserved via a separate traversal axis). - OpenAI branch of _is_retryable_one now retries on status_code 429/>=500, mirroring the Anthropic and ModelHTTPError branches (HTML-body 5xx match no snippet, so status_code is the only reliable signal). - Add 'bad gateway'/'gateway timeout' snippets as belt-and-braces. - Tests: ExceptionGroup (nested, cause-chain member, cycle-safe, non-transient) and OpenAI status-code retry/no-retry coverage. Co-authored-by: Julien Ellie <julien.ellie@walmart.com>
…affenberger#545) Extend the existing run_shell_command callback contract so a plugin can transparently transform a command before execution, in addition to the existing allow / block semantics. A callback may now return {"rewrite": "<new command>"} (optionally with a "rewrite_reason" string for the UI) alongside the existing {"blocked": True} response. Rewrites are applied in callback registration order and always emit a visible info line so users can see what actually ran -- rewriting must never be sneaky. Why: * Unlocks a class of plugins that cannot exist today: secret redaction in commands, corporate proxy / mirror injection, path fixup, attribution trailers on git commits, etc. * Fully backward compatible: callbacks that return None or {"blocked": True} keep working unchanged. The new behaviour only fires when a callback explicitly returns a "rewrite" key with a non-empty string value. Change is intentionally scoped down to just the infrastructure. Any policy-carrying plugin (attribution trailers, redaction rules, ...) belongs outside core -- either in a user plugin, a project plugin, or an external marketplace, depending on how opinionated it is. Tests: * tests/tools/test_command_runner_full_coverage.py -- three new cases covering the happy path (rewrite is applied and executed), a no-op rewrite where the string is unchanged (no notice emitted), and defensive handling of empty / non-string rewrite payloads. * All 259 pre-existing tests across command_runner, shell_safety, destructive_command_detector, shell_passthrough, and shell_line_crlf still pass -- backward compatibility verified. Docs: * AGENTS.md: document the new "rewrite" key alongside "blocked" in the run_shell_command hook row. Co-authored-by: a0s01yh <ashish.singhi@walmart.com>
A skill dir that doesn't exist (e.g. a project without .code_puppy/skills/) is routine, not alarming. Demote 'Skill path does not exist' (and the sibling 'SKILL.md not found' in load_full_skill_content) from WARNING to DEBUG. Real read/list failures still log as errors. Tests now assert zero WARNING+ records while keeping the debug breadcrumb.
…ntion (mpfaffenberger#548) * fix(statusline): cross-platform Windows support + Unicode crash Two bugs reported by Windows users: 1. Terminal crash on German umlauts (ä, ö, ü) subprocess.run(..., text=True) used cp1252 on Windows by default. Any non-ASCII character in script output raised UnicodeDecodeError and killed the terminal session (exit code 1). Fix: add encoding='utf-8', errors='replace' to subprocess.run(). 2. /statusline init broken on Windows _do_init() always wrote a bash .sh script and set the command to the bare file path. Windows has no bash and cmd.exe cannot run .sh. Fix: platform-branch on sys.platform == 'win32': - Write statusline.ps1 using a PowerShell template (no bash/jq) - Set command to: powershell -ExecutionPolicy Bypass -File '<path>' Linux/macOS behaviour is fully unchanged. Tests: add TestCrossPlatform (9 tests) covering: - _default_script_path() for win32 / linux / darwin - PS1 template content guards (no bash-isms, no jq) - _do_init() sets powershell command on win32, bare path on posix - subprocess.run kwargs asserted to include encoding + errors - Umlaut output round-trips without raising * fix: remove unused `call` import (ruff F401) * style: ruff format fixes (statusline_command + test file)
This reverts commit 67c159c.
This reverts commit e8cb918.
…p sub-agent runs + widen retry spacing (mpfaffenberger#616) The production 502 that kept crashing the REPL is NOT an HTTP 502. A gateway (puppy-backend custom_anthropic proxy) delivers the upstream failure as an in-band SSE 'error' event over a connection that itself returned HTTP 200. The Anthropic SDK builds the APIStatusError from the *stream* response, so: * status_code is 200 (not 502), * the class is a plain APIStatusError (not InternalServerError), * body.error.type is a generic 'internal_error', * the only faithful trace of the failure is a '[HTTP 502]' marker in the text. The classifier keyed on status_code / snippet / a fixed error-type set, all of which miss this shape, so should_retry_streaming returned False and no retry fired. The ExceptionGroup-traversal fix (mpfaffenberger#546) couldn't help because every path led to a classifier that said 'not retryable'. - _embedded_http_status(): recover the real upstream status from a '[HTTP NNN]' marker (case-insensitive); _is_transient_status() centralizes the 429/5xx rule. - _is_retryable_one(): provider-agnostic early check on the embedded marker (4xx markers still do NOT retry) + add 'internal_error' to the Anthropic body-type set. - streaming_retry: widen the default spacing from (1,2,4) to (5,30). With 3 attempts only 2 delays fire, so the old budget gave up after ~3s -- but a gateway 502 ('try again in 30 seconds') outlasts that every time, exhausting the burst before the upstream recovers. (5,30) keeps a quick first retry for instant SSE blips, then rides out the advertised ~30s outage (~35s window). - subagent_invocation: wrap temp_agent.run() in streaming_retry(). This path was the ONLY unprotected model-stream call -- run_agent_task has the decorator but sub-agents (e.g. docs-oracle) ran raw and surfaced the 5xx straight up. - Tests: TestInBandSSE5xx (marker shape, ExceptionGroup, internal_error type, 4xx negative) + TestRetryBudgetSpacing (default (5,30), runner sleeps 5 then 30). Co-authored-by: Julien Ellie <julien.ellie@walmart.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
Testing
Notes