pyagentic-core 2.2.1a2__tar.gz → 2.3.0a1__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.
Files changed (45) hide show
  1. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/PKG-INFO +2 -1
  2. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/_base/_agent/_agent_state.py +3 -3
  3. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/llm/_openai.py +36 -2
  4. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/llm/_provider.py +2 -0
  5. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic_core.egg-info/PKG-INFO +2 -1
  6. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic_core.egg-info/requires.txt +1 -0
  7. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyproject.toml +2 -1
  8. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/LICENSE +0 -0
  9. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/README.md +0 -0
  10. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/__init__.py +0 -0
  11. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/_base/__init__.py +0 -0
  12. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/_base/_agent/__init__.py +0 -0
  13. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/_base/_agent/_agent.py +0 -0
  14. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/_base/_agent/_agent_linking.py +0 -0
  15. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/_base/_exceptions.py +0 -0
  16. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/_base/_info.py +0 -0
  17. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/_base/_metaclasses.py +0 -0
  18. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/_base/_ref.py +0 -0
  19. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/_base/_spec.py +0 -0
  20. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/_base/_state.py +0 -0
  21. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/_base/_tool.py +0 -0
  22. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/_base/_validation.py +0 -0
  23. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/_utils/_typing.py +0 -0
  24. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/_utils/_warnings.py +0 -0
  25. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/llm/__init__.py +0 -0
  26. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/llm/_anthropic.py +0 -0
  27. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/llm/_gemini.py +0 -0
  28. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/llm/_mock.py +0 -0
  29. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/llm/_openaiv1.py +0 -0
  30. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/logging.py +0 -0
  31. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/models/llm.py +0 -0
  32. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/models/response.py +0 -0
  33. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/models/tracing.py +0 -0
  34. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/policies/__init__.py +0 -0
  35. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/policies/_events.py +0 -0
  36. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/policies/_policy.py +0 -0
  37. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/tracing/__init__.py +0 -0
  38. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/tracing/_basic.py +0 -0
  39. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/tracing/_langfuse.py +0 -0
  40. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/tracing/_tracer.py +0 -0
  41. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic/updates.py +0 -0
  42. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic_core.egg-info/SOURCES.txt +0 -0
  43. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic_core.egg-info/dependency_links.txt +0 -0
  44. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/pyagentic_core.egg-info/top_level.txt +0 -0
  45. {pyagentic_core-2.2.1a2 → pyagentic_core-2.3.0a1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyagentic-core
3
- Version: 2.2.1a2
3
+ Version: 2.3.0a1
4
4
  Summary: Build LLM Agents in a Pythonic way
5
5
  Author-email: Ryan Mikulec <rmikulec.dev@gmail.com>
6
6
  License: MIT
@@ -21,6 +21,7 @@ Requires-Dist: c3linearize>=0.1.0
21
21
  Requires-Dist: anthropic>=0.62.0
22
22
  Requires-Dist: google-generativeai>=0.8.0
23
23
  Requires-Dist: transitions>=0.9.3
24
+ Requires-Dist: pillow>=12.1.0
24
25
  Dynamic: license-file
25
26
 
26
27
  # PyAgentic
@@ -60,10 +60,10 @@ class _AgentState(BaseModel):
60
60
  self._machine = machine
61
61
 
62
62
  def _update_state_machine(self, phases):
63
- for to_, from_, condition in phases:
63
+ for source, dest, condition in phases:
64
64
  with self._state_lock:
65
- if condition(self) and self.phase == from_:
66
- trigger = f"{to_}_to_{from_}"
65
+ if condition(self) and self.phase == source:
66
+ trigger = f"{source}_to_{dest}"
67
67
  getattr(self._machine, trigger)()
68
68
 
69
69
  def model_post_init(self, state):
@@ -9,8 +9,11 @@ import openai
9
9
  from openai.types.responses import Response as OpenAIResponse
10
10
  from openai.types.responses import ParsedResponse as OpenAIParsedResponse
11
11
 
12
+ import base64
13
+ import io
12
14
  from typing import List, Optional, Type
13
15
  from pydantic import BaseModel
16
+ from PIL.Image import Image
14
17
 
15
18
  from pyagentic._base._agent._agent_state import _AgentState
16
19
  from pyagentic._base._tool import _ToolDefinition
@@ -85,10 +88,27 @@ class OpenAIProvider(LLMProvider):
85
88
  """
86
89
  return OpenAIMessage(type="function_call_output", call_id=id_, output=result)
87
90
 
91
+ def _encode_image(self, image: Image) -> str:
92
+ """
93
+ Convert a PIL Image to a base64-encoded data URL.
94
+
95
+ Args:
96
+ image: PIL Image object to encode
97
+
98
+ Returns:
99
+ Base64-encoded data URL string
100
+ """
101
+ buffer = io.BytesIO()
102
+ image.save(buffer, format="PNG")
103
+ image_bytes = buffer.getvalue()
104
+ base64_image = base64.b64encode(image_bytes).decode("utf-8")
105
+ return f"data:image/png;base64,{base64_image}"
106
+
88
107
  async def generate(
89
108
  self,
90
109
  state: _AgentState,
91
110
  *,
111
+ images: Optional[Image] = None,
92
112
  tool_defs: Optional[List[_ToolDefinition]] = None,
93
113
  response_format: Optional[Type[BaseModel]] = None,
94
114
  **kwargs,
@@ -102,6 +122,7 @@ class OpenAIProvider(LLMProvider):
102
122
 
103
123
  Args:
104
124
  state: Agent state containing conversation history and system messages
125
+ images: Optional PIL Image to include in the request
105
126
  tool_defs: List of available tools the model can call
106
127
  response_format: Optional Pydantic model for structured output
107
128
  **kwargs: Additional parameters for the OpenAI API call
@@ -113,11 +134,24 @@ class OpenAIProvider(LLMProvider):
113
134
  if tool_defs is None:
114
135
  tool_defs = []
115
136
 
137
+ # Prepare input messages
138
+ input_messages = [message.to_dict() for message in state._messages]
139
+
140
+ # Add image if provided
141
+ if images:
142
+ image_url = self._encode_image(images)
143
+ # Add image as a user message with image content
144
+ image_message = {
145
+ "role": "user",
146
+ "content": [{"type": "image_url", "image_url": {"url": image_url}}],
147
+ }
148
+ input_messages.append(image_message)
149
+
116
150
  if response_format:
117
151
  response: OpenAIParsedResponse[Type[BaseModel]] = await self.client.responses.parse(
118
152
  model=self._model,
119
153
  instructions=state.system_message,
120
- input=[message.to_dict() for message in state._messages],
154
+ input=input_messages,
121
155
  tools=[tool.to_openai_spec() for tool in tool_defs],
122
156
  text_format=response_format,
123
157
  **kwargs,
@@ -142,7 +176,7 @@ class OpenAIProvider(LLMProvider):
142
176
  response: OpenAIResponse = await self.client.responses.create(
143
177
  model=self._model,
144
178
  instructions=state.system_message,
145
- input=[message.to_dict() for message in state._messages],
179
+ input=input_messages,
146
180
  tools=[tool.to_openai_spec() for tool in tool_defs],
147
181
  **kwargs,
148
182
  )
@@ -8,6 +8,7 @@ compatible with the pyagentic framework.
8
8
  from typing import Optional, Type
9
9
  from abc import ABC, abstractmethod
10
10
  from pydantic import BaseModel
11
+ from PIL.Image import Image
11
12
 
12
13
  from pyagentic._base._tool import _ToolDefinition
13
14
  from pyagentic._base._agent._agent_state import _AgentState
@@ -80,6 +81,7 @@ class LLMProvider(ABC):
80
81
  self,
81
82
  state: _AgentState,
82
83
  *,
84
+ images: Optional[Image] = None,
83
85
  tool_defs: Optional[list[_ToolDefinition]] = None,
84
86
  response_format: Optional[Type[BaseModel]] = None,
85
87
  **kwargs,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyagentic-core
3
- Version: 2.2.1a2
3
+ Version: 2.3.0a1
4
4
  Summary: Build LLM Agents in a Pythonic way
5
5
  Author-email: Ryan Mikulec <rmikulec.dev@gmail.com>
6
6
  License: MIT
@@ -21,6 +21,7 @@ Requires-Dist: c3linearize>=0.1.0
21
21
  Requires-Dist: anthropic>=0.62.0
22
22
  Requires-Dist: google-generativeai>=0.8.0
23
23
  Requires-Dist: transitions>=0.9.3
24
+ Requires-Dist: pillow>=12.1.0
24
25
  Dynamic: license-file
25
26
 
26
27
  # PyAgentic
@@ -9,3 +9,4 @@ c3linearize>=0.1.0
9
9
  anthropic>=0.62.0
10
10
  google-generativeai>=0.8.0
11
11
  transitions>=0.9.3
12
+ pillow>=12.1.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pyagentic-core"
3
- version = "2.2.1-a.2"
3
+ version = "2.3.0-a.1"
4
4
  description = "Build LLM Agents in a Pythonic way"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.13"
@@ -24,6 +24,7 @@ dependencies = [
24
24
  "anthropic>=0.62.0",
25
25
  "google-generativeai>=0.8.0",
26
26
  "transitions>=0.9.3",
27
+ "pillow>=12.1.0",
27
28
  ]
28
29
 
29
30
  [dependency-groups]