Skip to content

fix: resolve 9 bugs across agent, memory compressor, and handler#9

Merged
cybersecua merged 1 commit intomainfrom
claude/review-fix-improve-ahokR
Mar 6, 2026
Merged

fix: resolve 9 bugs across agent, memory compressor, and handler#9
cybersecua merged 1 commit intomainfrom
claude/review-fix-improve-ahokR

Conversation

@cybersecua
Copy link
Owner

  • isRetryableError: fix "EOF" case mismatch with strings.ToLower (was never matching)
  • getAvailableTools: propagate caller context instead of context.Background() so task cancellation correctly stops external MCP queries
  • convertToOpenAIType: map "int"/"integer" to "integer" (not "number") to conform to JSON Schema/OpenAI spec
  • attachmentContentToBytes: use MimeType field to determine encoding instead of opportunistic try-and-see base64 decode that could corrupt plain-text files
  • summarizeChunk: fallback on empty summary now preserves all chunk messages instead of silently discarding all but the first
  • countTotalTokens: include ToolCalls JSON when counting message tokens so compression triggers at the correct threshold
  • AgentLoopWithProgress: remove duplicate comment
  • AgentLoopStream: consolidate two separate role-config lookups into one, ensuring roleSkills is captured alongside roleTools
  • saveAttachmentsToDateAndConversationDir: enforce 50 MB per-file size limit to prevent disk/memory exhaustion

- isRetryableError: fix "EOF" case mismatch with strings.ToLower (was never matching)
- getAvailableTools: propagate caller context instead of context.Background() so task cancellation correctly stops external MCP queries
- convertToOpenAIType: map "int"/"integer" to "integer" (not "number") to conform to JSON Schema/OpenAI spec
- attachmentContentToBytes: use MimeType field to determine encoding instead of opportunistic try-and-see base64 decode that could corrupt plain-text files
- summarizeChunk: fallback on empty summary now preserves all chunk messages instead of silently discarding all but the first
- countTotalTokens: include ToolCalls JSON when counting message tokens so compression triggers at the correct threshold
- AgentLoopWithProgress: remove duplicate comment
- AgentLoopStream: consolidate two separate role-config lookups into one, ensuring roleSkills is captured alongside roleTools
- saveAttachmentsToDateAndConversationDir: enforce 50 MB per-file size limit to prevent disk/memory exhaustion

https://claude.ai/code/session_017MtB57yFAgBeBhNyo7vfkp
@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses nine distinct bugs and improvements across the agent, memory compressor, and handler components. The changes focus on enhancing the robustness, correctness, and resource management of the application, including better error handling, accurate token counting, improved attachment processing, and streamlined agent configuration.

Highlights

  • Error Handling: Fixed an "EOF" case mismatch in isRetryableError, ensuring proper error detection.
  • Context Propagation: Propagated the caller's context to getAvailableTools to allow task cancellation for external MCP queries.
  • OpenAI Type Conformance: Corrected convertToOpenAIType to map "int" and "integer" to "integer" for better adherence to JSON Schema/OpenAI specifications.
  • Attachment Encoding: Updated attachmentContentToBytes to use the MimeType field for determining content encoding, preventing potential corruption of plain-text files.
  • Memory Compression Fallback: Implemented a fallback in summarizeChunk that preserves all chunk messages when an empty summary is generated, preventing data loss.
  • Accurate Token Counting: Included ToolCalls JSON in the token count within countTotalTokens to ensure memory compression triggers at the correct threshold.
  • Code Cleanliness: Removed a duplicate comment in AgentLoopWithProgress for improved code clarity.
  • Agent Configuration Streamlining: Consolidated role-config lookups in AgentLoopStream to ensure roleSkills are captured alongside roleTools efficiently.
  • Resource Management: Enforced a 50 MB per-file size limit for attachments in saveAttachmentsToDateAndConversationDir to prevent disk/memory exhaustion.
Changelog
  • internal/agent/agent.go
    • Removed a redundant comment.
    • Updated getAvailableTools function signature to accept context.Context.
    • Modified getAvailableTools to pass the provided context.Context to external MCP manager calls instead of context.Background().
    • Corrected the convertToOpenAIType function to map "int" and "integer" to "integer" for OpenAI specification compliance.
    • Changed the "EOF" string to lowercase "eof" in isRetryableError for consistent error matching.
  • internal/agent/memory_compressor.go
    • Added encoding/json import.
    • Refactored countTotalTokens to utilize a new helper function countMessageTokens.
    • Introduced countMessageTokens to accurately count tokens for ChatMessage objects, including the JSON representation of ToolCalls.
    • Modified summarizeChunk to concatenate all messages in a chunk into a summary if the generated summary is empty, preventing data loss.
  • internal/handler/agent.go
    • Defined maxAttachmentSizeBytes constant for a 50 MB file limit.
    • Implemented a size check in saveAttachmentsToDateAndConversationDir to prevent saving attachments larger than 50 MB.
    • Updated attachmentContentToBytes to use the MimeType field to determine if content should be base64 decoded, rather than an opportunistic approach.
    • Consolidated the roleSkills and roleTools configuration lookup within AgentLoopStream to avoid redundant processing.
    • Removed a duplicate block of code responsible for roleSkills lookup in AgentLoopStream.
Activity
  • No human activity has been recorded for this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@cybersecua cybersecua merged commit dce71d3 into main Mar 6, 2026
@cybersecua cybersecua deleted the claude/review-fix-improve-ahokR branch March 6, 2026 00:29
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a series of bug fixes and improvements across the agent, memory compressor, and handler components. However, a security audit identified two critical vulnerabilities in the attachment handling logic: a path traversal vulnerability due to insufficient filename sanitization and a potential Denial of Service (DoS) via memory exhaustion during base64 decoding of large attachments. These must be addressed to ensure the robustness of the file upload functionality. The PR also includes fixes for incorrect context propagation to external MCP queries, more robust attachment decoding using MIME types, and enhancements to the memory compressor for tool call tokens and summarization failures. A further improvement would be to expand the list of recognized MIME types for binary attachments.

Comment on lines +163 to +165
if len(raw) > maxAttachmentSizeBytes {
return nil, fmt.Errorf("attachment %s exceeds maximum allowed size of %d MB", a.FileName, maxAttachmentSizeBytes/(1024*1024))
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The function saveAttachmentsToDateAndConversationDir is vulnerable to path traversal. While it uses filepath.Base to extract the filename from a.FileName, this is insufficient on Unix-like systems if the filename contains backslashes (\). An attacker can provide a filename like ..\..\..\etc\passwd, which filepath.Base will return unchanged on Linux. When this is subsequently used in filepath.Join to construct the fullPath, it allows writing files outside the intended targetDir. Although this PR adds a size check, it does not address the underlying path traversal vulnerability in the filename handling logic.

if a.MimeType != "" && (strings.HasPrefix(a.MimeType, "image/") ||
a.MimeType == "application/octet-stream" ||
a.MimeType == "application/pdf") {
decoded, err := base64.StdEncoding.DecodeString(content)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

The attachmentContentToBytes function decodes base64-encoded content from the user request before any size validation is performed. An attacker can send a request with a very large base64 string and a binary MimeType, causing the server to attempt to allocate a large amount of memory for the decoded bytes. This can lead to memory exhaustion and a Denial of Service (DoS) condition. The size check added in saveAttachmentsToDateAndConversationDir occurs after the decoding process, which is too late to prevent the initial memory allocation.

Suggested change
decoded, err := base64.StdEncoding.DecodeString(content)
if len(content) > maxAttachmentSizeBytes * 4 / 3 {
return nil, fmt.Errorf("attachment content exceeds maximum allowed size")
}
decoded, err := base64.StdEncoding.DecodeString(content)

Comment on lines +206 to +208
if a.MimeType != "" && (strings.HasPrefix(a.MimeType, "image/") ||
a.MimeType == "application/octet-stream" ||
a.MimeType == "application/pdf") {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The list of MIME types that are treated as base64-encoded seems incomplete. It currently covers images, PDFs, and generic binary streams. However, other common binary file types like audio, video, and various document/archive formats (e.g., zip) would be incorrectly treated as plain text, potentially leading to data corruption when they are saved.

Consider expanding this list to include more common binary MIME type prefixes and types.

Suggested change
if a.MimeType != "" && (strings.HasPrefix(a.MimeType, "image/") ||
a.MimeType == "application/octet-stream" ||
a.MimeType == "application/pdf") {
if a.MimeType != "" && (strings.HasPrefix(a.MimeType, "image/") ||
strings.HasPrefix(a.MimeType, "audio/") ||
strings.HasPrefix(a.MimeType, "video/") ||
a.MimeType == "application/octet-stream" ||
a.MimeType == "application/pdf" ||
a.MimeType == "application/zip") {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants