pyagentic-core 2.1.0a3__tar.gz → 2.2.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.1.0a3 → pyagentic_core-2.2.0a1}/PKG-INFO +2 -1
  2. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/_base/_agent/_agent.py +33 -0
  3. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/_base/_agent/_agent_state.py +3 -2
  4. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic_core.egg-info/PKG-INFO +2 -1
  5. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic_core.egg-info/requires.txt +1 -0
  6. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyproject.toml +3 -2
  7. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/LICENSE +0 -0
  8. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/README.md +0 -0
  9. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/__init__.py +0 -0
  10. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/_base/__init__.py +0 -0
  11. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/_base/_agent/__init__.py +0 -0
  12. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/_base/_agent/_agent_linking.py +0 -0
  13. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/_base/_exceptions.py +0 -0
  14. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/_base/_info.py +0 -0
  15. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/_base/_metaclasses.py +0 -0
  16. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/_base/_ref.py +0 -0
  17. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/_base/_spec.py +0 -0
  18. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/_base/_state.py +0 -0
  19. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/_base/_tool.py +0 -0
  20. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/_base/_validation.py +0 -0
  21. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/_utils/_typing.py +0 -0
  22. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/_utils/_warnings.py +0 -0
  23. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/llm/__init__.py +0 -0
  24. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/llm/_anthropic.py +0 -0
  25. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/llm/_gemini.py +0 -0
  26. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/llm/_mock.py +0 -0
  27. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/llm/_openai.py +0 -0
  28. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/llm/_openaiv1.py +0 -0
  29. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/llm/_provider.py +0 -0
  30. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/logging.py +0 -0
  31. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/models/llm.py +0 -0
  32. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/models/response.py +0 -0
  33. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/models/tracing.py +0 -0
  34. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/policies/__init__.py +0 -0
  35. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/policies/_events.py +0 -0
  36. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/policies/_policy.py +0 -0
  37. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/tracing/__init__.py +0 -0
  38. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/tracing/_basic.py +0 -0
  39. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/tracing/_langfuse.py +0 -0
  40. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/tracing/_tracer.py +0 -0
  41. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic/updates.py +0 -0
  42. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic_core.egg-info/SOURCES.txt +0 -0
  43. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic_core.egg-info/dependency_links.txt +0 -0
  44. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/pyagentic_core.egg-info/top_level.txt +0 -0
  45. {pyagentic_core-2.1.0a3 → pyagentic_core-2.2.0a1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyagentic-core
3
- Version: 2.1.0a3
3
+ Version: 2.2.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
@@ -20,6 +20,7 @@ Requires-Dist: typeguard>=4.4.4
20
20
  Requires-Dist: c3linearize>=0.1.0
21
21
  Requires-Dist: anthropic>=0.62.0
22
22
  Requires-Dist: google-generativeai>=0.8.0
23
+ Requires-Dist: transitions>=0.9.3
23
24
  Dynamic: license-file
24
25
 
25
26
  # PyAgentic
@@ -13,6 +13,7 @@ from typing import (
13
13
  Union,
14
14
  )
15
15
 
16
+ from transitions import Machine
16
17
  from pydantic import BaseModel, ValidationError
17
18
 
18
19
  from pyagentic.logging import get_logger
@@ -165,8 +166,10 @@ class BaseAgent(metaclass=AgentMeta):
165
166
  __description__: ClassVar[str] # Optional: description for linked agents
166
167
  __input_template__: ClassVar[str] = None # Optional: template for user input
167
168
  __response_format__: ClassVar[Type[BaseModel]] = None # Optional: structured output format
169
+ phases: ClassVar[list[tuple[str, str, Callable]]] = None
168
170
 
169
171
  # Generated Class Attributes (built by metaclass)
172
+ __machine__: Machine | None = None
170
173
  __response_model__: ClassVar[Type[AgentResponse]] = None # Pydantic response model
171
174
  __state_class__: ClassVar[Type[_AgentState]] = None # Generated state class
172
175
  __tool_response_models__: ClassVar[dict[str, Type[ToolResponse]]] # Tool response models
@@ -229,6 +232,34 @@ class BaseAgent(metaclass=AgentMeta):
229
232
  if self.__tool_defs__ and not self.provider.__supports_tool_calls__:
230
233
  raise Exception("Tools are not supported with this provider")
231
234
 
235
+ def _build_phase_machine(self) -> Machine:
236
+ if not self.phases:
237
+ return None
238
+
239
+ states = []
240
+ for to_, from_, _ in self.phases:
241
+ if to_ not in states:
242
+ states.append(to_)
243
+ if from_ not in states:
244
+ states.append(from_)
245
+
246
+ machine = Machine(states=states, initial=states[0])
247
+
248
+ for to_, from_, _ in self.phases:
249
+ machine.add_transition(
250
+ trigger=f"{to_}_to_{from_}",
251
+ source=to_,
252
+ dest=from_,
253
+ )
254
+
255
+ return machine
256
+
257
+ def _update_state_machine(self):
258
+ for to_, from_, condition in self.phases:
259
+ if condition(self.state):
260
+ trigger = f"{to_}_to_{from_}"
261
+ getattr(self.__machine__, trigger)()
262
+
232
263
  def __post_init__(self):
233
264
  """
234
265
  Post-initialization hook called after agent instance is created.
@@ -250,6 +281,7 @@ class BaseAgent(metaclass=AgentMeta):
250
281
  ```
251
282
  """
252
283
  self._check_llm_provider()
284
+ self.__machine__ = self._build_phase_machine()
253
285
 
254
286
  # Use BasicTracer as default if no tracer provided
255
287
  if not self.tracer:
@@ -547,6 +579,7 @@ class BaseAgent(metaclass=AgentMeta):
547
579
  yield result
548
580
 
549
581
  # Increment depth and continue loop (LLM will see tool results next iteration)
582
+ self._update_state_machine()
550
583
  depth += 1
551
584
 
552
585
  # If we exhausted max_call_depth without final text, get one more response
@@ -1,9 +1,10 @@
1
1
  import asyncio
2
2
  import threading
3
3
  from typing import Any, Type, Self, Optional, ClassVar
4
- from pydantic import BaseModel, create_model, Field, PrivateAttr
4
+ from pydantic import BaseModel, create_model, Field, PrivateAttr, ConfigDict
5
5
  from jinja2 import Template
6
- from typing import Optional, Literal
6
+ from typing import Optional, Literal, Callable
7
+ from transitions import Machine
7
8
 
8
9
  from pyagentic._base._exceptions import InvalidStateRefNotFoundInState
9
10
  from pyagentic._base._state import _StateDefinition
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyagentic-core
3
- Version: 2.1.0a3
3
+ Version: 2.2.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
@@ -20,6 +20,7 @@ Requires-Dist: typeguard>=4.4.4
20
20
  Requires-Dist: c3linearize>=0.1.0
21
21
  Requires-Dist: anthropic>=0.62.0
22
22
  Requires-Dist: google-generativeai>=0.8.0
23
+ Requires-Dist: transitions>=0.9.3
23
24
  Dynamic: license-file
24
25
 
25
26
  # PyAgentic
@@ -8,3 +8,4 @@ typeguard>=4.4.4
8
8
  c3linearize>=0.1.0
9
9
  anthropic>=0.62.0
10
10
  google-generativeai>=0.8.0
11
+ transitions>=0.9.3
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pyagentic-core"
3
- version = "2.1.0-a.3"
3
+ version = "2.2.0-a.1"
4
4
  description = "Build LLM Agents in a Pythonic way"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.13"
@@ -23,6 +23,7 @@ dependencies = [
23
23
  "c3linearize>=0.1.0",
24
24
  "anthropic>=0.62.0",
25
25
  "google-generativeai>=0.8.0",
26
+ "transitions>=0.9.3",
26
27
  ]
27
28
 
28
29
  [dependency-groups]
@@ -105,4 +106,4 @@ include = ["pyagentic*"]
105
106
  compile-diagrams = "for file in docs/diagrams/source/*.d2; do d2 --layout elk \"$file\" \"docs/diagrams/$(basename \"$file\" .d2).svg\"; done"
106
107
  build-docs = "task compile-diagrams && mkdocs build --clean"
107
108
  serve-docs = "task compile-diagrams && mkdocs serve"
108
- deploy-docs = "task compile-diagrams && mkdocs gh-deploy --force"
109
+ deploy-docs = "task compile-diagrams && mkdocs gh-deploy --force"