Harden edit_file matching and complete VPS SSH tools - #18
Closed
nvdorman wants to merge 15 commits into
Closed
Conversation
edit_file now recovers from the common read_file→edit failures (CRLF vs LF, pasted NUMBER| prefixes) and diagnoses tab/space mismatches; system prompt documents the NUMBER|CONTENT contract. vps_run no longer false-timeouts on systemctl-class work: default 120s, agent envelope above the 900s max, race-free cancel, keyboard-interactive auth, and clear timeout errors. Add vps_upload/vps_download over SFTP.
//go:embed all:dist fails on a bare checkout because built assets are gitignored. Track a .gitkeep placeholder and recreate it in CI so test/vet compile without a frontend build.
Persistent-shell scripts keep stdin open for the next tool call. Children like `adb shell` inherit that pipe, steal the completion sentinel or block on it, and the tool waits until timeout even though remote work finished. Run each command in a brace group with stdin from /dev/null so the sentinel can fire immediately; brace group preserves cd/export across calls.
Dashboard login sessions lived only in memory, so after antares restart the browser cookie looked valid but /api/chat/attach returned 401 in a 3s loop — live tool/stream updates never arrived. Persist sessions to disk and accept allowlisted ?token= in dashboard auth. The chat UI ignored EventNotice, so multi-minute context compaction showed only "Working… · Ns". Surface notices in the streaming indicator, and stream GET attach via fetch+credentials instead of EventSource for reliable cookies.
… turn Compaction ran on every turn for oversized sessions because the summary lived only in memory while loadHistory always reloaded all raw messages. Store the summary and through_seq on session meta; subsequent turns load head+summary+tail and only compact again when that view exceeds the threshold. Clear the meta on edit-message so history rewrites stay consistent.
Tools existed but system prompt never steered models away from terminal rsync/scp. Add tool-notes guidance whenever the VPS transfer tools are active, and tighten tool descriptions plus the vps-manager skill/role.
Arrow keys previously only navigated the slash-command palette. Store recent sends in localStorage and recall them with ↑/↓ when the caret is on the first/last line, matching shell-style prompt history without breaking multi-line editing.
Re-apply the missing fix: Go's append(nil, empty...) encodes tools as JSON null, and the MCP page called .length on it. Return a non-nil empty slice and normalize tools on the client with mcpToolsOrEmpty.
Brings the remaining coverage from the closed daemon-stdin fix so a background setsid/adb-style child cannot pin the shell's completion sentinel.
Prevent top-level model credentials from clobbering named providers, rename web_search on Antigravity wires, preserve Gemini thought signatures, accept CLI-style /antigravity base URLs (append /v1beta), and pin sticky session signals so multi-account gateways keep account affinity across agent turns.
MCP stdio held a lock for the full RPC duration, so Close/Refresh blocked when IDA or another backend hung, leaving zombie children and freezing the web UI. Chat also re-mapped the entire transcript every frame and grew unbounded reasoning strings during high-effort turns. Release the send lock while waiting for responses, kill+Wait on Close, batch stream patches by message only, and make live reasoning display configurable via display.show_reasoning and display.max_live_reasoning_chars.
Reasoning traces are long decompiler-style text. Rendering them through the chat Markdown pipeline on expand created hundreds of React nodes and locked the main thread (Chrome "Page Unresponsive"). Show reasoning as plain pre-wrap text in a height-capped scroller, and defer the body to the next frame so the toggle stays responsive.
…-misses Most edit_file failures are model-side: short old_string hits many sites, or stale/wrong identifiers (entity vs attachEntity) never exist in the file. Surface occurrence line numbers when the match is ambiguous, and near-miss file lines when nothing matches, so the agent re-reads instead of inventing. Also steer the prompt to require unique context and prefer edit_file over sed.
…and near-misses" This reverts commit 164078d.
enowdev
pushed a commit
that referenced
this pull request
Aug 9, 2026
…avity routing Merges nvdorman's work covering edit_file CRLF/line-prefix recovery, vps_run timeout fixes plus new vps_upload/vps_download SFTP tools, persisted context compaction, dashboard session persistence, MCP tool refresh, composer prompt history, and Gemini thoughtSignature handling. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
enowdev
pushed a commit
that referenced
this pull request
Aug 9, 2026
Three defects found reviewing the merge: - config: ANTARES_BASE_URL / ANTARES_API_KEY became silently inert. PR #18 made a named provider's stored credentials always beat the top-level model.* fields, but those env vars are documented overrides that write into model.*, so exporting them stopped having any effect whenever providers.<id> already had a key (the common case). Track whether the value came from the environment and let an env-supplied credential win, while a stale value left in config.yaml still loses. The cross-provider leak PR #18 targeted is already handled by its own ClearInlineModelCredentials() calls on every provider-switch path. - server: POST /api/mcp/refresh panicked when MCP was not configured. handleMCPRefresh boxed a possibly-nil *mcp.Manager into the mcpRefresher interface, where the 'refresher == nil' guard is false, so Refresh dereferenced a nil receiver. Check the concrete pointer first, matching handleMCPStatus. - vps: vps_download/vps_upload could destroy the file they replace. Both opened the destination with O_TRUNC before the first byte arrived, so a mid-transfer timeout left a truncated stub and no original — worst on upload, whose whole purpose is replacing a live service config. Stream to a temp path and rename on success. Download also created the local file with the *remote* file's permission bits, so a 0777 remote file produced a world-writable local one; use a fixed 0600 instead. Also adds tool_call argument validation and retryable provider-side truncated-JSON messages (prior local work). Pre-existing issues found while reviewing, left alone as out of scope: Manager.Connect replaces m.clients without closing the old clients or updating the registry (leaks one stdio subprocess per server on every MCP add/delete), and Status unconditionally overwrites the connect error with the tool-listing error. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Owner
|
Landed on |
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
read_file→ edit failures (LF paste against CRLF files, pastedNUMBER|line prefixes), diagnose tab-vs-space mismatches, and teach the NUMBER|CONTENT contract in the system prompt.systemctl-class work — default timeout 120s (max 900), agent envelope above that, race-free session cancel, keyboard-interactive password auth, SSH keepalives, and actionable timeout errors with partial output.Root causes (researched, not guessed)
read_filealways displays LF whileedit_filemust match on-disk bytes; this completes CRLF recovery, strips accidentalNUMBER|pastes, and surfaces tab/space diagnostics.vps_rundefaulted to 60s whilesystemctl restart/stopoften exceeds that; the agent tool envelope (5m) could cut off longtimeout_secondsearly; password-only auth failed on keyboard-interactive hosts; the timeout path raced on output and did not reliably close the SSH session.Test plan
go test ./internal/tools/ ./internal/vps/ ./internal/agent/ -count=1go build ./cmd/antaresread_filea CRLF/tabbed source,edit_filewith content after|vps_runlist servers;systemctl status … --no-pager; restart withtimeout_seconds=180vps_uploada small file,vps_downloadit back, confirm bytes