pydantic-ai-slim 0.4.9__py3-none-any.whl → 0.4.11__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pydantic-ai-slim might be problematic. Click here for more details.

pydantic_ai/agent.py CHANGED
@@ -774,90 +774,91 @@ class Agent(Generic[AgentDepsT, OutputDataT]):
774
774
 
775
775
  toolset = self._get_toolset(output_toolset=output_toolset, additional_toolsets=toolsets)
776
776
  # This will raise errors for any name conflicts
777
- run_toolset = await ToolManager[AgentDepsT].build(toolset, run_context)
778
-
779
- # Merge model settings in order of precedence: run > agent > model
780
- merged_settings = merge_model_settings(model_used.settings, self.model_settings)
781
- model_settings = merge_model_settings(merged_settings, model_settings)
782
- usage_limits = usage_limits or _usage.UsageLimits()
783
- agent_name = self.name or 'agent'
784
- run_span = tracer.start_span(
785
- 'agent run',
786
- attributes={
787
- 'model_name': model_used.model_name if model_used else 'no-model',
788
- 'agent_name': agent_name,
789
- 'logfire.msg': f'{agent_name} run',
790
- },
791
- )
792
-
793
- async def get_instructions(run_context: RunContext[AgentDepsT]) -> str | None:
794
- parts = [
795
- self._instructions,
796
- *[await func.run(run_context) for func in self._instructions_functions],
797
- ]
798
-
799
- model_profile = model_used.profile
800
- if isinstance(output_schema, _output.PromptedOutputSchema):
801
- instructions = output_schema.instructions(model_profile.prompted_output_template)
802
- parts.append(instructions)
777
+ async with toolset:
778
+ run_toolset = await ToolManager[AgentDepsT].build(toolset, run_context)
779
+
780
+ # Merge model settings in order of precedence: run > agent > model
781
+ merged_settings = merge_model_settings(model_used.settings, self.model_settings)
782
+ model_settings = merge_model_settings(merged_settings, model_settings)
783
+ usage_limits = usage_limits or _usage.UsageLimits()
784
+ agent_name = self.name or 'agent'
785
+ run_span = tracer.start_span(
786
+ 'agent run',
787
+ attributes={
788
+ 'model_name': model_used.model_name if model_used else 'no-model',
789
+ 'agent_name': agent_name,
790
+ 'logfire.msg': f'{agent_name} run',
791
+ },
792
+ )
803
793
 
804
- parts = [p for p in parts if p]
805
- if not parts:
806
- return None
807
- return '\n\n'.join(parts).strip()
794
+ async def get_instructions(run_context: RunContext[AgentDepsT]) -> str | None:
795
+ parts = [
796
+ self._instructions,
797
+ *[await func.run(run_context) for func in self._instructions_functions],
798
+ ]
808
799
 
809
- graph_deps = _agent_graph.GraphAgentDeps[AgentDepsT, RunOutputDataT](
810
- user_deps=deps,
811
- prompt=user_prompt,
812
- new_message_index=new_message_index,
813
- model=model_used,
814
- model_settings=model_settings,
815
- usage_limits=usage_limits,
816
- max_result_retries=self._max_result_retries,
817
- end_strategy=self.end_strategy,
818
- output_schema=output_schema,
819
- output_validators=output_validators,
820
- history_processors=self.history_processors,
821
- tool_manager=run_toolset,
822
- tracer=tracer,
823
- get_instructions=get_instructions,
824
- instrumentation_settings=instrumentation_settings,
825
- )
826
- start_node = _agent_graph.UserPromptNode[AgentDepsT](
827
- user_prompt=user_prompt,
828
- instructions=self._instructions,
829
- instructions_functions=self._instructions_functions,
830
- system_prompts=self._system_prompts,
831
- system_prompt_functions=self._system_prompt_functions,
832
- system_prompt_dynamic_functions=self._system_prompt_dynamic_functions,
833
- )
800
+ model_profile = model_used.profile
801
+ if isinstance(output_schema, _output.PromptedOutputSchema):
802
+ instructions = output_schema.instructions(model_profile.prompted_output_template)
803
+ parts.append(instructions)
804
+
805
+ parts = [p for p in parts if p]
806
+ if not parts:
807
+ return None
808
+ return '\n\n'.join(parts).strip()
809
+
810
+ graph_deps = _agent_graph.GraphAgentDeps[AgentDepsT, RunOutputDataT](
811
+ user_deps=deps,
812
+ prompt=user_prompt,
813
+ new_message_index=new_message_index,
814
+ model=model_used,
815
+ model_settings=model_settings,
816
+ usage_limits=usage_limits,
817
+ max_result_retries=self._max_result_retries,
818
+ end_strategy=self.end_strategy,
819
+ output_schema=output_schema,
820
+ output_validators=output_validators,
821
+ history_processors=self.history_processors,
822
+ tool_manager=run_toolset,
823
+ tracer=tracer,
824
+ get_instructions=get_instructions,
825
+ instrumentation_settings=instrumentation_settings,
826
+ )
827
+ start_node = _agent_graph.UserPromptNode[AgentDepsT](
828
+ user_prompt=user_prompt,
829
+ instructions=self._instructions,
830
+ instructions_functions=self._instructions_functions,
831
+ system_prompts=self._system_prompts,
832
+ system_prompt_functions=self._system_prompt_functions,
833
+ system_prompt_dynamic_functions=self._system_prompt_dynamic_functions,
834
+ )
834
835
 
835
- try:
836
- async with graph.iter(
837
- start_node,
838
- state=state,
839
- deps=graph_deps,
840
- span=use_span(run_span) if run_span.is_recording() else None,
841
- infer_name=False,
842
- ) as graph_run:
843
- agent_run = AgentRun(graph_run)
844
- yield agent_run
845
- if (final_result := agent_run.result) is not None and run_span.is_recording():
846
- if instrumentation_settings and instrumentation_settings.include_content:
847
- run_span.set_attribute(
848
- 'final_result',
849
- (
850
- final_result.output
851
- if isinstance(final_result.output, str)
852
- else json.dumps(InstrumentedModel.serialize_any(final_result.output))
853
- ),
854
- )
855
- finally:
856
836
  try:
857
- if instrumentation_settings and run_span.is_recording():
858
- run_span.set_attributes(self._run_span_end_attributes(state, usage, instrumentation_settings))
837
+ async with graph.iter(
838
+ start_node,
839
+ state=state,
840
+ deps=graph_deps,
841
+ span=use_span(run_span) if run_span.is_recording() else None,
842
+ infer_name=False,
843
+ ) as graph_run:
844
+ agent_run = AgentRun(graph_run)
845
+ yield agent_run
846
+ if (final_result := agent_run.result) is not None and run_span.is_recording():
847
+ if instrumentation_settings and instrumentation_settings.include_content:
848
+ run_span.set_attribute(
849
+ 'final_result',
850
+ (
851
+ final_result.output
852
+ if isinstance(final_result.output, str)
853
+ else json.dumps(InstrumentedModel.serialize_any(final_result.output))
854
+ ),
855
+ )
859
856
  finally:
860
- run_span.end()
857
+ try:
858
+ if instrumentation_settings and run_span.is_recording():
859
+ run_span.set_attributes(self._run_span_end_attributes(state, usage, instrumentation_settings))
860
+ finally:
861
+ run_span.end()
861
862
 
862
863
  def _run_span_end_attributes(
863
864
  self, state: _agent_graph.GraphAgentState, usage: _usage.Usage, settings: InstrumentationSettings
@@ -1869,9 +1870,13 @@ class Agent(Generic[AgentDepsT, OutputDataT]):
1869
1870
  on_shutdown: Sequence[Callable[[], Any]] | None = None,
1870
1871
  lifespan: Lifespan[AGUIApp[AgentDepsT, OutputDataT]] | None = None,
1871
1872
  ) -> AGUIApp[AgentDepsT, OutputDataT]:
1872
- """Convert the agent to an AG-UI application.
1873
+ """Returns an ASGI application that handles every AG-UI request by running the agent.
1873
1874
 
1874
- This allows you to use the agent with a compatible AG-UI frontend.
1875
+ Note that the `deps` will be the same for each request, with the exception of the AG-UI state that's
1876
+ injected into the `state` field of a `deps` object that implements the [`StateHandler`][pydantic_ai.ag_ui.StateHandler] protocol.
1877
+ To provide different `deps` for each request (e.g. based on the authenticated user),
1878
+ use [`pydantic_ai.ag_ui.run_ag_ui`][pydantic_ai.ag_ui.run_ag_ui] or
1879
+ [`pydantic_ai.ag_ui.handle_ag_ui_request`][pydantic_ai.ag_ui.handle_ag_ui_request] instead.
1875
1880
 
1876
1881
  Example:
1877
1882
  ```python
@@ -1881,8 +1886,6 @@ class Agent(Generic[AgentDepsT, OutputDataT]):
1881
1886
  app = agent.to_ag_ui()
1882
1887
  ```
1883
1888
 
1884
- The `app` is an ASGI application that can be used with any ASGI server.
1885
-
1886
1889
  To run the application, you can use the following command:
1887
1890
 
1888
1891
  ```bash
@@ -1901,7 +1904,7 @@ class Agent(Generic[AgentDepsT, OutputDataT]):
1901
1904
  usage_limits: Optional limits on model request count or token usage.
1902
1905
  usage: Optional usage to start with, useful for resuming a conversation or agents used in tools.
1903
1906
  infer_name: Whether to try to infer the agent name from the call frame if it's not set.
1904
- toolsets: Optional list of toolsets to use for this agent, defaults to the agent's toolset.
1907
+ toolsets: Optional additional toolsets for this run.
1905
1908
 
1906
1909
  debug: Boolean indicating if debug tracebacks should be returned on errors.
1907
1910
  routes: A list of routes to serve incoming HTTP and WebSocket requests.
@@ -2173,7 +2176,7 @@ class AgentRun(Generic[AgentDepsT, OutputDataT]):
2173
2176
  ) -> _agent_graph.AgentNode[AgentDepsT, OutputDataT] | End[FinalResult[OutputDataT]]:
2174
2177
  """Advance to the next node automatically based on the last returned node."""
2175
2178
  next_node = await self._graph_run.__anext__()
2176
- if _agent_graph.is_agent_node(next_node):
2179
+ if _agent_graph.is_agent_node(node=next_node):
2177
2180
  return next_node
2178
2181
  assert isinstance(next_node, End), f'Unexpected node type: {type(next_node)}'
2179
2182
  return next_node
pydantic_ai/messages.py CHANGED
@@ -412,8 +412,8 @@ class ToolReturn:
412
412
  return_value: Any
413
413
  """The return value to be used in the tool response."""
414
414
 
415
- content: Sequence[UserContent] | None = None
416
- """The content sequence to be sent to the model as a UserPromptPart."""
415
+ content: str | Sequence[UserContent] | None = None
416
+ """The content to be sent to the model as a UserPromptPart."""
417
417
 
418
418
  metadata: Any = None
419
419
  """Additional data that can be accessed programmatically by the application but is not sent to the LLM."""
@@ -137,12 +137,12 @@ KnownModelName = TypeAliasType(
137
137
  'google-gla:gemini-2.0-flash',
138
138
  'google-gla:gemini-2.0-flash-lite',
139
139
  'google-gla:gemini-2.5-flash',
140
- 'google-gla:gemini-2.5-flash-lite-preview-06-17',
140
+ 'google-gla:gemini-2.5-flash-lite',
141
141
  'google-gla:gemini-2.5-pro',
142
142
  'google-vertex:gemini-2.0-flash',
143
143
  'google-vertex:gemini-2.0-flash-lite',
144
144
  'google-vertex:gemini-2.5-flash',
145
- 'google-vertex:gemini-2.5-flash-lite-preview-06-17',
145
+ 'google-vertex:gemini-2.5-flash-lite',
146
146
  'google-vertex:gemini-2.5-pro',
147
147
  'gpt-3.5-turbo',
148
148
  'gpt-3.5-turbo-0125',
@@ -192,7 +192,7 @@ class CohereModel(Model):
192
192
  # While Cohere's API returns a list, it only does that for future proofing
193
193
  # and currently only one item is being returned.
194
194
  choice = response.message.content[0]
195
- parts.extend(split_content_into_text_and_thinking(choice.text))
195
+ parts.extend(split_content_into_text_and_thinking(choice.text, self.profile.thinking_tags))
196
196
  for c in response.message.tool_calls or []:
197
197
  if c.function and c.function.name and c.function.arguments: # pragma: no branch
198
198
  parts.append(
@@ -51,7 +51,7 @@ LatestGeminiModelNames = Literal[
51
51
  'gemini-2.0-flash',
52
52
  'gemini-2.0-flash-lite',
53
53
  'gemini-2.5-flash',
54
- 'gemini-2.5-flash-lite-preview-06-17',
54
+ 'gemini-2.5-flash-lite',
55
55
  'gemini-2.5-pro',
56
56
  ]
57
57
  """Latest Gemini models."""
@@ -76,7 +76,7 @@ LatestGoogleModelNames = Literal[
76
76
  'gemini-2.0-flash',
77
77
  'gemini-2.0-flash-lite',
78
78
  'gemini-2.5-flash',
79
- 'gemini-2.5-flash-lite-preview-06-17',
79
+ 'gemini-2.5-flash-lite',
80
80
  'gemini-2.5-pro',
81
81
  ]
82
82
  """Latest Gemini models."""
@@ -30,7 +30,7 @@ from ..messages import (
30
30
  ToolReturnPart,
31
31
  UserPromptPart,
32
32
  )
33
- from ..profiles import ModelProfileSpec
33
+ from ..profiles import ModelProfile, ModelProfileSpec
34
34
  from ..providers import Provider, infer_provider
35
35
  from ..settings import ModelSettings
36
36
  from ..tools import ToolDefinition
@@ -261,7 +261,7 @@ class GroqModel(Model):
261
261
  items.append(ThinkingPart(content=choice.message.reasoning))
262
262
  if choice.message.content is not None:
263
263
  # NOTE: The `<think>` tag is only present if `groq_reasoning_format` is set to `raw`.
264
- items.extend(split_content_into_text_and_thinking(choice.message.content))
264
+ items.extend(split_content_into_text_and_thinking(choice.message.content, self.profile.thinking_tags))
265
265
  if choice.message.tool_calls is not None:
266
266
  for c in choice.message.tool_calls:
267
267
  items.append(ToolCallPart(tool_name=c.function.name, args=c.function.arguments, tool_call_id=c.id))
@@ -281,6 +281,7 @@ class GroqModel(Model):
281
281
  return GroqStreamedResponse(
282
282
  _response=peekable_response,
283
283
  _model_name=self._model_name,
284
+ _model_profile=self.profile,
284
285
  _timestamp=number_to_datetime(first_chunk.created),
285
286
  )
286
287
 
@@ -400,6 +401,7 @@ class GroqStreamedResponse(StreamedResponse):
400
401
  """Implementation of `StreamedResponse` for Groq models."""
401
402
 
402
403
  _model_name: GroqModelName
404
+ _model_profile: ModelProfile
403
405
  _response: AsyncIterable[chat.ChatCompletionChunk]
404
406
  _timestamp: datetime
405
407
 
@@ -416,7 +418,9 @@ class GroqStreamedResponse(StreamedResponse):
416
418
  content = choice.delta.content
417
419
  if content is not None:
418
420
  maybe_event = self._parts_manager.handle_text_delta(
419
- vendor_part_id='content', content=content, extract_think_tags=True
421
+ vendor_part_id='content',
422
+ content=content,
423
+ thinking_tags=self._model_profile.thinking_tags,
420
424
  )
421
425
  if maybe_event is not None: # pragma: no branch
422
426
  yield maybe_event
@@ -33,6 +33,7 @@ from ..messages import (
33
33
  UserPromptPart,
34
34
  VideoUrl,
35
35
  )
36
+ from ..profiles import ModelProfile
36
37
  from ..settings import ModelSettings
37
38
  from ..tools import ToolDefinition
38
39
  from . import Model, ModelRequestParameters, StreamedResponse, check_allow_model_requests
@@ -244,7 +245,7 @@ class HuggingFaceModel(Model):
244
245
  items: list[ModelResponsePart] = []
245
246
 
246
247
  if content is not None:
247
- items.extend(split_content_into_text_and_thinking(content))
248
+ items.extend(split_content_into_text_and_thinking(content, self.profile.thinking_tags))
248
249
  if tool_calls is not None:
249
250
  for c in tool_calls:
250
251
  items.append(ToolCallPart(c.function.name, c.function.arguments, tool_call_id=c.id))
@@ -267,6 +268,7 @@ class HuggingFaceModel(Model):
267
268
 
268
269
  return HuggingFaceStreamedResponse(
269
270
  _model_name=self._model_name,
271
+ _model_profile=self.profile,
270
272
  _response=peekable_response,
271
273
  _timestamp=datetime.fromtimestamp(first_chunk.created, tz=timezone.utc),
272
274
  )
@@ -412,6 +414,7 @@ class HuggingFaceStreamedResponse(StreamedResponse):
412
414
  """Implementation of `StreamedResponse` for Hugging Face models."""
413
415
 
414
416
  _model_name: str
417
+ _model_profile: ModelProfile
415
418
  _response: AsyncIterable[ChatCompletionStreamOutput]
416
419
  _timestamp: datetime
417
420
 
@@ -428,7 +431,9 @@ class HuggingFaceStreamedResponse(StreamedResponse):
428
431
  content = choice.delta.content
429
432
  if content:
430
433
  maybe_event = self._parts_manager.handle_text_delta(
431
- vendor_part_id='content', content=content, extract_think_tags=True
434
+ vendor_part_id='content',
435
+ content=content,
436
+ thinking_tags=self._model_profile.thinking_tags,
432
437
  )
433
438
  if maybe_event is not None: # pragma: no branch
434
439
  yield maybe_event
@@ -333,7 +333,7 @@ class MistralModel(Model):
333
333
 
334
334
  parts: list[ModelResponsePart] = []
335
335
  if text := _map_content(content):
336
- parts.extend(split_content_into_text_and_thinking(text))
336
+ parts.extend(split_content_into_text_and_thinking(text, self.profile.thinking_tags))
337
337
 
338
338
  if isinstance(tool_calls, list):
339
339
  for tool_call in tool_calls:
@@ -37,7 +37,7 @@ from ..messages import (
37
37
  UserPromptPart,
38
38
  VideoUrl,
39
39
  )
40
- from ..profiles import ModelProfileSpec
40
+ from ..profiles import ModelProfile, ModelProfileSpec
41
41
  from ..settings import ModelSettings
42
42
  from ..tools import ToolDefinition
43
43
  from . import (
@@ -120,10 +120,10 @@ class OpenAIModelSettings(ModelSettings, total=False):
120
120
  See [OpenAI's safety best practices](https://platform.openai.com/docs/guides/safety-best-practices#end-user-ids) for more details.
121
121
  """
122
122
 
123
- openai_service_tier: Literal['auto', 'default', 'flex']
123
+ openai_service_tier: Literal['auto', 'default', 'flex', 'priority']
124
124
  """The service tier to use for the model request.
125
125
 
126
- Currently supported values are `auto`, `default`, and `flex`.
126
+ Currently supported values are `auto`, `default`, `flex`, and `priority`.
127
127
  For more information, see [OpenAI's service tiers documentation](https://platform.openai.com/docs/api-reference/chat/object#chat/object-service_tier).
128
128
  """
129
129
 
@@ -407,7 +407,7 @@ class OpenAIModel(Model):
407
407
  }
408
408
 
409
409
  if choice.message.content is not None:
410
- items.extend(split_content_into_text_and_thinking(choice.message.content))
410
+ items.extend(split_content_into_text_and_thinking(choice.message.content, self.profile.thinking_tags))
411
411
  if choice.message.tool_calls is not None:
412
412
  for c in choice.message.tool_calls:
413
413
  part = ToolCallPart(c.function.name, c.function.arguments, tool_call_id=c.id)
@@ -433,6 +433,7 @@ class OpenAIModel(Model):
433
433
 
434
434
  return OpenAIStreamedResponse(
435
435
  _model_name=self._model_name,
436
+ _model_profile=self.profile,
436
437
  _response=peekable_response,
437
438
  _timestamp=number_to_datetime(first_chunk.created),
438
439
  )
@@ -803,6 +804,7 @@ class OpenAIResponsesModel(Model):
803
804
  top_p=sampling_settings.get('top_p', NOT_GIVEN),
804
805
  truncation=model_settings.get('openai_truncation', NOT_GIVEN),
805
806
  timeout=model_settings.get('timeout', NOT_GIVEN),
807
+ service_tier=model_settings.get('openai_service_tier', NOT_GIVEN),
806
808
  reasoning=reasoning,
807
809
  user=model_settings.get('openai_user', NOT_GIVEN),
808
810
  text=text or NOT_GIVEN,
@@ -1008,6 +1010,7 @@ class OpenAIStreamedResponse(StreamedResponse):
1008
1010
  """Implementation of `StreamedResponse` for OpenAI models."""
1009
1011
 
1010
1012
  _model_name: OpenAIModelName
1013
+ _model_profile: ModelProfile
1011
1014
  _response: AsyncIterable[ChatCompletionChunk]
1012
1015
  _timestamp: datetime
1013
1016
 
@@ -1024,7 +1027,9 @@ class OpenAIStreamedResponse(StreamedResponse):
1024
1027
  content = choice.delta.content
1025
1028
  if content:
1026
1029
  maybe_event = self._parts_manager.handle_text_delta(
1027
- vendor_part_id='content', content=content, extract_think_tags=True
1030
+ vendor_part_id='content',
1031
+ content=content,
1032
+ thinking_tags=self._model_profile.thinking_tags,
1028
1033
  )
1029
1034
  if maybe_event is not None: # pragma: no branch
1030
1035
  yield maybe_event
@@ -123,7 +123,9 @@ class TestModel(Model):
123
123
 
124
124
  model_response = self._request(messages, model_settings, model_request_parameters)
125
125
  yield TestStreamedResponse(
126
- _model_name=self._model_name, _structured_response=model_response, _messages=messages
126
+ _model_name=self._model_name,
127
+ _structured_response=model_response,
128
+ _messages=messages,
127
129
  )
128
130
 
129
131
  @property
@@ -35,6 +35,9 @@ class ModelProfile:
35
35
  json_schema_transformer: type[JsonSchemaTransformer] | None = None
36
36
  """The transformer to use to make JSON schemas for tools and structured output compatible with the model."""
37
37
 
38
+ thinking_tags: tuple[str, str] = ('<think>', '</think>')
39
+ """The tags used to indicate thinking parts in the model's output. Defaults to ('<think>', '</think>')."""
40
+
38
41
  @classmethod
39
42
  def from_profile(cls, profile: ModelProfile | None) -> Self:
40
43
  """Build a ModelProfile subclass instance from a ModelProfile instance."""
@@ -5,4 +5,4 @@ from . import ModelProfile
5
5
 
6
6
  def anthropic_model_profile(model_name: str) -> ModelProfile | None:
7
7
  """Get the model profile for an Anthropic model."""
8
- return None
8
+ return ModelProfile(thinking_tags=('<thinking>', '</thinking>'))
@@ -98,10 +98,16 @@ class VercelProvider(Provider[AsyncOpenAI]):
98
98
  'or pass the API key via `VercelProvider(api_key=...)` to use the Vercel provider.'
99
99
  )
100
100
 
101
+ default_headers = {'http-referer': 'https://ai.pydantic.dev/', 'x-title': 'pydantic-ai'}
102
+
101
103
  if openai_client is not None:
102
104
  self._client = openai_client
103
105
  elif http_client is not None:
104
- self._client = AsyncOpenAI(base_url=self.base_url, api_key=api_key, http_client=http_client)
106
+ self._client = AsyncOpenAI(
107
+ base_url=self.base_url, api_key=api_key, http_client=http_client, default_headers=default_headers
108
+ )
105
109
  else:
106
110
  http_client = cached_async_http_client(provider='vercel')
107
- self._client = AsyncOpenAI(base_url=self.base_url, api_key=api_key, http_client=http_client)
111
+ self._client = AsyncOpenAI(
112
+ base_url=self.base_url, api_key=api_key, http_client=http_client, default_headers=default_headers
113
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydantic-ai-slim
3
- Version: 0.4.9
3
+ Version: 0.4.11
4
4
  Summary: Agent Framework / shim to use Pydantic with LLMs, slim package
5
5
  Author-email: Samuel Colvin <samuel@pydantic.dev>, Marcelo Trylesinski <marcelotryle@gmail.com>, David Montague <david@pydantic.dev>, Alex Hall <alex@pydantic.dev>, Douwe Maan <douwe@pydantic.dev>
6
6
  License-Expression: MIT
@@ -30,7 +30,7 @@ Requires-Dist: exceptiongroup; python_version < '3.11'
30
30
  Requires-Dist: griffe>=1.3.2
31
31
  Requires-Dist: httpx>=0.27
32
32
  Requires-Dist: opentelemetry-api>=1.28.0
33
- Requires-Dist: pydantic-graph==0.4.9
33
+ Requires-Dist: pydantic-graph==0.4.11
34
34
  Requires-Dist: pydantic>=2.10
35
35
  Requires-Dist: typing-inspection>=0.4.0
36
36
  Provides-Extra: a2a
@@ -51,7 +51,7 @@ Requires-Dist: cohere>=5.16.0; (platform_system != 'Emscripten') and extra == 'c
51
51
  Provides-Extra: duckduckgo
52
52
  Requires-Dist: ddgs>=9.0.0; extra == 'duckduckgo'
53
53
  Provides-Extra: evals
54
- Requires-Dist: pydantic-evals==0.4.9; extra == 'evals'
54
+ Requires-Dist: pydantic-evals==0.4.11; extra == 'evals'
55
55
  Provides-Extra: google
56
56
  Requires-Dist: google-genai>=1.24.0; extra == 'google'
57
57
  Provides-Extra: groq
@@ -1,26 +1,26 @@
1
1
  pydantic_ai/__init__.py,sha256=h6Rll8pEzUUUX6SckosummoAFbq7ctfBlI6WSyaXR4I,1300
2
2
  pydantic_ai/__main__.py,sha256=Q_zJU15DUA01YtlJ2mnaLCoId2YmgmreVEERGuQT-Y0,132
3
3
  pydantic_ai/_a2a.py,sha256=Tw_j9VRud0rLEk5kRs4GhRyhWYioXnsoZaTTyISq4M4,12126
4
- pydantic_ai/_agent_graph.py,sha256=FrNq9kppV8kFVZf6t-MVGVOWUVBCXQfAinQjMh2gVWw,37192
4
+ pydantic_ai/_agent_graph.py,sha256=-D_X7qyg4fHRbgR9ffKM_FU4KZ3qas-YgVvSmS0eXeI,37347
5
5
  pydantic_ai/_cli.py,sha256=YkiW2u9HGPd9fsgo9dpK1DZvtUPk4uXGQJcm75XgfhU,13250
6
6
  pydantic_ai/_function_schema.py,sha256=6Xuash0DVpfPF0rWQce0bhtgti8YRyk3B1-OK_n6dqs,11099
7
7
  pydantic_ai/_griffe.py,sha256=Ugft16ZHw9CN_6-lW0Svn6jESK9zHXO_x4utkGBkbBI,5253
8
8
  pydantic_ai/_mcp.py,sha256=PuvwnlLjv7YYOa9AZJCrklevBug99zGMhwJCBGG7BHQ,5626
9
9
  pydantic_ai/_output.py,sha256=2k-nxfPNLJEb-wjnPhQo63lh-yQH1XsIhNG1hjsrim0,37462
10
- pydantic_ai/_parts_manager.py,sha256=T4nlxaS697KeikJoqc1I9kRoIN5-_t5TEv-ovpMlzZg,17856
10
+ pydantic_ai/_parts_manager.py,sha256=lWXN75zLy_MSDz4Wib65lqIPHk1SY8KDU8_OYaxG3yw,17788
11
11
  pydantic_ai/_run_context.py,sha256=pqb_HPXytE1Z9zZRRuBboRYes_tVTC75WGTpZgnb2Ko,1691
12
12
  pydantic_ai/_system_prompt.py,sha256=lUSq-gDZjlYTGtd6BUm54yEvTIvgdwBmJ8mLsNZZtYU,1142
13
- pydantic_ai/_thinking_part.py,sha256=mzx2RZSfiQxAKpljEflrcXRXmFKxtp6bKVyorY3UYZk,1554
13
+ pydantic_ai/_thinking_part.py,sha256=x80-Vkon16GOyq3W6f2qzafTVPC5dCgF7QD3k8ZMmYU,1304
14
14
  pydantic_ai/_tool_manager.py,sha256=BdjPntbSshNvYVpYZUNxb-yib5n4GPqcDinbNpzhBVo,8960
15
15
  pydantic_ai/_utils.py,sha256=0Pte4mjir4YFZJTa6i-H6Cra9NbVwSKjOKegArzUggk,16283
16
- pydantic_ai/ag_ui.py,sha256=T7plrZ-pRDptL3r9kNlB2Vit2mVWMCZ1nhxG0ZTfH5M,25562
17
- pydantic_ai/agent.py,sha256=IaO8MQapAKwDTyMCdufLZM5dDsPnNBBiQ5JA-CCFHW8,106528
16
+ pydantic_ai/ag_ui.py,sha256=snIBVMcUUm3WWZ5P5orikyAzvM-7vGunNMgIudhvK-A,26156
17
+ pydantic_ai/agent.py,sha256=VJOvadfilVm60BxWqxtXrzmNTnN8tuhapvFk2r13RO4,107234
18
18
  pydantic_ai/direct.py,sha256=WRfgke3zm-eeR39LTuh9XI2TrdHXAqO81eDvFwih4Ko,14803
19
19
  pydantic_ai/exceptions.py,sha256=o0l6fBrWI5UhosICVZ2yaT-JEJF05eqBlKlQCW8i9UM,3462
20
20
  pydantic_ai/format_as_xml.py,sha256=IINfh1evWDphGahqHNLBArB5dQ4NIqS3S-kru35ztGg,372
21
21
  pydantic_ai/format_prompt.py,sha256=Or-Ytq55RQb1UJqy2HKIyPpZ-knWXfdDP3Z6tNc6Orw,4244
22
22
  pydantic_ai/mcp.py,sha256=v_f4CRzJ399uPC96aqTiEzpaYvuo6vIQyLIpXQBudsY,26271
23
- pydantic_ai/messages.py,sha256=QutKuCXC6aglsbpyI5b3FTzCh7n7uVhJ47KwpEfCtpU,42548
23
+ pydantic_ai/messages.py,sha256=jeaB0o4T4YUdEtnW-whf_2jAiXZ3HPSInvccqTwUcgE,42545
24
24
  pydantic_ai/output.py,sha256=54Cwd1RruXlA5hucZ1h-SxFrzKHJuLvYvLtH9iyg2GI,11988
25
25
  pydantic_ai/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
26
  pydantic_ai/result.py,sha256=bFo2oQZiSw1wvpa6k3rZ3ae2KhzoiQno0F8glKWpvgg,25328
@@ -34,26 +34,26 @@ pydantic_ai/common_tools/tavily.py,sha256=Q1xxSF5HtXAaZ10Pp-OaDOHXwJf2mco9wScGEQ
34
34
  pydantic_ai/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
35
  pydantic_ai/ext/aci.py,sha256=vUaNIj6pRM52x6RkPW_DohSYxJPm75pPUfOMw2i5Xx0,2515
36
36
  pydantic_ai/ext/langchain.py,sha256=GemxfhpyG1JPxj69PbRiSJANnY8Q5s4hSB7wqt-uTbo,2266
37
- pydantic_ai/models/__init__.py,sha256=GZ2YE5qcqI8tNpovlO0_6Ryx92bo8sQTsLmRKiYnSU4,30912
37
+ pydantic_ai/models/__init__.py,sha256=UDi-zXjRt_Zb8kaN5OKMxGXnJtDkROpfa66tSz_wNdI,30884
38
38
  pydantic_ai/models/anthropic.py,sha256=dMPFqIeYCIhoeU_4uk9PmZYQWL1NbkSVmVrBKXplTiI,24167
39
39
  pydantic_ai/models/bedrock.py,sha256=O6wKZDu4L18L1L2Nsa-XMW4ch073FjcLKRA5t_NXcHU,29511
40
- pydantic_ai/models/cohere.py,sha256=lKUXEPqTMqxIJfouDj-Fr1bnfkrPu-JK3Xth7CL03kU,12800
40
+ pydantic_ai/models/cohere.py,sha256=GYhQ6jkCYDHf3ca1835aig9o59XTvsyw4ISAVThYejA,12828
41
41
  pydantic_ai/models/fallback.py,sha256=URaV-dTQWkg99xrlkmknue5lXZWDcEt7cJ1Vsky4oB4,5130
42
42
  pydantic_ai/models/function.py,sha256=iHhG6GYN14XDo3_qbdliv_umY10B7-k11aoDoVF4xP8,13563
43
- pydantic_ai/models/gemini.py,sha256=BMFEiDJXbB0DPj5DKK4kCwXuQHifT2WU-WuthJOqPsI,38138
44
- pydantic_ai/models/google.py,sha256=NNcr2jJlK3eFlSRyaTgDPuSjG2GxOOj0vYDrAfD6rbo,24394
45
- pydantic_ai/models/groq.py,sha256=8-sh8h2sJNZE6TiNUoiTKjmWghtCncxa3BX_xN979XQ,18854
46
- pydantic_ai/models/huggingface.py,sha256=06Rh0Q-p_2LPuny5RIooMx-NWD1rbbhLWP2wL4E6aq0,19019
43
+ pydantic_ai/models/gemini.py,sha256=J-05fngctXSqk3NzLaemt0h6r3S6jmr9ArvlWQE5Q0A,38124
44
+ pydantic_ai/models/google.py,sha256=PNN5Z5VYPioT0-FzS4PoZ33es26AfUqwMBLfHhrElnw,24380
45
+ pydantic_ai/models/groq.py,sha256=JX3Hi8tUJTsTj2A6CGoDhpW4IwNUxgOk0Ta58OCEL_A,19035
46
+ pydantic_ai/models/huggingface.py,sha256=g4Z2C_e_OddYyGKLSOtP4nCL-AbWxmOdkW4zFcFtLq0,19222
47
47
  pydantic_ai/models/instrumented.py,sha256=aqvzspcGexn1Molbu6Mn4EEPRBSoQCCCS_yknJvJJ-8,16205
48
48
  pydantic_ai/models/mcp_sampling.py,sha256=q9nnjNEAAbhrfRc_Qw5z9TtCHMG_SwlCWW9FvKWjh8k,3395
49
- pydantic_ai/models/mistral.py,sha256=u3LcPVqvdI2WHckffbj7zRT5oQn9yYdTRbtEN20Gqpw,31427
50
- pydantic_ai/models/openai.py,sha256=CJC5nU-b8HeKSa_4EbvTG_cmRjEnBjpoVbdfg_4ttyA,55834
51
- pydantic_ai/models/test.py,sha256=tkm6K0-G5Mc_iSqVzVIpU9VLil9dfkE1-5az8GGWwTI,18457
49
+ pydantic_ai/models/mistral.py,sha256=bj56Meckuji8r4vowiFJMDSli-HZktocqSqtbzgpXa0,31455
50
+ pydantic_ai/models/openai.py,sha256=Soqb7kZpQLBS6En7hVlhzBMlS07rjISJ9IlH96bBBBU,56122
51
+ pydantic_ai/models/test.py,sha256=lGMblastixKF_f5MhP3TcvLWx7jj94H4ohmL7DMpdGo,18482
52
52
  pydantic_ai/models/wrapper.py,sha256=A5-ncYhPF8c9S_czGoXkd55s2KOQb65p3jbVpwZiFPA,2043
53
- pydantic_ai/profiles/__init__.py,sha256=BXMqUpgRfosmYgcxjKAI9ESCj47JTSa30DhKXEgVLzM,2419
53
+ pydantic_ai/profiles/__init__.py,sha256=uC1_64Pb0O1IMt_SwzvU3W7a2_T3pvdoSDcm8_WI7hw,2592
54
54
  pydantic_ai/profiles/_json_schema.py,sha256=sTNHkaK0kbwmbldZp9JRGQNax0f5Qvwy0HkWuu_nGxU,7179
55
55
  pydantic_ai/profiles/amazon.py,sha256=O4ijm1Lpz01vaSiHrkSeGQhbCKV5lyQVtHYqh0pCW_k,339
56
- pydantic_ai/profiles/anthropic.py,sha256=DtTGh85tbkTrrrn2OrJ4FJKXWUIxUH_1Vw6y5fyMRyM,222
56
+ pydantic_ai/profiles/anthropic.py,sha256=J9N46G8eOjHdQ5CwZSLiwGdPb0eeIMdsMjwosDpvNhI,275
57
57
  pydantic_ai/profiles/cohere.py,sha256=lcL34Ht1jZopwuqoU6OV9l8vN4zwF-jiPjlsEABbSRo,215
58
58
  pydantic_ai/profiles/deepseek.py,sha256=DS_idprnXpMliKziKF0k1neLDJOwUvpatZ3YLaiYnCM,219
59
59
  pydantic_ai/profiles/google.py,sha256=cd5zwtx0MU1Xwm8c-oqi2_OJ2-PMJ8Vy23mxvSJF7ik,4856
@@ -83,7 +83,7 @@ pydantic_ai/providers/moonshotai.py,sha256=3BAE9eC9QaD3kblVwxtQWEln0-PhgK7bRvrYT
83
83
  pydantic_ai/providers/openai.py,sha256=7iGij0EaFylab7dTZAZDgXr78tr-HsZrn9EI9AkWBNQ,3091
84
84
  pydantic_ai/providers/openrouter.py,sha256=NXjNdnlXIBrBMMqbzcWQnowXOuZh4NHikXenBn5h3mc,4061
85
85
  pydantic_ai/providers/together.py,sha256=zFVSMSm5jXbpkNouvBOTjWrPmlPpCp6sQS5LMSyVjrQ,3482
86
- pydantic_ai/providers/vercel.py,sha256=JM1NmqLR64RvEmVWI8t2zGQdxOHJ-CguibOI0uSv-_Q,4061
86
+ pydantic_ai/providers/vercel.py,sha256=wFIfyfD2RCAVRWtveDDMjumOkP8v9AHy94KV1HXF180,4285
87
87
  pydantic_ai/toolsets/__init__.py,sha256=JCnqqAFeuHhmVW4XK0LM6Op_9B1cvsQUJ3vTmQ9Z5cQ,590
88
88
  pydantic_ai/toolsets/abstract.py,sha256=LqunlpwUsoHVn4VMtdjEoLY5kiMUF74PZ4KW539K8tQ,6027
89
89
  pydantic_ai/toolsets/combined.py,sha256=UBSZ5quJAm4aITkI4enOTJ6sEDndkJ2sKvT1sTeX5LU,3440
@@ -94,8 +94,8 @@ pydantic_ai/toolsets/prefixed.py,sha256=MIStkzUdiU0rk2Y6P19IrTBxspH5pTstGxsqCBt-
94
94
  pydantic_ai/toolsets/prepared.py,sha256=Zjfz6S8In6PBVxoKFN9sKPN984zO6t0awB7Lnq5KODw,1431
95
95
  pydantic_ai/toolsets/renamed.py,sha256=JuLHpi-hYPiSPlaTpN8WiXLiGsywYK0axi2lW2Qs75k,1637
96
96
  pydantic_ai/toolsets/wrapper.py,sha256=WjLoiM1WDuffSJ4mDS6pZrEZGHgZ421fjrqFcB66W94,1205
97
- pydantic_ai_slim-0.4.9.dist-info/METADATA,sha256=p2wcexoX1rrBSYBuKbm6ZMdCLnZnNFtClEhlqI8Iz60,4173
98
- pydantic_ai_slim-0.4.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
99
- pydantic_ai_slim-0.4.9.dist-info/entry_points.txt,sha256=kbKxe2VtDCYS06hsI7P3uZGxcVC08-FPt1rxeiMpIps,50
100
- pydantic_ai_slim-0.4.9.dist-info/licenses/LICENSE,sha256=vA6Jc482lEyBBuGUfD1pYx-cM7jxvLYOxPidZ30t_PQ,1100
101
- pydantic_ai_slim-0.4.9.dist-info/RECORD,,
97
+ pydantic_ai_slim-0.4.11.dist-info/METADATA,sha256=csPdqlBPAN-VkDDT1zV3WRxgwQLM_6saa0dNDI9Iyqs,4176
98
+ pydantic_ai_slim-0.4.11.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
99
+ pydantic_ai_slim-0.4.11.dist-info/entry_points.txt,sha256=kbKxe2VtDCYS06hsI7P3uZGxcVC08-FPt1rxeiMpIps,50
100
+ pydantic_ai_slim-0.4.11.dist-info/licenses/LICENSE,sha256=vA6Jc482lEyBBuGUfD1pYx-cM7jxvLYOxPidZ30t_PQ,1100
101
+ pydantic_ai_slim-0.4.11.dist-info/RECORD,,