Conversation
Under `from __future__ import annotations`, or with quoted annotations, every parameter annotation is a string. convert_function_to_tool passed those strings to a pydantic model built inside ollama._utils, which cannot resolve names like Optional or Literal from the caller's module, so chat(tools=[func]) raised PydanticUserError before sending anything. Evaluate the annotations with get_type_hints in the function's own module and fall back to the raw annotation if that fails.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Passing a function as a tool fails when its module uses
from __future__ import annotations, or when its annotations are quoted:The call fails inside
_copy_tools, before any request is sent. With the future import, every annotation is a string ('Literal[...]','Optional[int]').convert_function_to_toolcopies those strings into a pydantic model that it creates insideollama._utils. Pydantic resolves them there, where names likeOptional,LiteralorListdo not exist. Builtins such asstrandintstill resolve, so only functions that usetypingnames are affected. Most tool functions do.This change evaluates string annotations with
get_type_hintsagainst the function's own module, following__wrapped__for decorated functions. If that fails, it falls back to the raw annotation, which is the current behavior. Annotations that are not strings are passed through unchanged.Verification
test_function_with_string_annotationsuses quoted annotations, which is the same code path as the future import. It fails onmainwith thePydanticUserErrorabove and passes with this change.Client.chat(tools=[get_weather])from a module with the future import, using anhttpx.MockTransport: onmainit raises before any request is sent. With the change, the request carriescity: string,unit: stringanddays: integer, the same schema as without the future import.pytest ollama testspasses (103 tests), andruff format --checkandruff checkare clean.