@@ -3,13 +3,15 @@ import AsyncAlgorithms
33import ChatBasic
44import CodableWrappers
55import Foundation
6+ import JoinJSON
67import Logger
78import Preferences
89
910/// https://docs.anthropic.com/claude/reference/messages_post
1011public actor ClaudeChatCompletionsService : ChatCompletionsStreamAPI , ChatCompletionsAPI {
1112 /// https://docs.anthropic.com/en/docs/about-claude/models
1213 public enum KnownModel : String , CaseIterable {
14+ case claude37Sonnet = " claude-3-7-sonnet-latest "
1315 case claude35Sonnet = " claude-3-5-sonnet-latest "
1416 case claude35Haiku = " claude-3-5-haiku-latest "
1517 case claude3Opus = " claude-3-opus-latest "
@@ -23,6 +25,7 @@ public actor ClaudeChatCompletionsService: ChatCompletionsStreamAPI, ChatComplet
2325 case . claude3Opus: return 200_000
2426 case . claude3Sonnet: return 200_000
2527 case . claude3Haiku: return 200_000
28+ case . claude37Sonnet: return 200_000
2629 }
2730 }
2831 }
@@ -232,6 +235,8 @@ public actor ClaudeChatCompletionsService: ChatCompletionsStreamAPI, ChatComplet
232235 if !apiKey. isEmpty {
233236 request. setValue ( apiKey, forHTTPHeaderField: " x-api-key " )
234237 }
238+ Self . setupCustomBody ( & request, model: model)
239+ await Self . setupExtraHeaderFields ( & request, model: model, apiKey: apiKey)
235240
236241 let ( result, response) = try await URLSession . shared. bytes ( for: request)
237242 guard let response = response as? HTTPURLResponse else {
@@ -295,6 +300,8 @@ public actor ClaudeChatCompletionsService: ChatCompletionsStreamAPI, ChatComplet
295300 if !apiKey. isEmpty {
296301 request. setValue ( apiKey, forHTTPHeaderField: " x-api-key " )
297302 }
303+ Self . setupCustomBody ( & request, model: model)
304+ await Self . setupExtraHeaderFields ( & request, model: model, apiKey: apiKey)
298305
299306 let ( result, response) = try await URLSession . shared. data ( for: request)
300307 guard let response = response as? HTTPURLResponse else {
@@ -315,6 +322,15 @@ public actor ClaudeChatCompletionsService: ChatCompletionsStreamAPI, ChatComplet
315322 throw error
316323 }
317324 }
325+
326+ static func setupCustomBody( _ request: inout URLRequest , model: ChatModel ) {
327+ let join = JoinJSON ( )
328+ let jsonBody = model. info. customBodyInfo. jsonBody
329+ . trimmingCharacters ( in: . whitespacesAndNewlines)
330+ guard let data = request. httpBody, !jsonBody. isEmpty else { return }
331+ let newBody = join. join ( data, with: jsonBody)
332+ request. httpBody = newBody
333+ }
318334}
319335
320336extension ClaudeChatCompletionsService . ResponseBody {
@@ -453,7 +469,7 @@ extension ClaudeChatCompletionsService.RequestBody {
453469 data: image. data. base64EncodedString ( )
454470 ) ) )
455471 }
456-
472+
457473 return content
458474 }
459475
0 commit comments