feat: git-aware context tools#2832
Open
TheArchitectit wants to merge 8 commits into
Open
Conversation
…w, GitBlame) Add five native git tools that provide structured read-only access to repository state, replacing ad-hoc bash git commands with purpose-built tool definitions the model can discover and invoke directly. - GitStatus: working tree status with --short --branch - GitDiff: diff with optional staged/commit/path filters - GitLog: commit log with count, oneline, author, since/until, path - GitShow: show commit/tree content with optional stat and path - GitBlame: line-level blame with optional start/end line range All tools use the existing git_stdout() helper and are PermissionMode::ReadOnly.
Some OpenAI-compatible providers (e.g., GLM-5) omit the `id` field in streaming and non-streaming responses. Adding #[serde(default)] allows the parser to accept these responses instead of failing with "missing field `id`". Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds scripts/install.sh that builds the release binary and links it to ~/.local/bin/claw. Run after code changes to update the CLI. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
When a provider returns HTML (e.g., error page, wrong endpoint) instead of JSON in an SSE stream, provide a clear error message instead of hanging or failing with a cryptic parse error. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
When a provider returns a JSON error (e.g., {"error":{"message":"..."}})
without SSE framing (no "data:" prefix), the SSE parser was silently
ignoring it and hanging. Now detects and surfaces these errors.
Also handles HTML responses that lack SSE framing.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Some providers (GLM, DeepSeek) emit reasoning tokens in `reasoning_content` or nested `thinking.content` fields instead of `content`. Added support for these fields so reasoning models work correctly. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The final streaming chunk from some providers contains only finish_reason and usage, with no delta field. Made it optional to prevent parse errors. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
When preserve_recent_messages == 0, raw_keep_from equals messages.len(), causing index out of bounds when accessing session.messages[k]. Added k >= session.messages.len() check to prevent panic. Reason: Compaction with preserve_recent_messages=0 triggered OOB access when checking for tool-use/tool-result pair preservation at boundary. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
fd03455 to
7aedde7
Compare
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
This PR adds five native, read-only git tools that replace ad-hoc
bashinvocations for common git operations:GitStatus,GitDiff,GitLog,GitShow, andGitBlame.Problem
Before this change, the model had to use the generic
bashtool for every git operation. This created several friction points:DangerFullAccessToolSearchwon't find "git diff" because no such tool existsgit logoutput with ANSI colors and padding consumes tokensSolution
Five first-class tools with structured JSON output,
ReadOnlypermissions, and model-friendly descriptions:GitStatuspath(optional repo root)GitDiffstaged,commit,pathGitLogcount,oneline,author,sinceGitShowcommit(hash or ref),statGitBlamepath,start_line,end_lineAll tools:
PermissionMode::ReadOnly— safe in restricted environmentsToolSearchwith keywords like "git", "diff", "blame", "history"bashImplementation
rust/crates/tools/src/git.rswithToolDescriptionderive macrosrun()for each tool using the existinggit_stdout()helperTest Plan
GitStatusreturns correct branch and file status JSONGitDiffwithstaged: trueshows cached changesGitLogwithcount: 5andoneline: truereturns condensed historyGitShowwith a commit hash returns the diff and metadataGitBlamewith a file path and line range returns per-line authorshipToolSearchwith relevant keywordsReadOnlyfor all five toolsImpact
DangerFullAccessbashgit invocations continue to work