Skip to content

Conversation

@stephentoub
Copy link
Member

@stephentoub stephentoub commented Oct 9, 2025

In the olden days (i.e. a few months ago), you could require the model/service to request invocation of any tool or of a specific function by name. Now, you can request that it invoke other tools as well. This adds another RequireSpecific overload that takes an AITool instead of a string function name, so that you can do things like RequireSpecific(webSearchTool).

Fixes #6288

Microsoft Reviewers: Open in CodeFlow

In the olden days (i.e. a few months ago), you could require the model/service to request invocation of any tool or of a specific function by name. Now, you can request that it invoke other tools as well. This adds another RequireSpecific overload that takes an AITool instead of a string function name, so that you can do things like RequireSpecific(webSearchTool).
@github-actions github-actions bot added the area-ai Microsoft.Extensions.AI libraries label Oct 9, 2025
/// </para>
/// </remarks>
[JsonIgnore]
public AITool? RequiredTool { get; }
Copy link
Member

@eiriktsarpalis eiriktsarpalis Oct 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we end up roundtripping this value the resultant object is going to have a subtly different equality semantic, and will have impact in how the resultant object gets processed in the OpenAI provider. Is there a way we could potentially preserve its intended representation in such cases?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we end up roundtripping this value the resultant object is going to have a subtly different equality semantic

Will it? Do you just mean it'll no longer be equal to another instance that contains the tool since this one is null? I mean, yeah :) That's not just equality, it's no longer the same requirement. If you set it to an AIFunctionDeclaration, though, it should behave the same, as the name gets extracted.

Is there a way we could potentially preserve its intended representation in such cases?

What did you have in mind?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What did you have in mind?

Nothing specific, just asking if serializing the value could inherently change how it gets handled by the leaf clients.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just asking if serializing the value could inherently change how it gets handled by the leaf clients.

It could, yes, as the AITool will be null after deserialization. That's already the case for ChatOptions.Tools, too. So if you serialize and deserialize a ChatOptions, you're going to lose both on the resulting instance.

We could revisit that. We could allow AITool to be serialized, and in most cases we can persist most data. The main (and important) thing we can't is the actual function implementation for AIFunction.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eiriktsarpalis, alternative suggestions or approaches? What do you think about enabling AITools to be serialized, except an AIFunction would roundtrip as an AIFunctionDeclaration (i.e. it would lose its invocation ability)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only alternative I can think of is requiring tools by name only.

What do you think about enabling AITools to be serialized, except an AIFunction would roundtrip as an AIFunctionDeclaration (i.e. it would lose its invocation ability)?

Seems reasonable, although that scheme would only work in the context of a JsonConverter<AITool> but not for a JsonConverter<AIFunction> due to the lack of type relationship with AIFunctionDefinition.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-ai Microsoft.Extensions.AI libraries

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ChatOptions.ToolMode doesn't enable require non-function tools

2 participants