@@ -41,8 +41,8 @@ public struct AnthropicLanguageModel: LanguageModel {
4141 /// The base URL for the API endpoint.
4242 public let baseURL : URL
4343
44- /// The API key for authentication.
45- public let apiKey : String
44+ /// The closure providing the API key for authentication.
45+ private let tokenProvider : @ Sendable ( ) -> String
4646
4747 /// The API version to use for requests.
4848 public let apiVersion : String
@@ -54,20 +54,19 @@ public struct AnthropicLanguageModel: LanguageModel {
5454 public let model : String
5555
5656 private let urlSession : URLSession
57- private let headers : [ String : String ]
5857
5958 /// Creates an Anthropic language model.
6059 ///
6160 /// - Parameters:
6261 /// - baseURL: The base URL for the API endpoint. Defaults to Anthropic's official API.
63- /// - apiKey: Your Anthropic API key.
62+ /// - apiKey: Your Anthropic API key or a closure that returns it .
6463 /// - apiVersion: The API version to use for requests. Defaults to `2023-06-01`.
6564 /// - betas: Optional beta version(s) of the API to use.
6665 /// - model: The model identifier (for example, "claude-3-5-sonnet-20241022").
6766 /// - session: The URL session to use for network requests.
6867 public init (
6968 baseURL: URL = defaultBaseURL,
70- apiKey: String ,
69+ apiKey tokenProvider : @escaping @autoclosure @ Sendable ( ) -> String ,
7170 apiVersion: String = defaultAPIVersion,
7271 betas: [ String ] ? = nil ,
7372 model: String ,
@@ -79,22 +78,11 @@ public struct AnthropicLanguageModel: LanguageModel {
7978 }
8079
8180 self . baseURL = baseURL
82- self . apiKey = apiKey
81+ self . tokenProvider = tokenProvider
8382 self . apiVersion = apiVersion
8483 self . betas = betas
8584 self . model = model
8685 self . urlSession = session
87-
88- var headers : [ String : String ] = [
89- " x-api-key " : apiKey,
90- " anthropic-version " : apiVersion,
91- ]
92-
93- if let betas = betas, !betas. isEmpty {
94- headers [ " anthropic-beta " ] = betas. joined ( separator: " , " )
95- }
96-
97- self . headers = headers
9886 }
9987
10088 public func respond< Content> (
@@ -109,6 +97,9 @@ public struct AnthropicLanguageModel: LanguageModel {
10997 fatalError ( " AnthropicLanguageModel only supports generating String content " )
11098 }
11199
100+ let url = baseURL. appendingPathComponent ( " v1/messages " )
101+ let headers = buildHeaders ( )
102+
112103 let messages = [
113104 AnthropicMessage ( role: . user, content: [ . text( . init( text: prompt. description) ) ] )
114105 ]
@@ -126,8 +117,8 @@ public struct AnthropicLanguageModel: LanguageModel {
126117 options: options
127118 )
128119
129- let url = baseURL. appendingPathComponent ( " v1/messages " )
130120 let body = try JSONEncoder ( ) . encode ( params)
121+
131122 let message : AnthropicMessageResponse = try await urlSession. fetch (
132123 . post,
133124 url: url,
@@ -189,6 +180,8 @@ public struct AnthropicLanguageModel: LanguageModel {
189180 continuation in
190181 let task = Task { @Sendable in
191182 do {
183+ let headers = buildHeaders ( )
184+
192185 // Convert available tools to Anthropic format
193186 let anthropicTools : [ AnthropicTool ] = try session. tools. map { tool in
194187 try convertToolToAnthropicFormat ( tool)
@@ -247,6 +240,19 @@ public struct AnthropicLanguageModel: LanguageModel {
247240
248241 return LanguageModelSession . ResponseStream ( stream: stream)
249242 }
243+
244+ private func buildHeaders( ) -> [ String : String ] {
245+ var headers : [ String : String ] = [
246+ " x-api-key " : tokenProvider ( ) ,
247+ " anthropic-version " : apiVersion,
248+ ]
249+
250+ if let betas = betas, !betas. isEmpty {
251+ headers [ " anthropic-beta " ] = betas. joined ( separator: " , " )
252+ }
253+
254+ return headers
255+ }
250256}
251257
252258// MARK: - Conversions
0 commit comments