You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: pydantic_ai_slim/pydantic_ai/_output.py
+71-5Lines changed: 71 additions & 5 deletions
Original file line number
Diff line number
Diff line change
@@ -12,8 +12,15 @@
12
12
13
13
from . import_utils, messagesas_messages
14
14
from .exceptionsimportModelRetry
15
-
from .resultimportDEFAULT_OUTPUT_TOOL_NAME, OutputDataT, OutputDataT_inv, OutputValidatorFunc, ToolOutput
16
-
from .toolsimportAgentDepsT, GenerateToolJsonSchema, RunContext, ToolDefinition
15
+
from .resultimport (
16
+
DEFAULT_OUTPUT_TOOL_NAME,
17
+
OutputDataT,
18
+
OutputDataT_inv,
19
+
OutputValidatorFunc,
20
+
StructuredOutput,
21
+
ToolOutput,
22
+
)
23
+
from .toolsimportAgentDepsT, GenerateToolJsonSchema, ObjectJsonSchema, RunContext, ToolDefinition
17
24
18
25
T=TypeVar('T')
19
26
"""An invariant TypeVar."""
@@ -83,13 +90,18 @@ class OutputSchema(Generic[OutputDataT]):
83
90
Similar to `Tool` but for the final output of running an agent.
84
91
"""
85
92
93
+
# TODO: Since this is currently called "preferred", models that don't have structured output implemented yet ignore it and use tools (except for Mistral).
94
+
# We should likely raise an error if an unsupported mode is used, _and_ allow the model to pick its own preferred mode if none is forced.
95
+
preferred_mode: Literal['tool', 'structured'] |None# TODO: Add mode for manual JSON
96
+
type_adapter: TypeAdapter[OutputDataT]
86
97
tools: dict[str, OutputSchemaTool[OutputDataT]]
87
-
allow_text_output: bool
98
+
allow_text_output: bool# TODO: Verify structured output works correctly with string as a union member
99
+
json_schema: ObjectJsonSchema# TODO: Verify structured output works correctly with a union
88
100
89
101
@classmethod
90
102
defbuild(
91
103
cls: type[OutputSchema[T]],
92
-
output_type: type[T] |ToolOutput[T],
104
+
output_type: type[T] |ToolOutput[T]|StructuredOutput[T], # TODO: Support a list of output types/markers
93
105
name: str|None=None,
94
106
description: str|None=None,
95
107
strict: bool|None=None,
@@ -98,15 +110,34 @@ def build(
98
110
ifoutput_typeisstr:
99
111
returnNone
100
112
113
+
preferred_mode=None
101
114
ifisinstance(output_type, ToolOutput):
102
115
# do we need to error on conflicts here? (DavidM): If this is internal maybe doesn't matter, if public, use overloads
103
116
name=output_type.name
104
117
description=output_type.description
105
118
output_type_=output_type.output_type
106
119
strict=output_type.strict
120
+
preferred_mode='tool'
121
+
elifisinstance(output_type, StructuredOutput):
122
+
name=output_type.name# TODO: Get this to the response_format model request arg
123
+
description=output_type.description# TODO: Get this to the response_format model request arg
124
+
output_type_=output_type.output_type
125
+
strict=output_type.strict# TODO: Get this to the response_format model request arg
0 commit comments