Skip to content

Commit ad2cb1a

Browse files
airy10mattt
andauthored
OpenAILanguageModel + SystemLanguageModel tools calling support (#49)
* Add basic support for proper tool support response to OpenAILanguageModel * Add support for Tool calling with Apple models * Add "description" support for the tools parameters * Fix ALM->FoundationModels schema conversion + empty "description" of converted DynamicGenerationSchema Property * Fix function calling for both Chat Completion and Responses - Add the call message to the messages list Tested with opencode.ai/zen/v1 (Chat and Responses) and generativelanguage.googleapis.com/v1beta/openai (Chat only) * Update Sources/AnyLanguageModel/Models/OpenAILanguageModel.swift Co-authored-by: Mattt <mattt@me.com> * Update Sources/AnyLanguageModel/Models/OpenAILanguageModel.swift Co-authored-by: Mattt <mattt@me.com> * Switch to using JSONSchema to convert tools schemas to FoundationModels format * Fix compiler warnings * swift format -i --recursive . * Fix OpenAI withTools() test failure Invalid type for 'input[2].output': expected one of a string or array of objects, but got an object instead. * Fix OpenAI tool calling logic and tests * Refactor dynamic schema convesion to be top-level functions * Change AnyToolWrapper APIs to be nonpublic * Refactor call(arguments:) and make it nonpublic * Make callFunction fileprivate * Remove unused, private SystemLanguageModelError * Add test coverage of dynamic schema conversion --------- Co-authored-by: Mattt <mattt@me.com>
1 parent 4c204c0 commit ad2cb1a

File tree

6 files changed

+898
-148
lines changed

6 files changed

+898
-148
lines changed

Sources/AnyLanguageModel/GenerationSchema.swift

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -408,14 +408,15 @@ public struct GenerationSchema: Sendable, Codable, CustomDebugStringConvertible
408408
private static func convertDynamic(
409409
_ dynamic: DynamicGenerationSchema,
410410
nameMap: [String: DynamicGenerationSchema],
411-
defs: inout [String: Node]
411+
defs: inout [String: Node],
412+
dynamicProp: DynamicGenerationSchema.Property? = nil
412413
) throws -> Node {
413414
switch dynamic.body {
414415
case .object(let name, let desc, let properties):
415416
var props: [String: Node] = [:]
416417
var required: Set<String> = []
417418
for prop in properties {
418-
props[prop.name] = try convertDynamic(prop.schema, nameMap: nameMap, defs: &defs)
419+
props[prop.name] = try convertDynamic(prop.schema, nameMap: nameMap, defs: &defs, dynamicProp: prop)
419420
if !prop.isOptional {
420421
required.insert(prop.name)
421422
}
@@ -452,20 +453,28 @@ public struct GenerationSchema: Sendable, Codable, CustomDebugStringConvertible
452453

453454
case .array(let item, let min, let max):
454455
let itemNode = try convertDynamic(item, nameMap: nameMap, defs: &defs)
455-
return .array(ArrayNode(description: nil, items: itemNode, minItems: min, maxItems: max))
456+
return .array(
457+
ArrayNode(description: dynamicProp?.description, items: itemNode, minItems: min, maxItems: max)
458+
)
456459

457460
case .scalar(let scalar):
458461
switch scalar {
459462
case .bool:
460463
return .boolean
461464
case .string:
462-
return .string(StringNode(description: nil, pattern: nil, enumChoices: nil))
465+
return .string(StringNode(description: dynamicProp?.description, pattern: nil, enumChoices: nil))
463466
case .number:
464-
return .number(NumberNode(description: nil, minimum: nil, maximum: nil, integerOnly: false))
467+
return .number(
468+
NumberNode(description: dynamicProp?.description, minimum: nil, maximum: nil, integerOnly: false)
469+
)
465470
case .integer:
466-
return .number(NumberNode(description: nil, minimum: nil, maximum: nil, integerOnly: true))
471+
return .number(
472+
NumberNode(description: dynamicProp?.description, minimum: nil, maximum: nil, integerOnly: true)
473+
)
467474
case .decimal:
468-
return .number(NumberNode(description: nil, minimum: nil, maximum: nil, integerOnly: false))
475+
return .number(
476+
NumberNode(description: dynamicProp?.description, minimum: nil, maximum: nil, integerOnly: false)
477+
)
469478
}
470479

471480
case .reference(let name):

0 commit comments

Comments
 (0)