Reduce context usage for create_or_update_file tool#2027
Open
tommaso-moro wants to merge 1 commit intomainfrom
Open
Reduce context usage for create_or_update_file tool#2027tommaso-moro wants to merge 1 commit intomainfrom
create_or_update_file tool#2027tommaso-moro wants to merge 1 commit intomainfrom
Conversation
create_or_update_file tool
Contributor
There was a problem hiding this comment.
Pull request overview
This PR reduces token usage for the create_or_update_file tool by returning a trimmed/minimal response payload instead of the full github.RepositoryContentResponse, aligning with the repository’s existing “minimal types” approach.
Changes:
- Introduces
MinimalFileContentResponse(+ related minimal structs) and a converter inminimal_types.go. - Updates
CreateOrUpdateFileto return the minimal response viaMarshalledTextResult(and in the warning path). - Updates
Test_CreateOrUpdateFileto unmarshal and assert against the new minimal response type.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| pkg/github/repositories.go | Returns minimized JSON payload for create_or_update_file results (including warning flow). |
| pkg/github/minimal_types.go | Adds minimal file content/commit response types + conversion helper. |
| pkg/github/repositories_test.go | Adjusts create/update file tests to validate the new minimal response type. |
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.
Closes: #2028
Summary
This PR reduces the tokens used by the
create_or_update_filetool. When tested it showed a ~69% reduction in tokens usage.It does so by using the minimal types pattern (which is already used elsewhere in the codebase for the same reason) to reduce the payload that is sent back to the model when the tool is used. Specifically, some irrelevant fields are removed, and nested objects are largely optimized by keeping only the strictly necessary fields.
Tests & Metrics
Results: tokens consumption went from 614 to 201, achieving a ~69% reduction in tokens usage.
Tokens were measured using the OpenAI Tokenizer
Fields preserved
name,path,sha,size,html_url(content);sha,message,html_url,author.name,author.email,author.date(commit)Fields dropped
type,encoding,content,target(content);url,git_url,download_url,submodule_git_url(content API URLs);committer(commit — duplicates author in most cases),tree,parents,verification,node_id,url,comment_count(commit)Before
Old payload (614 tokens)
{ "content": { "type": "file", "size": 25, "name": "README.md", "path": "README.md", "sha": "2ff31689ecfd4f3296a0cab5f3a69c14e6d6a71a", "url": "https://api.github.com/repos/tommaso-moro/test-mcp-stuff/contents/README.md?ref=master", "git_url": "https://api.github.com/repos/tommaso-moro/test-mcp-stuff/git/blobs/2ff31689ecfd4f3296a0cab5f3a69c14e6d6a71a", "html_url": "https://github.com/tommaso-moro/test-mcp-stuff/blob/master/README.md", "download_url": "https://raw.githubusercontent.com/tommaso-moro/test-mcp-stuff/master/README.md" }, "commit": { "sha": "af913d0cb94587abfc3203bc004fb81ca0ea5736", "author": { "date": "2026-02-17T16:06:58Z", "name": "Tommaso Moro", "email": "37270480+tommaso-moro@users.noreply.github.com" }, "committer": { "date": "2026-02-17T16:06:58Z", "name": "Tommaso Moro", "email": "37270480+tommaso-moro@users.noreply.github.com" }, "message": "Add \"hello world\" to README.md", "tree": { "sha": "8f92333e6427529dc323e62ab3e8d53db1df0ee7" }, "parents": [ { "sha": "1a5dc5d233f591b1420e84a39cfc0688cb5a6813", "html_url": "https://github.com/tommaso-moro/test-mcp-stuff/commit/1a5dc5d233f591b1420e84a39cfc0688cb5a6813", "url": "https://api.github.com/repos/tommaso-moro/test-mcp-stuff/git/commits/1a5dc5d233f591b1420e84a39cfc0688cb5a6813" } ], "html_url": "https://github.com/tommaso-moro/test-mcp-stuff/commit/af913d0cb94587abfc3203bc004fb81ca0ea5736", "url": "https://api.github.com/repos/tommaso-moro/test-mcp-stuff/git/commits/af913d0cb94587abfc3203bc004fb81ca0ea5736", "verification": { "verified": false, "reason": "unsigned" }, "node_id": "C_kwDOPODl29oAKGFmOTEzZDBjYjk0NTg3YWJmYzMyMDNiYzAwNGZiODFjYTBlYTU3MzY" } }After
New payload: 201 tokens
{ "content": { "name": "README.md", "path": "README.md", "sha": "3b18e512dba79e4c8300dd08aeb37f8e728b8dad", "size": 12, "html_url": "https://github.com/tommaso-moro/test-mcp-stuff/blob/master/README.md" }, "commit": { "sha": "1a5dc5d233f591b1420e84a39cfc0688cb5a6813", "message": "Update README.md with hello world", "html_url": "https://github.com/tommaso-moro/test-mcp-stuff/commit/1a5dc5d233f591b1420e84a39cfc0688cb5a6813", "author": { "name": "Tommaso Moro", "email": "37270480+tommaso-moro@users.noreply.github.com", "date": "2026-02-17T16:05:27Z" } } }Why
The full
github.RepositoryContentResponsepayload returned by the GitHub API is unnecessarily verbose for model reasoning. The embeddedCommitobject contains deeply nested structures —tree,parents(which are themselves fullCommitobjects with their own URLs),verification(signature details), and acommitterthat almost always duplicatesauthor— none of which are useful to the model after a file create/update. TheContentobject also includes multiple API URL variants (url,git_url,download_url,submodule_git_url) that duplicate information derivable fromhtml_url. Sincecreate_or_update_fileis one of the top 3 most-used tools, this overhead is incurred on a large fraction of all tool calls.What changed
MinimalFileContentResponse,MinimalFileContent, andMinimalFileCommittypes tominimal_types.go, following the existingMinimalCommit/MinimalIssue/MinimalPullRequestpatternconvertToMinimalFileContentResponseconverter functionCreateOrUpdateFileto returnMinimalFileContentResponseviaMarshalledTextResultinstead of rawjson.Marshal(fileContent)MinimalFileContentResponsefieldsMCP impact
Prompts tested (tool changes only)
Security / limits
Tool renaming
deprecated_tool_aliases.goNote: if you're renaming tools, you must add the tool aliases. For more information on how to do so, please refer to the official docs.
Lint & tests
./script/lint./script/testDocs