- Notifications
You must be signed in to change notification settings - Fork 1.5k
Add Agent.output_json_schema() method #3454
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
Conversation
| @DouweM is there a source of truth I can reference for what the schema output should be for tests? I think I will get stuck figuring this out so any guidance will be appreciated. Edit: I added snapshots of expected output to the tests. Please review them carefully as I'm guessing what they are supposed to be. |
| @DouweM thanks for the reviews so far. Fixed:
allows_text to True. This doesn't seem right but I'll wait for confirmation. |
| @DouweM ready for review |
| json_schemas: list[JsonSchema] = [] | ||
| for output_spec in flat_output_type: | ||
| json_schema = TypeAdapter(output_spec).json_schema(mode='serialization') | ||
| if json_schema not in json_schemas: |
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.
Maybe json_schemas can be a set so that it's automatically de-duped
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.
I don't think I can do that because dictionaries are mutable.
| elif isinstance(output_spec, _output.ToolOutput): | ||
| flat_output_type += _flatten_output_spec(output_spec.output) | ||
| elif inspect.isfunction(output_spec) or inspect.ismethod(output_spec): | ||
| return_annotation = inspect.signature(output_spec).return_annotation |
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.
What if there is no return annotation on the output function?
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 function_schema we use a helper method for this:
| type_hints = _typing_extra.get_function_type_hints(function) |
I think its return value will have a 'return' key. Can we use it here as well?
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.
Done - if there is no key, I set the return type to string.
| raise ValueError('`BinaryImage` must be have a media type that starts with "image/"') # pragma: no cover | ||
| | ||
| @classmethod | ||
| def __get_pydantic_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.
On second thought, let's leave these changes out for now. Once we get to #3122, we'll also need to think about the schemas for BinaryContent, FileUrl etc, so I'd rather tackle this in one go than instead of giving BinaryImage special treatment now.
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.
I reverted all changes to BinaryImage, hopefully that is okay.
| @DouweM ready for review |
| | ||
| def flatten_output_type( | ||
| output_type: OutputSpec[OutputDataT], | ||
| ) -> list[OutputSpec[OutputDataT] | type[str]]: |
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.
Would this be list[OutputDataT], without the OutputSpec? 🤔
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.
_flatten_output_spec returns OutputSpec sequences, so out of the box it doesn't work (I gave it a try, type checkers not pleased). So I think I would have to cast flat_output_type or write my own version of _flatten_output_spec to achieve the effect of having list[OutputDataT] as the return.
| return outputs_flat | ||
| | ||
| | ||
| def flatten_output_type( |
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.
types_from_output_spec?
| @g-eoj Thanks Joe, looks great! 🤞🏻 that CI goes green |
This PR adds a method to get the json schema for agent output.
It aims to support all output types, including special ones:
BinaryImageDeferredToolRequestsSimple example:
{'type': 'string'}Override agent output types:
{'type': 'bool'}Closes #3225