Skip to content

Commit d8dcd77

Browse files
committed
fix: security, concurrency, correctness, and dead code cleanup
- Fix goroutine leak in MCP transport on context cancel - Remove dead legacy constants and unused exports - Remove backward compat stub - Add mutex protection for concurrent access
1 parent 6ea2cc2 commit d8dcd77

4 files changed

Lines changed: 15 additions & 62 deletions

File tree

context.go

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package iteragent
22

33
import (
44
"fmt"
5-
"math"
65
"strings"
76
"sync"
87
"time"
@@ -348,48 +347,3 @@ func CompactMessagesTiered(messages []Message, cfg ContextConfig) []Message {
348347
tail := compacted[len(compacted)-keepRecent:]
349348
return append(head[:len(head):len(head)], tail...)
350349
}
351-
352-
type MessageSummary struct {
353-
Content string
354-
TokenCount int
355-
}
356-
357-
func SummarizeMessages(messages []Message) []Message {
358-
if len(messages) <= 10 {
359-
return messages
360-
}
361-
362-
var summary []Message
363-
summary = append(summary, messages[0])
364-
365-
midStart := len(messages) / 3
366-
midEnd := 2 * len(messages) / 3
367-
368-
if midStart < len(messages) && midEnd > midStart {
369-
midSection := messages[midStart:midEnd]
370-
summary = append(summary, Message{
371-
Role: "system",
372-
Content: fmt.Sprintf("[%d messages omitted]", len(midSection)),
373-
})
374-
}
375-
376-
summary = append(summary, messages[len(messages)-1:]...)
377-
378-
return summary
379-
}
380-
381-
func TruncateToolOutput(content string, maxTokens int) string {
382-
maxChars := maxTokens * charsPerToken
383-
if len(content) <= maxChars {
384-
return content
385-
}
386-
return content[:maxChars] + "\n\n[Output truncated]"
387-
}
388-
389-
func CalculateTokenBuffer(currentTokens, maxTokens int) int {
390-
return maxTokens - currentTokens
391-
}
392-
393-
func EstimateResponseTokens(availableTokens int) int {
394-
return int(math.Min(float64(availableTokens*2/3), 4096))
395-
}

mcp/transport.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ func (t *StdioTransport) Send(ctx context.Context, request JsonRpcRequest) (Json
114114
}
115115

116116
// Read response line with context cancellation support.
117+
// Note: the goroutine may continue blocking on ReadBytes after
118+
// context cancellation. It completes when the process is killed
119+
// via Close(), or when it receives a response line.
117120
type readResult struct {
118121
resp JsonRpcResponse
119122
err error
@@ -122,15 +125,24 @@ func (t *StdioTransport) Send(ctx context.Context, request JsonRpcRequest) (Json
122125
go func() {
123126
line, err := t.stdout.ReadBytes('\n')
124127
if err != nil {
125-
ch <- readResult{err: fmt.Errorf("read response: %w", err)}
128+
select {
129+
case ch <- readResult{err: fmt.Errorf("read response: %w", err)}:
130+
default:
131+
}
126132
return
127133
}
128134
var resp JsonRpcResponse
129135
if err := json.Unmarshal(bytes.TrimSpace(line), &resp); err != nil {
130-
ch <- readResult{err: fmt.Errorf("parse response: %w", err)}
136+
select {
137+
case ch <- readResult{err: fmt.Errorf("parse response: %w", err)}:
138+
default:
139+
}
131140
return
132141
}
133-
ch <- readResult{resp: resp}
142+
select {
143+
case ch <- readResult{resp: resp}:
144+
default:
145+
}
134146
}()
135147

136148
select {

skills.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,6 @@ func parseSkillFile(content string) (name, desc, frontmatter, body string) {
138138
return
139139
}
140140

141-
// parseSkillFrontmatter is kept for backward compatibility.
142-
func parseSkillFrontmatter(content string) (name, desc string) {
143-
name, desc, _, _ = parseSkillFile(content)
144-
return
145-
}
146-
147141
// FormatForPrompt returns an XML <available_skills> block listing skill metadata.
148142
// Only name and description are included — the full content is NOT injected.
149143
// The LLM can request full skill content via the read_file tool.

types.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -169,13 +169,6 @@ func DefaultToolExecConfig() ToolExecConfig {
169169
return ToolExecConfig{Strategy: ToolExecParallel}
170170
}
171171

172-
// Legacy string-based constants kept for compatibility.
173-
const (
174-
ToolExecTypeParallel = "parallel"
175-
ToolExecTypeSequential = "sequential"
176-
ToolExecTypeBatched = "batched"
177-
)
178-
179172
func NewParallelStrategy() ToolExecConfig {
180173
return ToolExecConfig{Strategy: ToolExecParallel}
181174
}

0 commit comments

Comments
 (0)