Skip to content

Commit fe05333

Browse files
authored
Merge pull request #26 from fumito-ito/feature/function-calling
Support `Tool Use`
2 parents 13852ad + afc359b commit fe05333

35 files changed

+1670
-52
lines changed

.swiftpm/configuration/Package.resolved

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

Example.swiftpm/.swiftpm/configuration/Package.resolved

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

Example.swiftpm/.swiftpm/xcode/xcshareddata/xcschemes/Example.xcscheme

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@
6161
value = ""
6262
isEnabled = "YES">
6363
</EnvironmentVariable>
64+
<EnvironmentVariable
65+
key = "IDEPreferLogStreaming"
66+
value = "YES"
67+
isEnabled = "YES">
68+
</EnvironmentVariable>
6469
</EnvironmentVariables>
6570
</LaunchAction>
6671
<ProfileAction

Example.swiftpm/FunctionTools.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//
2+
// FunctionTools.swift
3+
// Example
4+
//
5+
// Created by 伊藤史 on 2024/07/23.
6+
//
7+
8+
import Foundation
9+
import FunctionCalling
10+
11+
@FunctionCalling(service: .claude)
12+
struct FunctionTools {
13+
/// Returns the temperature at the location specified by the argument, together with the units.
14+
/// - Parameter location: location to specify the temperature
15+
/// - Returns: the temperature at the location
16+
@CallableFunction
17+
func getWeather(location: String) -> String {
18+
return "32 Celsius"
19+
}
20+
}

Example.swiftpm/Package.resolved

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

Example.swiftpm/Protocol/MessagesSubject.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import Foundation
99
import SwiftUI
1010
import AnthropicSwiftSDK
11+
import FunctionCalling
1112

1213
protocol MessagesSubject {
1314
var messages: [ChatMessage] { get }
@@ -42,7 +43,9 @@ protocol MessageSendable {
4243
stopSequence: [String]?,
4344
temperature: Double?,
4445
topP: Double?,
45-
topK: Int?
46+
topK: Int?,
47+
toolContainer: ToolContainer?,
48+
toolChoice: ToolChoice
4649
) async throws -> MessagesResponse
4750
}
4851

@@ -56,6 +59,8 @@ protocol MessageStreamable {
5659
stopSequence: [String]?,
5760
temperature: Double?,
5861
topP: Double?,
59-
topK: Int?
62+
topK: Int?,
63+
toolContainer: ToolContainer?,
64+
toolChoice: ToolChoice
6065
) async throws -> AsyncThrowingStream<StreamingResponse, Error>
6166
}

Example.swiftpm/ViewModel/MockViewModel.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import Foundation
99
import AnthropicSwiftSDK
10+
import FunctionCalling
1011

1112
@Observable class MockViewModel: StreamMessagesSubject, SendMessagesSubject {
1213
required init(messageHandler: any MessageStreamable, title: String, model: AnthropicSwiftSDK.Model) {
@@ -71,13 +72,13 @@ import AnthropicSwiftSDK
7172
}
7273

7374
struct MockMessageStreamable: MessageStreamable {
74-
func streamMessage(_ messages: [AnthropicSwiftSDK.Message], model: AnthropicSwiftSDK.Model, system: String?, maxTokens: Int, metaData: AnthropicSwiftSDK.MetaData?, stopSequence: [String]?, temperature: Double?, topP: Double?, topK: Int?) async throws -> AsyncThrowingStream<any AnthropicSwiftSDK.StreamingResponse, any Error> {
75+
func streamMessage(_ messages: [AnthropicSwiftSDK.Message], model: AnthropicSwiftSDK.Model, system: String?, maxTokens: Int, metaData: AnthropicSwiftSDK.MetaData?, stopSequence: [String]?, temperature: Double?, topP: Double?, topK: Int?, toolContainer: ToolContainer?, toolChoice: ToolChoice) async throws -> AsyncThrowingStream<any AnthropicSwiftSDK.StreamingResponse, any Error> {
7576
fatalError()
7677
}
7778
}
7879

7980
struct MockMessagesSendable: MessageSendable {
80-
func createMessage(_ messages: [AnthropicSwiftSDK.Message], model: AnthropicSwiftSDK.Model, system: String?, maxTokens: Int, metaData: AnthropicSwiftSDK.MetaData?, stopSequence: [String]?, temperature: Double?, topP: Double?, topK: Int?) async throws -> AnthropicSwiftSDK.MessagesResponse {
81+
func createMessage(_ messages: [AnthropicSwiftSDK.Message], model: AnthropicSwiftSDK.Model, system: String?, maxTokens: Int, metaData: AnthropicSwiftSDK.MetaData?, stopSequence: [String]?, temperature: Double?, topP: Double?, topK: Int?, toolContainer: ToolContainer?, toolChoice: ToolChoice) async throws -> AnthropicSwiftSDK.MessagesResponse {
8182
fatalError()
8283
}
8384
}

Example.swiftpm/ViewModel/SendViewModel.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import AnthropicSwiftSDK
1010

1111
@Observable class SendViewModel: SendMessagesSubject {
1212
private let messageHandler: MessageSendable
13+
private let functionTools = FunctionTools()
1314
let title: String
1415
let model: Model
1516

@@ -49,7 +50,9 @@ import AnthropicSwiftSDK
4950
stopSequence: nil,
5051
temperature: nil,
5152
topP: nil,
52-
topK: nil
53+
topK: nil,
54+
toolContainer: functionTools,
55+
toolChoice: .auto
5356
)
5457

5558
if case let .text(reply) = result.content.first {

Example.swiftpm/ViewModel/StreamViewModel.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import AnthropicSwiftSDK
1010

1111
@Observable class StreamViewModel: StreamMessagesSubject {
1212
private let messageHandler: MessageStreamable
13+
private let functionTools = FunctionTools()
1314
let title: String
1415
let model: Model
1516

@@ -40,7 +41,7 @@ import AnthropicSwiftSDK
4041
task = Task {
4142
do {
4243
isLoading = true
43-
let stream = try await messageHandler.streamMessage(
44+
let stream = try await self.messageHandler.streamMessage(
4445
[message],
4546
model: model,
4647
system: nil,
@@ -49,13 +50,15 @@ import AnthropicSwiftSDK
4950
stopSequence: nil,
5051
temperature: nil,
5152
topP: nil,
52-
topK: nil
53+
topK: nil,
54+
toolContainer: functionTools,
55+
toolChoice: .auto
5356
)
5457
for try await chunk in stream {
5558
switch chunk.type {
5659
case .contentBlockDelta:
5760
if let response = chunk as? StreamingContentBlockDeltaResponse {
58-
messages.append(.init(user: .assistant, text: response.delta.text))
61+
messages.append(.init(user: .assistant, text: response.delta.text ?? ""))
5962
}
6063
default:
6164
break

0 commit comments

Comments
 (0)