Claude API docs: https://docs.anthropic.com/en/api/getting-started
(ctx context.Context, aiSetting *storepb.AISetting, request *v1pb.AICompletionRequest)
| 296 | |
| 297 | // Claude API docs: https://docs.anthropic.com/en/api/getting-started |
| 298 | func callClaude(ctx context.Context, aiSetting *storepb.AISetting, request *v1pb.AICompletionRequest) (*connect.Response[v1pb.AICompletionResponse], error) { |
| 299 | // Convert messages to Claude format |
| 300 | var messages []claudeMessage |
| 301 | for _, m := range request.Messages { |
| 302 | messages = append(messages, claudeMessage{ |
| 303 | Role: m.Role, |
| 304 | Content: m.Content, |
| 305 | }) |
| 306 | } |
| 307 | |
| 308 | payload := claudeRequest{ |
| 309 | Model: aiSetting.Model, |
| 310 | Messages: messages, |
| 311 | MaxTokens: 4096, |
| 312 | Temperature: 0.7, |
| 313 | TopP: 0.95, |
| 314 | TopK: 0, |
| 315 | } |
| 316 | |
| 317 | payloadBytes, err := json.Marshal(payload) |
| 318 | if err != nil { |
| 319 | return nil, errors.Errorf("failed to marshal Claude request payload: %s", err) |
| 320 | } |
| 321 | |
| 322 | httpReq, err := http.NewRequestWithContext(ctx, "POST", aiSetting.Endpoint, bytes.NewBuffer(payloadBytes)) |
| 323 | if err != nil { |
| 324 | return nil, errors.Errorf("failed to create HTTP request: %s", err) |
| 325 | } |
| 326 | |
| 327 | httpReq.Header.Set("Content-Type", "application/json") |
| 328 | httpReq.Header.Set("x-api-key", aiSetting.ApiKey) |
| 329 | // Claude API requires anthropic-version header |
| 330 | if aiSetting.Version != "" { |
| 331 | httpReq.Header.Set("anthropic-version", aiSetting.Version) |
| 332 | } else { |
| 333 | httpReq.Header.Set("anthropic-version", "2023-06-01") |
| 334 | } |
| 335 | |
| 336 | client := &http.Client{} |
| 337 | httpResp, err := client.Do(httpReq) |
| 338 | if err != nil { |
| 339 | return nil, errors.Errorf("failed to send HTTP request: %s", err) |
| 340 | } |
| 341 | defer httpResp.Body.Close() |
| 342 | |
| 343 | body, err := io.ReadAll(httpResp.Body) |
| 344 | if err != nil { |
| 345 | return nil, errors.Errorf("failed to read response body: %s", err) |
| 346 | } |
| 347 | |
| 348 | if httpResp.StatusCode != http.StatusOK { |
| 349 | return nil, errors.Errorf("Claude API returned status %d: %s", httpResp.StatusCode, string(body)) |
| 350 | } |
| 351 | |
| 352 | var claudeResp claudeResponse |
| 353 | if err := json.Unmarshal(body, &claudeResp); err != nil { |
| 354 | return nil, errors.Errorf("failed to unmarshal Claude response: %s", err) |
| 355 | } |