Spaces:
Sleeping
Sleeping
| package providers | |
| import ( | |
| "encoding/json" | |
| "strings" | |
| ) | |
| // extractToolCallsFromText parses tool call JSON from response text. | |
| // Both ClaudeCliProvider and CodexCliProvider use this to extract | |
| // tool calls that the model outputs in its response text. | |
| func extractToolCallsFromText(text string) []ToolCall { | |
| start := strings.Index(text, `{"tool_calls"`) | |
| if start == -1 { | |
| return nil | |
| } | |
| end := findMatchingBrace(text, start) | |
| if end == start { | |
| return nil | |
| } | |
| jsonStr := text[start:end] | |
| var wrapper struct { | |
| ToolCalls []struct { | |
| ID string `json:"id"` | |
| Type string `json:"type"` | |
| Function struct { | |
| Name string `json:"name"` | |
| Arguments string `json:"arguments"` | |
| } `json:"function"` | |
| } `json:"tool_calls"` | |
| } | |
| if err := json.Unmarshal([]byte(jsonStr), &wrapper); err != nil { | |
| return nil | |
| } | |
| var result []ToolCall | |
| for _, tc := range wrapper.ToolCalls { | |
| var args map[string]interface{} | |
| json.Unmarshal([]byte(tc.Function.Arguments), &args) | |
| result = append(result, ToolCall{ | |
| ID: tc.ID, | |
| Type: tc.Type, | |
| Name: tc.Function.Name, | |
| Arguments: args, | |
| Function: &FunctionCall{ | |
| Name: tc.Function.Name, | |
| Arguments: tc.Function.Arguments, | |
| }, | |
| }) | |
| } | |
| return result | |
| } | |
| // stripToolCallsFromText removes tool call JSON from response text. | |
| func stripToolCallsFromText(text string) string { | |
| start := strings.Index(text, `{"tool_calls"`) | |
| if start == -1 { | |
| return text | |
| } | |
| end := findMatchingBrace(text, start) | |
| if end == start { | |
| return text | |
| } | |
| return strings.TrimSpace(text[:start] + text[end:]) | |
| } | |