-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support anyOf in function parameters #15012
Conversation
- Added support for `anyOf` types in function parameters. - Modified the language model and added new test cases for validation. - Ensures compatibility with MCP servers using `anyOf`, like the official `mcp-server-git`. Fixed #15011
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general the code looks fine for what it does, however it brings up some questions. Please have a look.
if ('type' in record && typeof record.type !== 'string') { | ||
return false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this mandatory? In JSON Schema a type
is also allowed to be an array of strings, allowing multiple types for the same property, e.g. type: ['null', 'string', 'number']
. Not sure how well the LLMs support this.
param1: { | ||
anyOf: [ | ||
{ type: 'string' }, | ||
{ type: 'number' } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also test the case of a more nested structure, e.g. nested anyOf
if (Object.prototype.hasOwnProperty.call(props, key)) { | ||
result[key] = { | ||
type: props[key].type, | ||
description: key | ||
const type = props[key].type; | ||
if (!type) { | ||
// Todo: Should handle anyOf, but this is not supported by the Ollama type yet | ||
} else { | ||
result[key] = { | ||
type: type, | ||
description: key | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we support nested objects for LLMs? In that case this check is not sufficient as an anyOf
could "hide" in a nested property.
const record = obj as Record<string, unknown>; | ||
|
||
// Check that at least one of "type" or "anyOf" exists | ||
if (!('type' in record) && !('anyOf' in record)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is also oneOf
and allOf
commonly used in JSON Schema
const record = obj as Record<string, unknown>; | ||
|
||
// Check that at least one of "type" or "anyOf" exists | ||
if (!('type' in record) && !('anyOf' in record)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that in JSON Schema the type
can be implicit, e.g. if an element specifies properties
then it's automatically of type: 'object'
. If it defines items
then it's automatically of type: 'array'
. I don't know how good LLMs support these specifics.
|
||
export interface ToolRequestParameterProperty { | ||
type?: string; | ||
anyOf?: ToolRequestParameterProperty[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As said in another comment: oneOf
and allOf
are other commonly used constructs in JSON Schema
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works for me, i.e. the createBranch
worked fine.
Still the comments should at least take into consideration for a followup
@sdirix : Thank you for the comments. They all go in the direction of supporting full JSON Schema I believe. I would merge this for now, as it fixes the current issue we are aware of and create a follow-up for after the release. @dhuebner Can you look at this from an Ollama POV? It will not work for anyOf (did not before), but it should also not break something that worked before, |
@JonasHelming |
@dhuebner Quick reminder to ideally have a quick look today (sorry for the additional ping) :-) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JonasHelming
The change seems to not break the previous functionality. One improvement that can be added is using now available required
property in line 231:
required: tool.parameters?.required ?? Object.keys(tool.parameters?.properties ?? {}),
Great thank you! Could you maybe submit this as a separate PR, as I cannot test the change, I would prefer not to commit the change blindly. |
Fixed #15011
What it does
anyOf
types in function parameters.How to test
Follow-ups
We might consider to switch the property type to JSONSchema, as define by openAI, but we already have compatibility issues with Ollama now.
Breaking changes
Attribution
Review checklist
Reminder for reviewers