@@ -8,7 +8,6 @@ import (
88 "io"
99 "net/http"
1010 "strings"
11− "sync"
1211 "time"
1312)
1413
@@ -25,9 +24,7 @@ type SourcegraphResponseMetadata struct {
2524}
2625
2726type sourcegraphTool struct {
28− client *http.Client
29− clientPool map[int]*http.Client
30− clientPoolMu sync.RWMutex
27+ client *http.Client
3128}
3229
3330const (
@@ -138,50 +135,9 @@ func NewSourcegraphTool() BaseTool {
138135 IdleConnTimeout: 90 * time.Second,
139136 },
140137 },
141− clientPool: make(map[int]*http.Client),
142138 }
143139}
144140
145−// getClientForTimeout returns a cached client for the given timeout or the default client
146−func (t *sourcegraphTool) getClientForTimeout(timeout int) *http.Client {
147− if timeout <= 0 {
148− return t.client
149− }
150−
151− maxTimeout := 120 // 2 minutes
152− if timeout > maxTimeout {
153− timeout = maxTimeout
154− }
155−
156− // Check if we have a cached client for this timeout
157− t.clientPoolMu.RLock()
158− if client, exists := t.clientPool[timeout]; exists {
159− t.clientPoolMu.RUnlock()
160− return client
161− }
162− t.clientPoolMu.RUnlock()
163−
164− // Create and cache a new client
165− t.clientPoolMu.Lock()
166− defer t.clientPoolMu.Unlock()
167−
168− // Double-check in case another goroutine created it
169− if client, exists := t.clientPool[timeout]; exists {
170− return client
171− }
172−
173− client := &http.Client{
174− Timeout: time.Duration(timeout) * time.Second,
175− Transport: &http.Transport{
176− MaxIdleConns: 100,
177− MaxIdleConnsPerHost: 10,
178− IdleConnTimeout: 90 * time.Second,
179− },
180− }
181− t.clientPool[timeout] = client
182− return client
183−}
184−
185141func (t *sourcegraphTool) Info() ToolInfo {
186142 return ToolInfo{
187143 Name: SourcegraphToolName,
@@ -227,7 +183,18 @@ func (t *sourcegraphTool) Run(ctx context.Context, call ToolCall) (ToolResponse,
227183 if params.ContextWindow <= 0 {
228184 params.ContextWindow = 10 // Default context window
229185 }
230− client := t.getClientForTimeout(params.Timeout)
186+
187+ // Handle timeout with context
188+ requestCtx := ctx
189+ if params.Timeout > 0 {
190+ maxTimeout := 120 // 2 minutes
191+ if params.Timeout > maxTimeout {
192+ params.Timeout = maxTimeout
193+ }
194+ var cancel context.CancelFunc
195+ requestCtx, cancel = context.WithTimeout(ctx, time.Duration(params.Timeout)*time.Second)
196+ defer cancel()
197+ }
231198
232199 type graphqlRequest struct {
233200 Query string `json:"query"`
@@ -248,7 +215,7 @@ func (t *sourcegraphTool) Run(ctx context.Context, call ToolCall) (ToolResponse,
248215 graphqlQuery := string(graphqlQueryBytes)
249216
250217 req, err := http.NewRequestWithContext(
251− ctx,
218+ requestCtx,
252219 "POST",
253220 "https://sourcegraph.com/.api/graphql",
254221 bytes.NewBuffer([]byte(graphqlQuery)),
@@ -260,7 +227,7 @@ func (t *sourcegraphTool) Run(ctx context.Context, call ToolCall) (ToolResponse,
260227 req.Header.Set("Content-Type", "application/json")
261228 req.Header.Set("User-Agent", "crush/1.0")
262229
263− resp, err := client.Do(req)
230+ resp, err := t.client.Do(req)
264231 if err != nil {
265232 return ToolResponse{}, fmt.Errorf("failed to fetch URL: %w", err)
266233 }