Skip to content
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

Merged
merged 1 commit into from
Feb 26, 2025
Merged

Support anyOf in function parameters #15012

merged 1 commit into from
Feb 26, 2025

Conversation

JonasHelming
Copy link
Contributor

Fixed #15011

What it does

  • Added support for anyOf types in function parameters.
  • Added new test cases for validation.
  • Ignore anyOf properties in Ollama, as they are not supported by their Schema

How to test

  • Use functions in general
  • Use the "createBranch" function of the MCP Git server

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

  • This PR introduces breaking changes and requires careful review. If yes, the breaking changes section in the changelog has been updated.

Attribution

Review checklist

Reminder for reviewers

- 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
Copy link
Member

@sdirix sdirix left a 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.

Comment on lines +80 to +82
if ('type' in record && typeof record.type !== 'string') {
return false;
}
Copy link
Member

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' }
Copy link
Member

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

Comment on lines 210 to +218
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
};
Copy link
Member

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)) {
Copy link
Member

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)) {
Copy link
Member

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[];
Copy link
Member

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

Copy link
Member

@sdirix sdirix left a 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

@JonasHelming
Copy link
Contributor Author

@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,

@dhuebner
Copy link
Member

@JonasHelming
I can check earliest tomorrow

@JonasHelming
Copy link
Contributor Author

JonasHelming commented Feb 25, 2025

@dhuebner OK, If I do not hear from you by tomorrow, I will merge (release is on Friday), please report any issues.

Follow up added to #14923

@JonasHelming
Copy link
Contributor Author

@dhuebner Quick reminder to ideally have a quick look today (sorry for the additional ping) :-)

Copy link
Member

@dhuebner dhuebner left a 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 ?? {}),

@JonasHelming
Copy link
Contributor Author

@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.

@JonasHelming JonasHelming merged commit 2e4a3b1 into master Feb 26, 2025
10 of 11 checks passed
@github-actions github-actions bot added this to the 1.59.0 milestone Feb 26, 2025
@JonasHelming JonasHelming mentioned this pull request Feb 26, 2025
45 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

[Theia AI] Support anyOf in function parameters
3 participants