pydantic-ai-slim 0.4.10__tar.gz → 0.5.0__tar.gz

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.

Files changed (102) hide show
  1. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/PKG-INFO +3 -3
  2. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/_function_schema.py +7 -4
  3. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/_parts_manager.py +8 -9
  4. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/_thinking_part.py +7 -12
  5. pydantic_ai_slim-0.5.0/pydantic_ai/ag_ui.py +688 -0
  6. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/agent.py +7 -5
  7. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/messages.py +37 -10
  8. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/models/__init__.py +2 -2
  9. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/models/cohere.py +1 -1
  10. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/models/gemini.py +1 -1
  11. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/models/google.py +1 -1
  12. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/models/groq.py +7 -3
  13. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/models/huggingface.py +7 -2
  14. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/models/mistral.py +1 -1
  15. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/models/openai.py +7 -3
  16. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/models/test.py +3 -1
  17. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/profiles/__init__.py +3 -0
  18. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/profiles/anthropic.py +1 -1
  19. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/profiles/openai.py +22 -12
  20. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/tools.py +13 -5
  21. pydantic_ai_slim-0.4.10/pydantic_ai/ag_ui.py +0 -658
  22. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/.gitignore +0 -0
  23. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/LICENSE +0 -0
  24. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/README.md +0 -0
  25. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/__init__.py +0 -0
  26. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/__main__.py +0 -0
  27. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/_a2a.py +0 -0
  28. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/_agent_graph.py +0 -0
  29. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/_cli.py +0 -0
  30. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/_griffe.py +0 -0
  31. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/_mcp.py +0 -0
  32. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/_output.py +0 -0
  33. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/_run_context.py +0 -0
  34. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/_system_prompt.py +0 -0
  35. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/_tool_manager.py +0 -0
  36. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/_utils.py +0 -0
  37. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/common_tools/__init__.py +0 -0
  38. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/common_tools/duckduckgo.py +0 -0
  39. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/common_tools/tavily.py +0 -0
  40. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/direct.py +0 -0
  41. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/exceptions.py +0 -0
  42. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/ext/__init__.py +0 -0
  43. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/ext/aci.py +0 -0
  44. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/ext/langchain.py +0 -0
  45. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/format_as_xml.py +0 -0
  46. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/format_prompt.py +0 -0
  47. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/mcp.py +0 -0
  48. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/models/anthropic.py +0 -0
  49. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/models/bedrock.py +0 -0
  50. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/models/fallback.py +0 -0
  51. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/models/function.py +0 -0
  52. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/models/instrumented.py +0 -0
  53. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/models/mcp_sampling.py +0 -0
  54. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/models/wrapper.py +0 -0
  55. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/output.py +0 -0
  56. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/profiles/_json_schema.py +0 -0
  57. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/profiles/amazon.py +0 -0
  58. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/profiles/cohere.py +0 -0
  59. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/profiles/deepseek.py +0 -0
  60. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/profiles/google.py +0 -0
  61. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/profiles/grok.py +0 -0
  62. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/profiles/meta.py +0 -0
  63. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/profiles/mistral.py +0 -0
  64. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/profiles/moonshotai.py +0 -0
  65. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/profiles/qwen.py +0 -0
  66. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/__init__.py +0 -0
  67. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/anthropic.py +0 -0
  68. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/azure.py +0 -0
  69. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/bedrock.py +0 -0
  70. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/cohere.py +0 -0
  71. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/deepseek.py +0 -0
  72. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/fireworks.py +0 -0
  73. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/github.py +0 -0
  74. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/google.py +0 -0
  75. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/google_gla.py +0 -0
  76. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/google_vertex.py +0 -0
  77. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/grok.py +0 -0
  78. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/groq.py +0 -0
  79. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/heroku.py +0 -0
  80. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/huggingface.py +0 -0
  81. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/mistral.py +0 -0
  82. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/moonshotai.py +0 -0
  83. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/openai.py +0 -0
  84. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/openrouter.py +0 -0
  85. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/together.py +0 -0
  86. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/providers/vercel.py +0 -0
  87. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/py.typed +0 -0
  88. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/result.py +0 -0
  89. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/retries.py +0 -0
  90. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/settings.py +0 -0
  91. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/toolsets/__init__.py +0 -0
  92. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/toolsets/abstract.py +0 -0
  93. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/toolsets/combined.py +0 -0
  94. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/toolsets/deferred.py +0 -0
  95. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/toolsets/filtered.py +0 -0
  96. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/toolsets/function.py +0 -0
  97. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/toolsets/prefixed.py +0 -0
  98. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/toolsets/prepared.py +0 -0
  99. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/toolsets/renamed.py +0 -0
  100. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/toolsets/wrapper.py +0 -0
  101. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pydantic_ai/usage.py +0 -0
  102. {pydantic_ai_slim-0.4.10 → pydantic_ai_slim-0.5.0}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydantic-ai-slim
3
- Version: 0.4.10
3
+ Version: 0.5.0
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.10
33
+ Requires-Dist: pydantic-graph==0.5.0
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.10; extra == 'evals'
54
+ Requires-Dist: pydantic-evals==0.5.0; extra == 'evals'
55
55
  Provides-Extra: google
56
56
  Requires-Dist: google-genai>=1.24.0; extra == 'google'
57
57
  Provides-Extra: groq
@@ -154,9 +154,13 @@ def function_schema( # noqa: C901
154
154
  if p.kind == Parameter.VAR_POSITIONAL:
155
155
  annotation = list[annotation]
156
156
 
157
- # FieldInfo.from_annotation expects a type, `annotation` is Any
157
+ required = p.default is Parameter.empty
158
+ # FieldInfo.from_annotated_attribute expects a type, `annotation` is Any
158
159
  annotation = cast(type[Any], annotation)
159
- field_info = FieldInfo.from_annotation(annotation)
160
+ if required:
161
+ field_info = FieldInfo.from_annotation(annotation)
162
+ else:
163
+ field_info = FieldInfo.from_annotated_attribute(annotation, p.default)
160
164
  if field_info.description is None:
161
165
  field_info.description = field_descriptions.get(field_name)
162
166
 
@@ -164,7 +168,7 @@ def function_schema( # noqa: C901
164
168
  field_name,
165
169
  field_info,
166
170
  decorators,
167
- required=p.default is Parameter.empty,
171
+ required=required,
168
172
  )
169
173
  # noinspection PyTypeChecker
170
174
  td_schema.setdefault('metadata', {})['is_model_like'] = is_model_like(annotation)
@@ -281,7 +285,6 @@ def _build_schema(
281
285
  td_schema = core_schema.typed_dict_schema(
282
286
  fields,
283
287
  config=core_config,
284
- total=var_kwargs_schema is None,
285
288
  extras_schema=gen_schema.generate_schema(var_kwargs_schema) if var_kwargs_schema else None,
286
289
  )
287
290
  return td_schema, None
@@ -17,7 +17,6 @@ from collections.abc import Hashable
17
17
  from dataclasses import dataclass, field, replace
18
18
  from typing import Any, Union
19
19
 
20
- from pydantic_ai._thinking_part import END_THINK_TAG, START_THINK_TAG
21
20
  from pydantic_ai.exceptions import UnexpectedModelBehavior
22
21
  from pydantic_ai.messages import (
23
22
  ModelResponsePart,
@@ -72,7 +71,7 @@ class ModelResponsePartsManager:
72
71
  *,
73
72
  vendor_part_id: VendorId | None,
74
73
  content: str,
75
- extract_think_tags: bool = False,
74
+ thinking_tags: tuple[str, str] | None = None,
76
75
  ) -> ModelResponseStreamEvent | None:
77
76
  """Handle incoming text content, creating or updating a TextPart in the manager as appropriate.
78
77
 
@@ -85,7 +84,7 @@ class ModelResponsePartsManager:
85
84
  of text. If None, a new part will be created unless the latest part is already
86
85
  a TextPart.
87
86
  content: The text content to append to the appropriate TextPart.
88
- extract_think_tags: Whether to extract `<think>` tags from the text content and handle them as thinking parts.
87
+ thinking_tags: If provided, will handle content between the thinking tags as thinking parts.
89
88
 
90
89
  Returns:
91
90
  - A `PartStartEvent` if a new part was created.
@@ -110,10 +109,10 @@ class ModelResponsePartsManager:
110
109
  if part_index is not None:
111
110
  existing_part = self._parts[part_index]
112
111
 
113
- if extract_think_tags and isinstance(existing_part, ThinkingPart):
114
- # We may be building a thinking part instead of a text part if we had previously seen a `<think>` tag
115
- if content == END_THINK_TAG:
116
- # When we see `</think>`, we're done with the thinking part and the next text delta will need a new part
112
+ if thinking_tags and isinstance(existing_part, ThinkingPart):
113
+ # We may be building a thinking part instead of a text part if we had previously seen a thinking tag
114
+ if content == thinking_tags[1]:
115
+ # When we see the thinking end tag, we're done with the thinking part and the next text delta will need a new part
117
116
  self._vendor_id_to_part_index.pop(vendor_part_id)
118
117
  return None
119
118
  else:
@@ -123,8 +122,8 @@ class ModelResponsePartsManager:
123
122
  else:
124
123
  raise UnexpectedModelBehavior(f'Cannot apply a text delta to {existing_part=}')
125
124
 
126
- if extract_think_tags and content == START_THINK_TAG:
127
- # When we see a `<think>` tag (which is a single token), we'll build a new thinking part instead
125
+ if thinking_tags and content == thinking_tags[0]:
126
+ # When we see a thinking start tag (which is a single token), we'll build a new thinking part instead
128
127
  self._vendor_id_to_part_index.pop(vendor_part_id, None)
129
128
  return self.handle_thinking_delta(vendor_part_id=vendor_part_id, content='')
130
129
 
@@ -2,35 +2,30 @@ from __future__ import annotations as _annotations
2
2
 
3
3
  from pydantic_ai.messages import TextPart, ThinkingPart
4
4
 
5
- START_THINK_TAG = '<think>'
6
- END_THINK_TAG = '</think>'
7
5
 
8
-
9
- def split_content_into_text_and_thinking(content: str) -> list[ThinkingPart | TextPart]:
6
+ def split_content_into_text_and_thinking(content: str, thinking_tags: tuple[str, str]) -> list[ThinkingPart | TextPart]:
10
7
  """Split a string into text and thinking parts.
11
8
 
12
9
  Some models don't return the thinking part as a separate part, but rather as a tag in the content.
13
10
  This function splits the content into text and thinking parts.
14
-
15
- We use the `<think>` tag because that's how Groq uses it in the `raw` format, so instead of using `<Thinking>` or
16
- something else, we just match the tag to make it easier for other models that don't support the `ThinkingPart`.
17
11
  """
12
+ start_tag, end_tag = thinking_tags
18
13
  parts: list[ThinkingPart | TextPart] = []
19
14
 
20
- start_index = content.find(START_THINK_TAG)
15
+ start_index = content.find(start_tag)
21
16
  while start_index >= 0:
22
- before_think, content = content[:start_index], content[start_index + len(START_THINK_TAG) :]
17
+ before_think, content = content[:start_index], content[start_index + len(start_tag) :]
23
18
  if before_think:
24
19
  parts.append(TextPart(content=before_think))
25
- end_index = content.find(END_THINK_TAG)
20
+ end_index = content.find(end_tag)
26
21
  if end_index >= 0:
27
- think_content, content = content[:end_index], content[end_index + len(END_THINK_TAG) :]
22
+ think_content, content = content[:end_index], content[end_index + len(end_tag) :]
28
23
  parts.append(ThinkingPart(content=think_content))
29
24
  else:
30
25
  # We lose the `<think>` tag, but it shouldn't matter.
31
26
  parts.append(TextPart(content=content))
32
27
  content = ''
33
- start_index = content.find(START_THINK_TAG)
28
+ start_index = content.find(start_tag)
34
29
  if content:
35
30
  parts.append(TextPart(content=content))
36
31
  return parts