Skip to content

Commit cfab455

Browse files
committed
remove dependency for FunctionCalling
1 parent 4efab18 commit cfab455

File tree

7 files changed

+17
-319
lines changed

7 files changed

+17
-319
lines changed

Package.resolved

Lines changed: 0 additions & 54 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ let package = Package(
1616
targets: ["AnthropicSwiftSDK"]),
1717
],
1818
dependencies: [
19-
.package(url: "https://github.com/fumito-ito/FunctionCalling", from: "0.4.0"),
2019
.package(url: "https://github.com/fumito-ito/SwiftyJSONLines.git", from: "0.0.3")
2120
],
2221
targets: [
@@ -25,7 +24,6 @@ let package = Package(
2524
.target(
2625
name: "AnthropicSwiftSDK",
2726
dependencies: [
28-
.product(name: "FunctionCalling", package: "FunctionCalling"),
2927
.product(name: "SwiftyJSONLines", package: "SwiftyJSONLines")
3028
]
3129
),

Sources/AnthropicSwiftSDK/Entity/Batch/BatchParameter.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public struct BatchParameter {
3838
/// Only sample from the top K options for each subsequent token.
3939
public let topK: Int?
4040
/// Definitions of tools that the model may use.
41-
public let toolContainer: ToolContainer?
41+
public let tools: [Tool]?
4242
/// How the model should use the provided tools. The model can use a specific tool, any available tool, or decide by itself.
4343
public let toolChoice: ToolChoice
4444

@@ -52,7 +52,7 @@ public struct BatchParameter {
5252
temperature: Double? = nil,
5353
topP: Double? = nil,
5454
topK: Int? = nil,
55-
toolContainer: ToolContainer? = nil,
55+
tools: [Tool]? = nil,
5656
toolChoice: ToolChoice = .auto
5757
) {
5858
self.messages = messages
@@ -64,7 +64,7 @@ public struct BatchParameter {
6464
self.temperature = temperature
6565
self.topP = topP
6666
self.topK = topK
67-
self.toolContainer = toolContainer
67+
self.tools = tools
6868
self.toolChoice = toolChoice
6969
}
7070
}

Sources/AnthropicSwiftSDK/Messages.swift

Lines changed: 10 additions & 199 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,9 @@
55
// Created by Fumito Ito on 2024/03/17.
66
//
77

8-
// swiftlint:disable file_length
9-
108
import Foundation
119
import FunctionCalling
1210

13-
// swiftlint:disable:next type_body_length
1411
public struct Messages {
1512
private let apiKey: String
1613
private let session: URLSession
@@ -46,7 +43,7 @@ public struct Messages {
4643
temperature: Double? = nil,
4744
topP: Double? = nil,
4845
topK: Int? = nil,
49-
toolContainer: ToolContainer? = nil,
46+
tools: [Tool]? = nil,
5047
toolChoice: ToolChoice = .auto
5148
) async throws -> MessagesResponse {
5249
try await createMessage(
@@ -59,7 +56,7 @@ public struct Messages {
5956
temperature: temperature,
6057
topP: topP,
6158
topK: topK,
62-
toolContainer: toolContainer,
59+
tools: tools,
6360
toolChoice: toolChoice,
6461
anthropicHeaderProvider: DefaultAnthropicHeaderProvider(),
6562
authenticationHeaderProvider: APIKeyAuthenticationHeaderProvider(apiKey: apiKey)
@@ -94,7 +91,7 @@ public struct Messages {
9491
temperature: Double? = nil,
9592
topP: Double? = nil,
9693
topK: Int? = nil,
97-
toolContainer: ToolContainer? = nil,
94+
tools: [Tool]? = nil,
9895
toolChoice: ToolChoice = .auto,
9996
anthropicHeaderProvider: AnthropicHeaderProvider,
10097
authenticationHeaderProvider: AuthenticationHeaderProvider
@@ -117,7 +114,7 @@ public struct Messages {
117114
temperature: temperature,
118115
topP: topP,
119116
topK: topK,
120-
tools: toolContainer?.allTools,
117+
tools: tools,
121118
toolChoice: toolChoice
122119
)
123120
)
@@ -132,95 +129,7 @@ public struct Messages {
132129
throw AnthropicAPIError(fromHttpStatusCode: httpResponse.statusCode)
133130
}
134131

135-
let result = try anthropicJSONDecoder.decode(MessagesResponse.self, from: data)
136-
137-
guard case .toolUse = result.stopReason else {
138-
return result
139-
}
140-
141-
return try await sendToolResult(
142-
forToolUseRequest: result,
143-
priviousMessages: messages,
144-
model: model,
145-
system: system,
146-
maxTokens: maxTokens,
147-
metaData: metaData,
148-
stopSequence: stopSequence,
149-
temperature: temperature,
150-
topP: topP,
151-
topK: topK,
152-
toolContainer: toolContainer,
153-
toolChoice: toolChoice,
154-
anthropicHeaderProvider: anthropicHeaderProvider,
155-
authenticationHeaderProvider: authenticationHeaderProvider
156-
)
157-
}
158-
159-
/// Return the result of tool execution back to the model as a user message
160-
///
161-
/// - Parameters:
162-
/// - toolUseRequest: Message response from API to execute tools with arguments.
163-
/// - messages: An array of Message objects representing the input prompt for message generation.
164-
/// - model: The model to be used for generating the message. Default is `.claude_3_Opus`.
165-
/// - system: The system identifier. Default is `nil`.
166-
/// - maxTokens: The maximum number of tokens in the generated message.
167-
/// - metaData: Additional metadata for the request. Default is `nil`.
168-
/// - stopSequence: An array of strings representing sequences where the message generation should stop.
169-
/// - temperature: The temperature parameter controls the randomness of the generated text. Default is `nil`.
170-
/// - topP: The nucleus sampling parameter. Default is `nil`.
171-
/// - topK: The top-k sampling parameter. Default is `nil`.
172-
/// - toolContainer: The tool provider for `tool_use`. Default is `nil`
173-
/// - toolChoice: The parameter for tool choice. Default is `.auto`
174-
/// - anthropicHeaderProvider: The provider for the anthropic header NOT required for API authentication.
175-
/// - authenticationHeaderProvider: The provider for the authentication header required for API authentication.
176-
/// - Returns: A `MessagesResponse` object representing the response from the Anthropic API.
177-
/// - Throws: An error if the request fails or if there's an issue decoding the response.
178-
func sendToolResult(
179-
forToolUseRequest toolUseRequest: MessagesResponse,
180-
priviousMessages messages: [Message],
181-
model: Model = .claude_3_Opus,
182-
system: [SystemPrompt] = [],
183-
maxTokens: Int,
184-
metaData: MetaData? = nil,
185-
stopSequence: [String]? = nil,
186-
temperature: Double? = nil,
187-
topP: Double? = nil,
188-
topK: Int? = nil,
189-
toolContainer: ToolContainer? = nil,
190-
toolChoice: ToolChoice = .auto,
191-
anthropicHeaderProvider: AnthropicHeaderProvider,
192-
authenticationHeaderProvider: AuthenticationHeaderProvider
193-
) async throws -> MessagesResponse {
194-
// If a `tool_use` response is returned with no `ToolContainer` specified, `tool_use_result` cannot be returned because any tool does not exist.
195-
guard let toolContainer else {
196-
throw ClientError.anyToolsAreDefined
197-
}
198-
199-
guard case .toolUse(let toolUseContent) = toolUseRequest.content.first(where: { $0.contentType == .toolUse }) else {
200-
throw ClientError.cannotFindToolUseContentFromResponse(toolUseRequest)
201-
}
202-
203-
let toolResult = await toolContainer.execute(methodName: toolUseContent.name, parameters: toolUseContent.input)
204-
let toolResultRequest = messages + [
205-
.init(role: .assistant, content: [.toolUse(toolUseContent)]),
206-
.init(role: .user, content: [.toolResult(.init(toolUseId: toolUseContent.id, content: [.text(toolResult)], isError: nil))])
207-
]
208-
209-
return try await createMessage(
210-
toolResultRequest,
211-
model: model,
212-
system: system,
213-
maxTokens: maxTokens,
214-
metaData: metaData,
215-
stopSequence: stopSequence,
216-
temperature: temperature,
217-
topP: topP,
218-
topK: topK,
219-
toolContainer: toolContainer,
220-
toolChoice: toolChoice,
221-
anthropicHeaderProvider: anthropicHeaderProvider,
222-
authenticationHeaderProvider: authenticationHeaderProvider
223-
)
132+
return try anthropicJSONDecoder.decode(MessagesResponse.self, from: data)
224133
}
225134

226135
/// Streams messages using the specified parameters and sends a request to the Anthropic API asynchronously.
@@ -249,7 +158,7 @@ public struct Messages {
249158
temperature: Double? = nil,
250159
topP: Double? = nil,
251160
topK: Int? = nil,
252-
toolContainer: ToolContainer? = nil,
161+
tools: [Tool]? = nil,
253162
toolChoice: ToolChoice = .auto
254163
) async throws -> AsyncThrowingStream<StreamingResponse, Error> {
255164
try await streamMessage(
@@ -262,7 +171,7 @@ public struct Messages {
262171
temperature: temperature,
263172
topP: topP,
264173
topK: topK,
265-
toolContainer: toolContainer,
174+
tools: tools,
266175
toolChoice: toolChoice,
267176
anthropicHeaderProvider: DefaultAnthropicHeaderProvider(),
268177
authenticationHeaderProvider: APIKeyAuthenticationHeaderProvider(apiKey: apiKey)
@@ -297,7 +206,7 @@ public struct Messages {
297206
temperature: Double? = nil,
298207
topP: Double? = nil,
299208
topK: Int? = nil,
300-
toolContainer: ToolContainer? = nil,
209+
tools: [Tool]? = nil,
301210
toolChoice: ToolChoice = .auto,
302211
anthropicHeaderProvider: AnthropicHeaderProvider,
303212
authenticationHeaderProvider: AuthenticationHeaderProvider
@@ -320,7 +229,7 @@ public struct Messages {
320229
temperature: temperature,
321230
topP: topP,
322231
topK: topK,
323-
tools: toolContainer?.allTools,
232+
tools: tools,
324233
toolChoice: toolChoice
325234
)
326235
)
@@ -335,104 +244,6 @@ public struct Messages {
335244
throw AnthropicAPIError(fromHttpStatusCode: httpResponse.statusCode)
336245
}
337246

338-
return resendStreamMessageIfClaudeRequestsToolUse(
339-
try await AnthropicStreamingParser.parse(stream: data.lines).accumulated(),
340-
messages: messages,
341-
model: model,
342-
system: system,
343-
maxTokens: maxTokens,
344-
metaData: metaData,
345-
stopSequence: stopSequence,
346-
temperature: temperature,
347-
topP: topP,
348-
topK: topK,
349-
toolContainer: toolContainer,
350-
toolChoice: toolChoice,
351-
anthropicHeaderProvider: anthropicHeaderProvider,
352-
authenticationHeaderProvider: authenticationHeaderProvider
353-
)
354-
}
355-
356-
/// Receive response from Claude in Stream format.
357-
///
358-
/// If there is a response related to `tool_use`, the information is compiled and streamed.
359-
///
360-
/// - Parameters:
361-
/// - stream: response stream from Claude Stream API
362-
/// - messages: An array of Message objects representing the input prompt for message generation.
363-
/// - model: The model to be used for generating the message. Default is `.claude_3_Opus`.
364-
/// - system: The system identifier. Default is `nil`.
365-
/// - maxTokens: The maximum number of tokens in the generated message.
366-
/// - metaData: Additional metadata for the request. Default is `nil`.
367-
/// - stopSequence: An array of strings representing sequences where the message generation should stop.
368-
/// - temperature: The temperature parameter controls the randomness of the generated text. Default is `nil`.
369-
/// - topP: The nucleus sampling parameter. Default is `nil`.
370-
/// - topK: The top-k sampling parameter. Default is `nil`.
371-
/// - toolContainer: The tool provider for `tool_use`. Default is `nil`
372-
/// - toolChoice: The parameter for tool choice. Default is `.auto`
373-
/// - anthropicHeaderProvider: The provider for the anthropic header NOT required for API authentication.
374-
/// - authenticationHeaderProvider: The provider for the authentication header required for API authentication.
375-
/// - Returns: Claude Stream API response stream. If `stream` returns `tool_use` content, this method returns re-request new stream.
376-
// swiftlint:disable:next function_parameter_count
377-
func resendStreamMessageIfClaudeRequestsToolUse(
378-
_ stream: AsyncThrowingStream<StreamingResponse, Error>,
379-
messages: [Message],
380-
model: Model,
381-
system: [SystemPrompt] = [],
382-
maxTokens: Int,
383-
metaData: MetaData?,
384-
stopSequence: [String]?,
385-
temperature: Double?,
386-
topP: Double?,
387-
topK: Int?,
388-
toolContainer: ToolContainer?,
389-
toolChoice: ToolChoice,
390-
anthropicHeaderProvider: AnthropicHeaderProvider,
391-
authenticationHeaderProvider: AuthenticationHeaderProvider
392-
) -> AsyncThrowingStream<StreamingResponse, Error> {
393-
AsyncThrowingStream { continuation in
394-
Task {
395-
do {
396-
for try await response in stream {
397-
if
398-
let toolContainer,
399-
let deltaResponse = response as? StreamingMessageDeltaResponse,
400-
let toolUseContent = deltaResponse.toolUseContent,
401-
let toolResultContent = await deltaResponse.getToolResultContent(from: toolContainer),
402-
response.isToolUse {
403-
let streamWithToolResult = try await streamMessage(
404-
messages + [
405-
.init(role: .assistant, content: [.toolUse(toolUseContent)]),
406-
.init(role: .user, content: [toolResultContent])
407-
],
408-
model: model,
409-
system: system,
410-
maxTokens: maxTokens,
411-
metaData: metaData,
412-
stopSequence: stopSequence,
413-
temperature: temperature,
414-
topP: topP,
415-
topK: topK,
416-
toolContainer: toolContainer,
417-
toolChoice: toolChoice,
418-
anthropicHeaderProvider: anthropicHeaderProvider,
419-
authenticationHeaderProvider: authenticationHeaderProvider
420-
)
421-
422-
for try await responseWithToolResult in streamWithToolResult {
423-
continuation.yield(responseWithToolResult)
424-
}
425-
} else {
426-
continuation.yield(response)
427-
}
428-
}
429-
continuation.finish()
430-
} catch {
431-
continuation.finish(throwing: error)
432-
}
433-
}
434-
}
247+
return try await AnthropicStreamingParser.parse(stream: data.lines).accumulated()
435248
}
436249
}
437-
438-
// swiftlint:enable file_length

0 commit comments

Comments
 (0)