pyagentic-core 2.0.0b1__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.
- pyagentic_core-2.0.0b1/LICENSE +21 -0
- pyagentic_core-2.0.0b1/PKG-INFO +261 -0
- pyagentic_core-2.0.0b1/README.md +237 -0
- pyagentic_core-2.0.0b1/pyagentic/__init__.py +46 -0
- pyagentic_core-2.0.0b1/pyagentic/_base/__init__.py +0 -0
- pyagentic_core-2.0.0b1/pyagentic/_base/_agent/__init__.py +0 -0
- pyagentic_core-2.0.0b1/pyagentic/_base/_agent/_agent.py +687 -0
- pyagentic_core-2.0.0b1/pyagentic/_base/_agent/_agent_linking.py +65 -0
- pyagentic_core-2.0.0b1/pyagentic/_base/_agent/_agent_state.py +274 -0
- pyagentic_core-2.0.0b1/pyagentic/_base/_exceptions.py +115 -0
- pyagentic_core-2.0.0b1/pyagentic/_base/_info.py +84 -0
- pyagentic_core-2.0.0b1/pyagentic/_base/_metaclasses.py +543 -0
- pyagentic_core-2.0.0b1/pyagentic/_base/_ref.py +110 -0
- pyagentic_core-2.0.0b1/pyagentic/_base/_spec.py +133 -0
- pyagentic_core-2.0.0b1/pyagentic/_base/_state.py +67 -0
- pyagentic_core-2.0.0b1/pyagentic/_base/_tool.py +287 -0
- pyagentic_core-2.0.0b1/pyagentic/_base/_validation.py +94 -0
- pyagentic_core-2.0.0b1/pyagentic/_utils/_typing.py +122 -0
- pyagentic_core-2.0.0b1/pyagentic/_utils/_warnings.py +46 -0
- pyagentic_core-2.0.0b1/pyagentic/llm/__init__.py +32 -0
- pyagentic_core-2.0.0b1/pyagentic/llm/_anthropic.py +178 -0
- pyagentic_core-2.0.0b1/pyagentic/llm/_gemini.py +296 -0
- pyagentic_core-2.0.0b1/pyagentic/llm/_mock.py +119 -0
- pyagentic_core-2.0.0b1/pyagentic/llm/_openai.py +162 -0
- pyagentic_core-2.0.0b1/pyagentic/llm/_openaiv1.py +221 -0
- pyagentic_core-2.0.0b1/pyagentic/llm/_provider.py +99 -0
- pyagentic_core-2.0.0b1/pyagentic/logging.py +70 -0
- pyagentic_core-2.0.0b1/pyagentic/models/llm.py +92 -0
- pyagentic_core-2.0.0b1/pyagentic/models/response.py +114 -0
- pyagentic_core-2.0.0b1/pyagentic/models/tracing.py +55 -0
- pyagentic_core-2.0.0b1/pyagentic/policies/__init__.py +3 -0
- pyagentic_core-2.0.0b1/pyagentic/policies/_events.py +69 -0
- pyagentic_core-2.0.0b1/pyagentic/policies/_policy.py +64 -0
- pyagentic_core-2.0.0b1/pyagentic/tracing/__init__.py +5 -0
- pyagentic_core-2.0.0b1/pyagentic/tracing/_basic.py +264 -0
- pyagentic_core-2.0.0b1/pyagentic/tracing/_langfuse.py +378 -0
- pyagentic_core-2.0.0b1/pyagentic/tracing/_tracer.py +241 -0
- pyagentic_core-2.0.0b1/pyagentic/updates.py +42 -0
- pyagentic_core-2.0.0b1/pyagentic_core.egg-info/PKG-INFO +261 -0
- pyagentic_core-2.0.0b1/pyagentic_core.egg-info/SOURCES.txt +43 -0
- pyagentic_core-2.0.0b1/pyagentic_core.egg-info/dependency_links.txt +1 -0
- pyagentic_core-2.0.0b1/pyagentic_core.egg-info/requires.txt +10 -0
- pyagentic_core-2.0.0b1/pyagentic_core.egg-info/top_level.txt +1 -0
- pyagentic_core-2.0.0b1/pyproject.toml +108 -0
- pyagentic_core-2.0.0b1/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Ryan Mikulec
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyagentic-core
|
|
3
|
+
Version: 2.0.0b1
|
|
4
|
+
Summary: Build LLM Agents in a Pythonic way
|
|
5
|
+
Author-email: Ryan Mikulec <rmikulec.dev@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Requires-Python: >=3.13
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: colorlog>=6.9.0
|
|
14
|
+
Requires-Dist: dotenv>=0.9.9
|
|
15
|
+
Requires-Dist: ipykernel>=6.29.5
|
|
16
|
+
Requires-Dist: taskipy>=1.14.1
|
|
17
|
+
Requires-Dist: openai>=1.99.3
|
|
18
|
+
Requires-Dist: pydantic>=2.11.7
|
|
19
|
+
Requires-Dist: typeguard>=4.4.4
|
|
20
|
+
Requires-Dist: c3linearize>=0.1.0
|
|
21
|
+
Requires-Dist: anthropic>=0.62.0
|
|
22
|
+
Requires-Dist: google-generativeai>=0.8.0
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# PyAgentic
|
|
26
|
+
|
|
27
|
+
[](https://www.python.org/downloads/)
|
|
28
|
+
[](https://opensource.org/licenses/MIT)
|
|
29
|
+
[](https://github.com/psf/black)
|
|
30
|
+
[](https://github.com/rmikulec/pyAgentic/actions/workflows/testing.yml?query=branch%3Amain)
|
|
31
|
+
|
|
32
|
+
A declarative, type-safe framework for building AI agents with OpenAI integration. PyAgentic lets you create sophisticated LLM agents using clean Python class syntax, with full support for tools, persistent state, agent linking, and agent inheritance.
|
|
33
|
+
|
|
34
|
+
## Documentation
|
|
35
|
+
|
|
36
|
+
Read the **[Getting Started](https://rmikulec.github.io/pyAgentic/getting-started/)**!
|
|
37
|
+
|
|
38
|
+
Complete documentation, tutorials, and examples can be found **[here](https://rmikulec.github.io/pyagentic)**
|
|
39
|
+
|
|
40
|
+
## Features
|
|
41
|
+
|
|
42
|
+
- **Declarative Design** - Define agents with simple class-based syntax and decorators
|
|
43
|
+
- **Powerful Tools** - Easy `@tool` decoration with automatic OpenAI schema generation
|
|
44
|
+
- **Persistent State** - Stateful agents with `State` fields that persist across conversations
|
|
45
|
+
- **Agent Linking** - Compose complex workflows by linking agents together
|
|
46
|
+
- **Structured Responses** - Type-safe Pydantic responses with full tool execution details
|
|
47
|
+
- **Dynamic Constraints** - Use `ref` to create smart parameter validation
|
|
48
|
+
- **Inheritance & Extensions** - Build agent hierarchies and mix in cross-cutting capabilities
|
|
49
|
+
- **Native Async Support** - Built for scalable applications with async/await throughout
|
|
50
|
+
- **Type Safety** - Complete typing support with validation and IDE autocompletion
|
|
51
|
+
|
|
52
|
+
## Quick Start
|
|
53
|
+
|
|
54
|
+
### Installation
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install pyagentic-core
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Simple Agent Example
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from pyagentic import BaseAgent, tool, State, spec
|
|
64
|
+
|
|
65
|
+
class ResearchAgent(BaseAgent):
|
|
66
|
+
__system_message__ = "I help with research tasks and maintain a collection of papers"
|
|
67
|
+
|
|
68
|
+
# Persistent state that survives across conversations
|
|
69
|
+
paper_count: State[int] = spec.State(default=0)
|
|
70
|
+
current_topic: State[str] = spec.State(default="general", access="write")
|
|
71
|
+
|
|
72
|
+
@tool("Search for academic papers")
|
|
73
|
+
def search_papers(self, query: str, max_results: int = 5) -> str:
|
|
74
|
+
# Your search logic here
|
|
75
|
+
self.paper_count += max_results
|
|
76
|
+
return f"Found {max_results} papers about '{query}'"
|
|
77
|
+
|
|
78
|
+
# Create and use the agent
|
|
79
|
+
agent = ResearchAgent(model="openai::gpt-4", api_key="your-key")
|
|
80
|
+
response = await agent("Help me research machine learning papers")
|
|
81
|
+
|
|
82
|
+
# Access structured response data
|
|
83
|
+
print(response.final_output) # Natural language response
|
|
84
|
+
print(len(response.tool_responses)) # Number of tools called
|
|
85
|
+
print(agent.paper_count) # Persistent state
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Advanced Features
|
|
89
|
+
|
|
90
|
+
#### Agent Linking
|
|
91
|
+
Create multi-agent workflows where agents can call other agents as tools:
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
class DatabaseAgent(BaseAgent):
|
|
95
|
+
__system_message__ = "I query databases"
|
|
96
|
+
__description__ = "Retrieves data from SQL databases"
|
|
97
|
+
|
|
98
|
+
@tool("Execute SQL query")
|
|
99
|
+
def query(self, sql: str) -> str: ...
|
|
100
|
+
|
|
101
|
+
class WebAgent(BaseAgent):
|
|
102
|
+
__system_message__ = "I search the web"
|
|
103
|
+
__description__ = "Searches the internet"
|
|
104
|
+
|
|
105
|
+
@tool("search")
|
|
106
|
+
def search(self, terms: list[str]) -> str: ...
|
|
107
|
+
|
|
108
|
+
class ReportAgent(BaseAgent):
|
|
109
|
+
__system_message__ = "I generate business reports"
|
|
110
|
+
database: DatabaseAgent # Linked agent appears as a tool
|
|
111
|
+
searcher: WebAgent
|
|
112
|
+
|
|
113
|
+
@tool("Create visualization")
|
|
114
|
+
def create_chart(self, data: str) -> str: ...
|
|
115
|
+
|
|
116
|
+
# The report agent can automatically coordinate with the database agent
|
|
117
|
+
report_agent = ReportAgent(database=DatabaseAgent(...), searcher=WebAgent(...))
|
|
118
|
+
response = await report_agent("Generate a plot of the latest financial data")
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
#### Dynamic Parameter Constraints
|
|
122
|
+
Use `ref` with Pydantic computed fields to create intelligent parameter validation:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from pydantic import BaseModel, computed_field
|
|
126
|
+
from pyagentic import ref, spec
|
|
127
|
+
|
|
128
|
+
class DatasetState(BaseModel):
|
|
129
|
+
available_datasets: list = []
|
|
130
|
+
|
|
131
|
+
@computed_field
|
|
132
|
+
@property
|
|
133
|
+
def dataset_names(self) -> list[str]:
|
|
134
|
+
return [ds['name'] for ds in self.available_datasets]
|
|
135
|
+
|
|
136
|
+
class DataAgent(BaseAgent):
|
|
137
|
+
__system_message__ = "I manage datasets"
|
|
138
|
+
|
|
139
|
+
datasets: State[DatasetState] = spec.State(default_factory=DatasetState)
|
|
140
|
+
|
|
141
|
+
@tool("Analyze specific dataset")
|
|
142
|
+
def analyze(
|
|
143
|
+
self,
|
|
144
|
+
dataset: str = spec.Param(
|
|
145
|
+
description="Dataset to analyze",
|
|
146
|
+
values=ref.datasets.dataset_names # LLM can only pick from available datasets
|
|
147
|
+
)) -> str: ...
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Contributing
|
|
151
|
+
|
|
152
|
+
Contribution is welcome! Whether it's bug fixes, new features, documentation improvements, or examples, help is appreciated.
|
|
153
|
+
|
|
154
|
+
### Development Setup
|
|
155
|
+
|
|
156
|
+
1. **Clone the repository**
|
|
157
|
+
```bash
|
|
158
|
+
git clone https://github.com/your-username/pyagentic.git
|
|
159
|
+
cd pyagentic
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
2. **Install dependencies with uv**
|
|
163
|
+
```bash
|
|
164
|
+
# Install uv if you haven't already
|
|
165
|
+
pip install uv
|
|
166
|
+
|
|
167
|
+
# Install all dependencies including dev tools
|
|
168
|
+
uv sync --group dev
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Code Quality
|
|
172
|
+
|
|
173
|
+
Several tools are used to maintain code quality:
|
|
174
|
+
|
|
175
|
+
#### Formatting with Black
|
|
176
|
+
```bash
|
|
177
|
+
# Format all Python files
|
|
178
|
+
uv run black -l99 pyagentic tests
|
|
179
|
+
|
|
180
|
+
# Check formatting without making changes
|
|
181
|
+
uv run black -l99 --check pyagentic tests
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
#### Linting with Flake8
|
|
185
|
+
```bash
|
|
186
|
+
# Run linting checks
|
|
187
|
+
uv run flake8 --max-line-length=99 pyagentic tests
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
### Testing
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# Run all tests
|
|
195
|
+
uv run pytest tests
|
|
196
|
+
|
|
197
|
+
# Run tests with coverage
|
|
198
|
+
uv run coverage run -m pytest tests
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Documentation
|
|
202
|
+
|
|
203
|
+
Documentation is built with MkDocs and deployed automatically:
|
|
204
|
+
|
|
205
|
+
#### Local Development
|
|
206
|
+
```bash
|
|
207
|
+
# Install docs dependencies
|
|
208
|
+
uv sync --group docs
|
|
209
|
+
|
|
210
|
+
# Serve docs locally (auto-reloads on changes)
|
|
211
|
+
uv run task serve-docs
|
|
212
|
+
|
|
213
|
+
# Build docs to ./site/
|
|
214
|
+
uv run task build-docs
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Docs are automatically deployed on pushes to main via GitHub Actions.
|
|
218
|
+
|
|
219
|
+
### Submitting Changes
|
|
220
|
+
|
|
221
|
+
1. **Create a feature branch**
|
|
222
|
+
```bash
|
|
223
|
+
git checkout -b feature/your-feature-name
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
2. **Make your changes** following the code style guidelines
|
|
227
|
+
|
|
228
|
+
3. **Run the full test suite**
|
|
229
|
+
```bash
|
|
230
|
+
uv run black pyagentic tests
|
|
231
|
+
uv run flake8 pyagentic tests --max-line-length=99
|
|
232
|
+
uv run pytest
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
4. **Commit with conventional commit messages**
|
|
236
|
+
```bash
|
|
237
|
+
git commit -m "feat: add new agent linking feature"
|
|
238
|
+
git commit -m "fix: resolve context persistence issue"
|
|
239
|
+
git commit -m "docs: improve getting started guide"
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
5. **Push and create a Pull Request**
|
|
243
|
+
```bash
|
|
244
|
+
git push origin feature/your-feature-name
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Conventional Commits
|
|
248
|
+
|
|
249
|
+
Conventional commits are used for automatic versioning:
|
|
250
|
+
|
|
251
|
+
- `feat:` - New features (minor version bump)
|
|
252
|
+
- `fix:` - Bug fixes (patch version bump)
|
|
253
|
+
- `docs:` - Documentation changes
|
|
254
|
+
- `test:` - Test additions or improvements
|
|
255
|
+
- `refactor:` - Code refactoring
|
|
256
|
+
- `style:` - Code style changes (formatting, etc.)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
## 📄 License
|
|
260
|
+
|
|
261
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# PyAgentic
|
|
2
|
+
|
|
3
|
+
[](https://www.python.org/downloads/)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://github.com/psf/black)
|
|
6
|
+
[](https://github.com/rmikulec/pyAgentic/actions/workflows/testing.yml?query=branch%3Amain)
|
|
7
|
+
|
|
8
|
+
A declarative, type-safe framework for building AI agents with OpenAI integration. PyAgentic lets you create sophisticated LLM agents using clean Python class syntax, with full support for tools, persistent state, agent linking, and agent inheritance.
|
|
9
|
+
|
|
10
|
+
## Documentation
|
|
11
|
+
|
|
12
|
+
Read the **[Getting Started](https://rmikulec.github.io/pyAgentic/getting-started/)**!
|
|
13
|
+
|
|
14
|
+
Complete documentation, tutorials, and examples can be found **[here](https://rmikulec.github.io/pyagentic)**
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
- **Declarative Design** - Define agents with simple class-based syntax and decorators
|
|
19
|
+
- **Powerful Tools** - Easy `@tool` decoration with automatic OpenAI schema generation
|
|
20
|
+
- **Persistent State** - Stateful agents with `State` fields that persist across conversations
|
|
21
|
+
- **Agent Linking** - Compose complex workflows by linking agents together
|
|
22
|
+
- **Structured Responses** - Type-safe Pydantic responses with full tool execution details
|
|
23
|
+
- **Dynamic Constraints** - Use `ref` to create smart parameter validation
|
|
24
|
+
- **Inheritance & Extensions** - Build agent hierarchies and mix in cross-cutting capabilities
|
|
25
|
+
- **Native Async Support** - Built for scalable applications with async/await throughout
|
|
26
|
+
- **Type Safety** - Complete typing support with validation and IDE autocompletion
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
### Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install pyagentic-core
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Simple Agent Example
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from pyagentic import BaseAgent, tool, State, spec
|
|
40
|
+
|
|
41
|
+
class ResearchAgent(BaseAgent):
|
|
42
|
+
__system_message__ = "I help with research tasks and maintain a collection of papers"
|
|
43
|
+
|
|
44
|
+
# Persistent state that survives across conversations
|
|
45
|
+
paper_count: State[int] = spec.State(default=0)
|
|
46
|
+
current_topic: State[str] = spec.State(default="general", access="write")
|
|
47
|
+
|
|
48
|
+
@tool("Search for academic papers")
|
|
49
|
+
def search_papers(self, query: str, max_results: int = 5) -> str:
|
|
50
|
+
# Your search logic here
|
|
51
|
+
self.paper_count += max_results
|
|
52
|
+
return f"Found {max_results} papers about '{query}'"
|
|
53
|
+
|
|
54
|
+
# Create and use the agent
|
|
55
|
+
agent = ResearchAgent(model="openai::gpt-4", api_key="your-key")
|
|
56
|
+
response = await agent("Help me research machine learning papers")
|
|
57
|
+
|
|
58
|
+
# Access structured response data
|
|
59
|
+
print(response.final_output) # Natural language response
|
|
60
|
+
print(len(response.tool_responses)) # Number of tools called
|
|
61
|
+
print(agent.paper_count) # Persistent state
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Advanced Features
|
|
65
|
+
|
|
66
|
+
#### Agent Linking
|
|
67
|
+
Create multi-agent workflows where agents can call other agents as tools:
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
class DatabaseAgent(BaseAgent):
|
|
71
|
+
__system_message__ = "I query databases"
|
|
72
|
+
__description__ = "Retrieves data from SQL databases"
|
|
73
|
+
|
|
74
|
+
@tool("Execute SQL query")
|
|
75
|
+
def query(self, sql: str) -> str: ...
|
|
76
|
+
|
|
77
|
+
class WebAgent(BaseAgent):
|
|
78
|
+
__system_message__ = "I search the web"
|
|
79
|
+
__description__ = "Searches the internet"
|
|
80
|
+
|
|
81
|
+
@tool("search")
|
|
82
|
+
def search(self, terms: list[str]) -> str: ...
|
|
83
|
+
|
|
84
|
+
class ReportAgent(BaseAgent):
|
|
85
|
+
__system_message__ = "I generate business reports"
|
|
86
|
+
database: DatabaseAgent # Linked agent appears as a tool
|
|
87
|
+
searcher: WebAgent
|
|
88
|
+
|
|
89
|
+
@tool("Create visualization")
|
|
90
|
+
def create_chart(self, data: str) -> str: ...
|
|
91
|
+
|
|
92
|
+
# The report agent can automatically coordinate with the database agent
|
|
93
|
+
report_agent = ReportAgent(database=DatabaseAgent(...), searcher=WebAgent(...))
|
|
94
|
+
response = await report_agent("Generate a plot of the latest financial data")
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### Dynamic Parameter Constraints
|
|
98
|
+
Use `ref` with Pydantic computed fields to create intelligent parameter validation:
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
from pydantic import BaseModel, computed_field
|
|
102
|
+
from pyagentic import ref, spec
|
|
103
|
+
|
|
104
|
+
class DatasetState(BaseModel):
|
|
105
|
+
available_datasets: list = []
|
|
106
|
+
|
|
107
|
+
@computed_field
|
|
108
|
+
@property
|
|
109
|
+
def dataset_names(self) -> list[str]:
|
|
110
|
+
return [ds['name'] for ds in self.available_datasets]
|
|
111
|
+
|
|
112
|
+
class DataAgent(BaseAgent):
|
|
113
|
+
__system_message__ = "I manage datasets"
|
|
114
|
+
|
|
115
|
+
datasets: State[DatasetState] = spec.State(default_factory=DatasetState)
|
|
116
|
+
|
|
117
|
+
@tool("Analyze specific dataset")
|
|
118
|
+
def analyze(
|
|
119
|
+
self,
|
|
120
|
+
dataset: str = spec.Param(
|
|
121
|
+
description="Dataset to analyze",
|
|
122
|
+
values=ref.datasets.dataset_names # LLM can only pick from available datasets
|
|
123
|
+
)) -> str: ...
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Contributing
|
|
127
|
+
|
|
128
|
+
Contribution is welcome! Whether it's bug fixes, new features, documentation improvements, or examples, help is appreciated.
|
|
129
|
+
|
|
130
|
+
### Development Setup
|
|
131
|
+
|
|
132
|
+
1. **Clone the repository**
|
|
133
|
+
```bash
|
|
134
|
+
git clone https://github.com/your-username/pyagentic.git
|
|
135
|
+
cd pyagentic
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
2. **Install dependencies with uv**
|
|
139
|
+
```bash
|
|
140
|
+
# Install uv if you haven't already
|
|
141
|
+
pip install uv
|
|
142
|
+
|
|
143
|
+
# Install all dependencies including dev tools
|
|
144
|
+
uv sync --group dev
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Code Quality
|
|
148
|
+
|
|
149
|
+
Several tools are used to maintain code quality:
|
|
150
|
+
|
|
151
|
+
#### Formatting with Black
|
|
152
|
+
```bash
|
|
153
|
+
# Format all Python files
|
|
154
|
+
uv run black -l99 pyagentic tests
|
|
155
|
+
|
|
156
|
+
# Check formatting without making changes
|
|
157
|
+
uv run black -l99 --check pyagentic tests
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
#### Linting with Flake8
|
|
161
|
+
```bash
|
|
162
|
+
# Run linting checks
|
|
163
|
+
uv run flake8 --max-line-length=99 pyagentic tests
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
### Testing
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# Run all tests
|
|
171
|
+
uv run pytest tests
|
|
172
|
+
|
|
173
|
+
# Run tests with coverage
|
|
174
|
+
uv run coverage run -m pytest tests
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Documentation
|
|
178
|
+
|
|
179
|
+
Documentation is built with MkDocs and deployed automatically:
|
|
180
|
+
|
|
181
|
+
#### Local Development
|
|
182
|
+
```bash
|
|
183
|
+
# Install docs dependencies
|
|
184
|
+
uv sync --group docs
|
|
185
|
+
|
|
186
|
+
# Serve docs locally (auto-reloads on changes)
|
|
187
|
+
uv run task serve-docs
|
|
188
|
+
|
|
189
|
+
# Build docs to ./site/
|
|
190
|
+
uv run task build-docs
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Docs are automatically deployed on pushes to main via GitHub Actions.
|
|
194
|
+
|
|
195
|
+
### Submitting Changes
|
|
196
|
+
|
|
197
|
+
1. **Create a feature branch**
|
|
198
|
+
```bash
|
|
199
|
+
git checkout -b feature/your-feature-name
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
2. **Make your changes** following the code style guidelines
|
|
203
|
+
|
|
204
|
+
3. **Run the full test suite**
|
|
205
|
+
```bash
|
|
206
|
+
uv run black pyagentic tests
|
|
207
|
+
uv run flake8 pyagentic tests --max-line-length=99
|
|
208
|
+
uv run pytest
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
4. **Commit with conventional commit messages**
|
|
212
|
+
```bash
|
|
213
|
+
git commit -m "feat: add new agent linking feature"
|
|
214
|
+
git commit -m "fix: resolve context persistence issue"
|
|
215
|
+
git commit -m "docs: improve getting started guide"
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
5. **Push and create a Pull Request**
|
|
219
|
+
```bash
|
|
220
|
+
git push origin feature/your-feature-name
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Conventional Commits
|
|
224
|
+
|
|
225
|
+
Conventional commits are used for automatic versioning:
|
|
226
|
+
|
|
227
|
+
- `feat:` - New features (minor version bump)
|
|
228
|
+
- `fix:` - Bug fixes (patch version bump)
|
|
229
|
+
- `docs:` - Documentation changes
|
|
230
|
+
- `test:` - Test additions or improvements
|
|
231
|
+
- `refactor:` - Code refactoring
|
|
232
|
+
- `style:` - Code style changes (formatting, etc.)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
## 📄 License
|
|
236
|
+
|
|
237
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PyAgentic: A declarative framework for building LLM-powered agents.
|
|
3
|
+
|
|
4
|
+
PyAgentic provides a clean, type-safe way to build agentic systems with:
|
|
5
|
+
- Tool calling: Let LLMs invoke Python functions
|
|
6
|
+
- Stateful agents: Maintain conversation and application state
|
|
7
|
+
- Multi-agent systems: Link agents together for complex workflows
|
|
8
|
+
- Provider flexibility: Support for OpenAI, Anthropic, and custom providers
|
|
9
|
+
- Observability: Built-in tracing with BasicTracer and LangfuseTracer
|
|
10
|
+
|
|
11
|
+
Quick Start:
|
|
12
|
+
```python
|
|
13
|
+
from pyagentic import BaseAgent, tool
|
|
14
|
+
|
|
15
|
+
class MyAgent(BaseAgent):
|
|
16
|
+
__system_message__ = "You are a helpful assistant"
|
|
17
|
+
|
|
18
|
+
@tool("Calculate the sum of two numbers")
|
|
19
|
+
def add(self, a: int, b: int) -> str:
|
|
20
|
+
return str(a + b)
|
|
21
|
+
|
|
22
|
+
# Create and run the agent
|
|
23
|
+
agent = MyAgent(model="openai::gpt-4o", api_key="your-key")
|
|
24
|
+
response = await agent.run("What is 5 + 3?")
|
|
25
|
+
print(response.final_output) # The LLM will call the add tool
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Main Components:
|
|
29
|
+
- BaseAgent: Base class for defining agents
|
|
30
|
+
- tool: Decorator for marking methods as LLM-callable tools
|
|
31
|
+
- State: Type annotation for persistent state fields
|
|
32
|
+
- Link: Type annotation for linking agents together
|
|
33
|
+
- spec: Configuration factory for state, params, and agent links
|
|
34
|
+
- ref: Dynamic state reference system for tool parameters
|
|
35
|
+
- AgentExtension: Base class for creating reusable agent mixins
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
from pyagentic._base._spec import spec
|
|
39
|
+
from pyagentic._base._agent._agent import BaseAgent, AgentExtension
|
|
40
|
+
from pyagentic._base._agent._agent_linking import Link
|
|
41
|
+
from pyagentic._base._tool import tool
|
|
42
|
+
|
|
43
|
+
from pyagentic._base._state import State
|
|
44
|
+
from pyagentic._base._ref import ref
|
|
45
|
+
|
|
46
|
+
__all__ = ["BaseAgent", "AgentExtension", "tool", "spec", "State", "Link", "ref"]
|
|
File without changes
|
|
File without changes
|