@@ -8,7 +8,6 @@ import (
@@ -25,9 +24,7 @@ type SourcegraphResponseMetadata struct {
27type sourcegraphTool struct {
26type sourcegraphTool struct {
28− client *http.Client
27+ client *http.Client
29− clientPool map[int]*http.Client
30− clientPoolMu sync.RWMutex
@@ -138,50 +135,9 @@ func NewSourcegraphTool() BaseTool {
138 IdleConnTimeout: 90 * time.Second,
135 IdleConnTimeout: 90 * time.Second,
141− clientPool: make(map[int]*http.Client),
145−// getClientForTimeout returns a cached client for the given timeout or the default client
146−func (t *sourcegraphTool) getClientForTimeout(timeout int) *http.Client {
151− maxTimeout := 120 // 2 minutes
152− if timeout > maxTimeout {
153− timeout = maxTimeout
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()
162− t.clientPoolMu.RUnlock()
164− // Create and cache a new client
165− t.clientPoolMu.Lock()
166− defer t.clientPoolMu.Unlock()
168− // Double-check in case another goroutine created it
169− if client, exists := t.clientPool[timeout]; exists {
173− client := &http.Client{
174− Timeout: time.Duration(timeout) * time.Second,
175− Transport: &http.Transport{
177− MaxIdleConnsPerHost: 10,
178− IdleConnTimeout: 90 * time.Second,
181− t.clientPool[timeout] = client
185func (t *sourcegraphTool) Info() ToolInfo {
141func (t *sourcegraphTool) Info() ToolInfo {
186 return ToolInfo{
142 return ToolInfo{
187 Name: SourcegraphToolName,
143 Name: SourcegraphToolName,
@@ -227,7 +183,18 @@ func (t *sourcegraphTool) Run(ctx context.Context, call ToolCall) (ToolResponse,
227 if params.ContextWindow <= 0 {
183 if params.ContextWindow <= 0 {
228 params.ContextWindow = 10 // Default context window
184 params.ContextWindow = 10 // Default context window
230− client := t.getClientForTimeout(params.Timeout)
186+
187+ // Handle timeout with context
189+ if params.Timeout > 0 {
190+ maxTimeout := 120 // 2 minutes
191+ if params.Timeout > maxTimeout {
192+ params.Timeout = maxTimeout
194+ var cancel context.CancelFunc
195+ requestCtx, cancel = context.WithTimeout(ctx, time.Duration(params.Timeout)*time.Second)
232 type graphqlRequest struct {
199 type graphqlRequest struct {
233 Query string `json:"query"`
200 Query string `json:"query"`
@@ -248,7 +215,7 @@ func (t *sourcegraphTool) Run(ctx context.Context, call ToolCall) (ToolResponse,
248 graphqlQuery := string(graphqlQueryBytes)
215 graphqlQuery := string(graphqlQueryBytes)
250 req, err := http.NewRequestWithContext(
217 req, err := http.NewRequestWithContext(
251− ctx,
218+ requestCtx,
253 "https://sourcegraph.com/.api/graphql",
220 "https://sourcegraph.com/.api/graphql",
254 bytes.NewBuffer([]byte(graphqlQuery)),
221 bytes.NewBuffer([]byte(graphqlQuery)),
@@ -260,7 +227,7 @@ func (t *sourcegraphTool) Run(ctx context.Context, call ToolCall) (ToolResponse,
260 req.Header.Set("Content-Type", "application/json")
227 req.Header.Set("Content-Type", "application/json")
261 req.Header.Set("User-Agent", "crush/1.0")
228 req.Header.Set("User-Agent", "crush/1.0")
263− resp, err := client.Do(req)
230+ resp, err := t.client.Do(req)
264 if err != nil {
231 if err != nil {
265 return ToolResponse{}, fmt.Errorf("failed to fetch URL: %w", err)
232 return ToolResponse{}, fmt.Errorf("failed to fetch URL: %w", err)