Skip to content

Commit 3eaa04d

Browse files
authored
[Vertex AI] Refactor function calling APIs (#13873)
1 parent 063b3ce commit 3eaa04d

File tree

4 files changed

+67
-53
lines changed

4 files changed

+67
-53
lines changed

FirebaseVertexAI/CHANGELOG.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
renamed to `inlineData`; no functionality changes. (#13700)
1616
- [changed] **Breaking Change**: The property `citationSources` of
1717
`CitationMetadata` has been renamed to `citations`. (#13702)
18-
- [changed] **Breaking Change**: The constructor for `Schema` is now internal;
19-
use the new static methods `Schema.string(...)`, `Schema.object(...)`, etc.,
18+
- [changed] **Breaking Change**: The initializer for `Schema` is now internal;
19+
use the new type methods `Schema.string(...)`, `Schema.object(...)`, etc.,
2020
instead. (#13852)
21-
- [changed] **Breaking Change**: The constructor for `FunctionDeclaration` now
21+
- [changed] **Breaking Change**: The initializer for `FunctionDeclaration` now
2222
accepts an array of *optional* parameters instead of a list of *required*
2323
parameters; if a parameter is not listed as optional it is assumed to be
2424
required. (#13616)
@@ -44,6 +44,12 @@
4444
`FinishReason` are now structs instead of enums types and the `unknown` cases
4545
have been removed; in a `switch` statement, use the `default:` case to cover
4646
unknown or unhandled values. (#13728, #13854, #13860)
47+
- [changed] **Breaking Change**: The `Tool` initializer is now internal; use the
48+
new type method `functionDeclarations(_:)` to create a `Tool` for function
49+
calling. (#13873)
50+
- [changed] **Breaking Change**: The `FunctionCallingConfig` initializer and
51+
`Mode` enum are now internal; use one of the new type methods `auto()`,
52+
`any(allowedFunctionNames:)`, or `none()` to create a config. (#13873)
4753
- [changed] The default request timeout is now 180 seconds instead of the
4854
platform-default value of 60 seconds for a `URLRequest`; this timeout may
4955
still be customized in `RequestOptions`. (#13722)

FirebaseVertexAI/Sample/FunctionCallingSample/ViewModels/FunctionCallingViewModel.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class FunctionCallingViewModel: ObservableObject {
4040
init() {
4141
model = VertexAI.vertexAI().generativeModel(
4242
modelName: "gemini-1.5-flash",
43-
tools: [Tool(functionDeclarations: [
43+
tools: [.functionDeclarations([
4444
FunctionDeclaration(
4545
name: "get_exchange_rate",
4646
description: "Get the exchange rate for currencies between countries",

FirebaseVertexAI/Sources/FunctionCalling.swift

Lines changed: 53 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public struct FunctionDeclaration {
2525
/// A brief description of the function.
2626
let description: String
2727

28-
/// Describes the parameters to this function; must be of type ``DataType/object``.
28+
/// Describes the parameters to this function; must be of type `DataType.object`.
2929
let parameters: Schema?
3030

3131
/// Constructs a new `FunctionDeclaration`.
@@ -47,55 +47,49 @@ public struct FunctionDeclaration {
4747
}
4848
}
4949

50-
/// Helper tools that the model may use to generate response.
50+
/// A helper tool that the model may use when generating responses.
5151
///
52-
/// A `Tool` is a piece of code that enables the system to interact with external systems to
53-
/// perform an action, or set of actions, outside of knowledge and scope of the model.
52+
/// A `Tool` is a piece of code that enables the system to interact with external systems to perform
53+
/// an action, or set of actions, outside of knowledge and scope of the model.
5454
public struct Tool {
5555
/// A list of `FunctionDeclarations` available to the model.
5656
let functionDeclarations: [FunctionDeclaration]?
5757

58-
/// Constructs a new `Tool`.
58+
init(functionDeclarations: [FunctionDeclaration]?) {
59+
self.functionDeclarations = functionDeclarations
60+
}
61+
62+
/// Creates a tool that allows the model to perform function calling.
63+
///
64+
/// Function calling can be used to provide data to the model that was not known at the time it
65+
/// was trained (for example, the current date or weather conditions) or to allow it to interact
66+
/// with external systems (for example, making an API request or querying/updating a database).
67+
/// For more details and use cases, see [Introduction to function
68+
/// calling](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling).
5969
///
6070
/// - Parameters:
6171
/// - functionDeclarations: A list of `FunctionDeclarations` available to the model that can be
6272
/// used for function calling.
6373
/// The model or system does not execute the function. Instead the defined function may be
64-
/// returned as a ``FunctionCall`` in ``ModelContent/Part/functionCall(_:)`` with arguments to
65-
/// the client side for execution. The model may decide to call a subset of these functions by
66-
/// populating ``FunctionCall`` in the response. The next conversation turn may contain a
67-
/// ``FunctionResponse`` in ``ModelContent/Part/functionResponse(_:)`` with the
68-
/// ``ModelContent/role`` "function", providing generation context for the next model turn.
69-
public init(functionDeclarations: [FunctionDeclaration]?) {
70-
self.functionDeclarations = functionDeclarations
74+
/// returned as a ``FunctionCallPart`` with arguments to the client side for execution. The
75+
/// model may decide to call none, some or all of the declared functions; this behavior may be
76+
/// configured by specifying a ``ToolConfig`` when instantiating the model. When a
77+
/// ``FunctionCallPart`` is received, the next conversation turn may contain a
78+
/// ``FunctionResponsePart`` in ``ModelContent/parts`` with a ``ModelContent/role`` of
79+
/// `"function"`; this response contains the result of executing the function on the client,
80+
/// providing generation context for the model's next turn.
81+
public static func functionDeclarations(_ functionDeclarations: [FunctionDeclaration]) -> Tool {
82+
return self.init(functionDeclarations: functionDeclarations)
7183
}
7284
}
7385

7486
/// Configuration for specifying function calling behavior.
7587
public struct FunctionCallingConfig {
7688
/// Defines the execution behavior for function calling by defining the execution mode.
77-
public struct Mode: EncodableProtoEnum {
78-
enum Kind: String {
79-
case auto = "AUTO"
80-
case any = "ANY"
81-
case none = "NONE"
82-
}
83-
84-
/// The default behavior for function calling.
85-
///
86-
/// The model calls functions to answer queries at its discretion.
87-
public static let auto = Mode(kind: .auto)
88-
89-
/// The model always predicts a provided function call to answer every query.
90-
public static let any = Mode(kind: .any)
91-
92-
/// The model will never predict a function call to answer a query.
93-
///
94-
/// > Note: This can also be achieved by not passing any ``FunctionDeclaration`` tools
95-
/// > when instantiating the model.
96-
public static let none = Mode(kind: .none)
97-
98-
let rawValue: String
89+
enum Mode: String {
90+
case auto = "AUTO"
91+
case any = "ANY"
92+
case none = "NONE"
9993
}
10094

10195
/// Specifies the mode in which function calling should execute.
@@ -104,20 +98,34 @@ public struct FunctionCallingConfig {
10498
/// A set of function names that, when provided, limits the functions the model will call.
10599
let allowedFunctionNames: [String]?
106100

107-
/// Creates a new `FunctionCallingConfig`.
108-
///
109-
/// - Parameters:
110-
/// - mode: Specifies the mode in which function calling should execute; if unspecified, the
111-
/// default behavior will be ``Mode/auto``.
112-
/// - allowedFunctionNames: A set of function names that, when provided, limits the functions
113-
/// the model will call.
114-
/// Note: This should only be set when the ``Mode`` is ``Mode/any``. Function names should match
115-
/// `[FunctionDeclaration.name]`. With mode set to ``Mode/any``, the model will predict a
116-
/// function call from the set of function names provided.
117-
public init(mode: FunctionCallingConfig.Mode? = nil, allowedFunctionNames: [String]? = nil) {
101+
init(mode: FunctionCallingConfig.Mode? = nil, allowedFunctionNames: [String]? = nil) {
118102
self.mode = mode
119103
self.allowedFunctionNames = allowedFunctionNames
120104
}
105+
106+
/// Creates a function calling config where the model calls functions at its discretion.
107+
///
108+
/// > Note: This is the default behavior.
109+
public static func auto() -> FunctionCallingConfig {
110+
return FunctionCallingConfig(mode: .auto)
111+
}
112+
113+
/// Creates a function calling config where the model will always call a provided function.
114+
///
115+
/// - Parameters:
116+
/// - allowedFunctionNames: A set of function names that, when provided, limits the functions
117+
/// that the model will call.
118+
public static func any(allowedFunctionNames: [String]? = nil) -> FunctionCallingConfig {
119+
return FunctionCallingConfig(mode: .any, allowedFunctionNames: allowedFunctionNames)
120+
}
121+
122+
/// Creates a function calling config where the model will never call a function.
123+
///
124+
/// > Note: This can also be achieved by not passing any ``FunctionDeclaration`` tools when
125+
/// > instantiating the model.
126+
public static func none() -> FunctionCallingConfig {
127+
return FunctionCallingConfig(mode: FunctionCallingConfig.Mode.none)
128+
}
121129
}
122130

123131
/// Tool configuration for any `Tool` specified in the request.

FirebaseVertexAI/Tests/Integration/IntegrationTests.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ final class IntegrationTests: XCTestCase {
5959
generationConfig: generationConfig,
6060
safetySettings: safetySettings,
6161
tools: [],
62-
toolConfig: .init(functionCallingConfig: .init(mode: FunctionCallingConfig.Mode.none)),
62+
toolConfig: .init(functionCallingConfig: .none()),
6363
systemInstruction: systemInstruction
6464
)
6565
}
@@ -95,7 +95,7 @@ final class IntegrationTests: XCTestCase {
9595
SafetySetting(harmCategory: .dangerousContent, threshold: .blockNone),
9696
SafetySetting(harmCategory: .civicIntegrity, threshold: .off),
9797
],
98-
toolConfig: .init(functionCallingConfig: .init(mode: .auto)),
98+
toolConfig: .init(functionCallingConfig: .auto()),
9999
systemInstruction: systemInstruction
100100
)
101101

@@ -137,8 +137,8 @@ final class IntegrationTests: XCTestCase {
137137
)
138138
model = vertex.generativeModel(
139139
modelName: "gemini-1.5-flash",
140-
tools: [Tool(functionDeclarations: [sumDeclaration])],
141-
toolConfig: .init(functionCallingConfig: .init(mode: .any, allowedFunctionNames: ["sum"]))
140+
tools: [.functionDeclarations([sumDeclaration])],
141+
toolConfig: .init(functionCallingConfig: .any(allowedFunctionNames: ["sum"]))
142142
)
143143
let prompt = "What is 10 + 32?"
144144
let sumCall = FunctionCallPart(name: "sum", args: ["x": .number(10), "y": .number(32)])

0 commit comments

Comments
 (0)