Skip to content

Commit 851030c

Browse files
authored
Reduce context usage for create_or_update_file tool (#2027)
* optimize context usage * add assortions and check for nil response * refactor
1 parent eec84f7 commit 851030c

File tree

3 files changed

+83
-14
lines changed

3 files changed

+83
-14
lines changed

pkg/github/minimal_types.go

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,29 @@ type MinimalIssueComment struct {
185185
UpdatedAt string `json:"updated_at,omitempty"`
186186
}
187187

188+
// MinimalFileContentResponse is the trimmed output type for create/update/delete file responses.
189+
type MinimalFileContentResponse struct {
190+
Content *MinimalFileContent `json:"content,omitempty"`
191+
Commit *MinimalFileCommit `json:"commit,omitempty"`
192+
}
193+
194+
// MinimalFileContent is the trimmed content portion of a file operation response.
195+
type MinimalFileContent struct {
196+
Name string `json:"name"`
197+
Path string `json:"path"`
198+
SHA string `json:"sha"`
199+
Size int `json:"size,omitempty"`
200+
HTMLURL string `json:"html_url"`
201+
}
202+
203+
// MinimalFileCommit is the trimmed commit portion of a file operation response.
204+
type MinimalFileCommit struct {
205+
SHA string `json:"sha"`
206+
Message string `json:"message,omitempty"`
207+
HTMLURL string `json:"html_url,omitempty"`
208+
Author *MinimalCommitAuthor `json:"author,omitempty"`
209+
}
210+
188211
// MinimalPullRequest is the trimmed output type for pull request objects to reduce verbosity.
189212
type MinimalPullRequest struct {
190213
Number int `json:"number"`
@@ -338,6 +361,42 @@ func convertToMinimalIssueComment(comment *github.IssueComment) MinimalIssueComm
338361
return m
339362
}
340363

364+
func convertToMinimalFileContentResponse(resp *github.RepositoryContentResponse) MinimalFileContentResponse {
365+
m := MinimalFileContentResponse{}
366+
367+
if resp == nil {
368+
return m
369+
}
370+
371+
if c := resp.Content; c != nil {
372+
m.Content = &MinimalFileContent{
373+
Name: c.GetName(),
374+
Path: c.GetPath(),
375+
SHA: c.GetSHA(),
376+
Size: c.GetSize(),
377+
HTMLURL: c.GetHTMLURL(),
378+
}
379+
}
380+
381+
m.Commit = &MinimalFileCommit{
382+
SHA: resp.Commit.GetSHA(),
383+
Message: resp.Commit.GetMessage(),
384+
HTMLURL: resp.Commit.GetHTMLURL(),
385+
}
386+
387+
if author := resp.Commit.Author; author != nil {
388+
m.Commit.Author = &MinimalCommitAuthor{
389+
Name: author.GetName(),
390+
Email: author.GetEmail(),
391+
}
392+
if author.Date != nil {
393+
m.Commit.Author.Date = author.Date.Format(time.RFC3339)
394+
}
395+
}
396+
397+
return m
398+
}
399+
341400
func convertToMinimalPullRequest(pr *github.PullRequest) MinimalPullRequest {
342401
m := MinimalPullRequest{
343402
Number: pr.GetNumber(),
@@ -480,7 +539,7 @@ func convertToMinimalCommit(commit *github.RepositoryCommit, includeDiffs bool)
480539
Email: commit.Commit.Author.GetEmail(),
481540
}
482541
if commit.Commit.Author.Date != nil {
483-
minimalCommit.Commit.Author.Date = commit.Commit.Author.Date.Format("2006-01-02T15:04:05Z")
542+
minimalCommit.Commit.Author.Date = commit.Commit.Author.Date.Format(time.RFC3339)
484543
}
485544
}
486545

@@ -490,7 +549,7 @@ func convertToMinimalCommit(commit *github.RepositoryCommit, includeDiffs bool)
490549
Email: commit.Commit.Committer.GetEmail(),
491550
}
492551
if commit.Commit.Committer.Date != nil {
493-
minimalCommit.Commit.Committer.Date = commit.Commit.Committer.Date.Format("2006-01-02T15:04:05Z")
552+
minimalCommit.Commit.Committer.Date = commit.Commit.Committer.Date.Format(time.RFC3339)
494553
}
495554
}
496555
}

pkg/github/repositories.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -489,13 +489,14 @@ If the SHA is not provided, the tool will attempt to acquire it by fetching the
489489
return ghErrors.NewGitHubAPIStatusErrorResponse(ctx, "failed to create/update file", resp, body), nil, nil
490490
}
491491

492-
r, err := json.Marshal(fileContent)
493-
if err != nil {
494-
return nil, nil, fmt.Errorf("failed to marshal response: %w", err)
495-
}
492+
minimalResponse := convertToMinimalFileContentResponse(fileContent)
496493

497494
// Warn if file was updated without SHA validation (blind update)
498495
if sha == "" && previousSHA != "" {
496+
warning, err := json.Marshal(minimalResponse)
497+
if err != nil {
498+
return nil, nil, fmt.Errorf("failed to marshal response: %w", err)
499+
}
499500
return utils.NewToolResultText(fmt.Sprintf(
500501
"Warning: File updated without SHA validation. Previous file SHA was %s. "+
501502
`Verify no unintended changes were overwritten:
@@ -504,10 +505,10 @@ If the SHA is not provided, the tool will attempt to acquire it by fetching the
504505
3. Revert changes if shas do not match.
505506
506507
%s`,
507-
previousSHA, path, string(r))), nil, nil
508+
previousSHA, path, string(warning))), nil, nil
508509
}
509510

510-
return utils.NewToolResultText(string(r)), nil, nil
511+
return MarshalledTextResult(minimalResponse), nil, nil
511512
},
512513
)
513514
}

pkg/github/repositories_test.go

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,18 +1434,27 @@ func Test_CreateOrUpdateFile(t *testing.T) {
14341434
}
14351435

14361436
// Unmarshal and verify the result
1437-
var returnedContent github.RepositoryContentResponse
1437+
var returnedContent MinimalFileContentResponse
14381438
err = json.Unmarshal([]byte(textContent.Text), &returnedContent)
14391439
require.NoError(t, err)
14401440

14411441
// Verify content
1442-
assert.Equal(t, *tc.expectedContent.Content.Name, *returnedContent.Content.Name)
1443-
assert.Equal(t, *tc.expectedContent.Content.Path, *returnedContent.Content.Path)
1444-
assert.Equal(t, *tc.expectedContent.Content.SHA, *returnedContent.Content.SHA)
1442+
assert.Equal(t, tc.expectedContent.Content.GetName(), returnedContent.Content.Name)
1443+
assert.Equal(t, tc.expectedContent.Content.GetPath(), returnedContent.Content.Path)
1444+
assert.Equal(t, tc.expectedContent.Content.GetSHA(), returnedContent.Content.SHA)
1445+
assert.Equal(t, tc.expectedContent.Content.GetSize(), returnedContent.Content.Size)
1446+
assert.Equal(t, tc.expectedContent.Content.GetHTMLURL(), returnedContent.Content.HTMLURL)
14451447

14461448
// Verify commit
1447-
assert.Equal(t, *tc.expectedContent.Commit.SHA, *returnedContent.Commit.SHA)
1448-
assert.Equal(t, *tc.expectedContent.Commit.Message, *returnedContent.Commit.Message)
1449+
assert.Equal(t, tc.expectedContent.Commit.GetSHA(), returnedContent.Commit.SHA)
1450+
assert.Equal(t, tc.expectedContent.Commit.GetMessage(), returnedContent.Commit.Message)
1451+
assert.Equal(t, tc.expectedContent.Commit.GetHTMLURL(), returnedContent.Commit.HTMLURL)
1452+
1453+
// Verify commit author
1454+
require.NotNil(t, returnedContent.Commit.Author)
1455+
assert.Equal(t, tc.expectedContent.Commit.Author.GetName(), returnedContent.Commit.Author.Name)
1456+
assert.Equal(t, tc.expectedContent.Commit.Author.GetEmail(), returnedContent.Commit.Author.Email)
1457+
assert.NotEmpty(t, returnedContent.Commit.Author.Date)
14491458
})
14501459
}
14511460
}

0 commit comments

Comments
 (0)