Files
goclaw/internal/tools/openai_compat_call.go
T
viettranx bdb60de7ae chore: upgrade Go 1.25 → 1.26 and apply go fix modernizations
- Update go.mod and Dockerfile to Go 1.26
- Apply `go fix ./...` stdlib modernizations across 170+ files
- Add `go fix` to post-implementation checklist in CLAUDE.md
- Fix go fix misapplied rewrite in loop_history.go
2026-03-10 00:09:15 +07:00

81 lines
2.4 KiB
Go

package tools
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
"time"
"github.com/nextlevelbuilder/goclaw/internal/providers"
)
// callOpenAICompatJSON sends a raw JSON body to an OpenAI-compatible chat/completions endpoint
// and parses the response into a ChatResponse. Used by audio/video tools that need custom
// message formats not supported by the generic providers.ChatRequest interface.
func callOpenAICompatJSON(ctx context.Context, apiKey, baseURL string, body map[string]any, timeout time.Duration) (*providers.ChatResponse, error) {
jsonBody, err := json.Marshal(body)
if err != nil {
return nil, fmt.Errorf("marshal request: %w", err)
}
url := strings.TrimRight(baseURL, "/") + "/chat/completions"
req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewReader(jsonBody))
if err != nil {
return nil, fmt.Errorf("create request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+apiKey)
client := &http.Client{Timeout: timeout}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("HTTP request: %w", err)
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("read response: %w", err)
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("HTTP %d: %s", resp.StatusCode, truncateStr(string(respBody), 500))
}
// Parse standard OpenAI chat completion response.
var oaiResp struct {
Choices []struct {
Message struct {
Content string `json:"content"`
} `json:"message"`
} `json:"choices"`
Usage *struct {
PromptTokens int `json:"prompt_tokens"`
CompletionTokens int `json:"completion_tokens"`
TotalTokens int `json:"total_tokens"`
} `json:"usage"`
}
if err := json.Unmarshal(respBody, &oaiResp); err != nil {
return nil, fmt.Errorf("parse response: %w", err)
}
if len(oaiResp.Choices) == 0 || oaiResp.Choices[0].Message.Content == "" {
return nil, fmt.Errorf("empty response")
}
chatResp := &providers.ChatResponse{
Content: oaiResp.Choices[0].Message.Content,
FinishReason: "stop",
}
if oaiResp.Usage != nil {
chatResp.Usage = &providers.Usage{
PromptTokens: oaiResp.Usage.PromptTokens,
CompletionTokens: oaiResp.Usage.CompletionTokens,
TotalTokens: oaiResp.Usage.TotalTokens,
}
}
return chatResp, nil
}