agent-runtime-core 0.3.0__py3-none-any.whl → 0.5.0__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.
@@ -1,8 +1,9 @@
1
- agent_runtime_core/__init__.py,sha256=Z3OrJpoY9vrf-2hX3ulTqVRwA7YN0cF5mi-xTg5o3kg,3626
1
+ agent_runtime_core/__init__.py,sha256=RUggqSjlyIpgPOM1vuqfrGky1TmoAcX0EzHoJte6YSI,4010
2
2
  agent_runtime_core/config.py,sha256=e3_uB5brAuQcWU36sOhWF9R6RoJrngtCS-xEB3n2fas,4986
3
- agent_runtime_core/interfaces.py,sha256=-VGZJHUkyF8kdO-BDkURyc-sLbObIHErIFw1Hzn3n14,10434
3
+ agent_runtime_core/interfaces.py,sha256=V3CAt8otNMF4Wdo5xJ9DyScL0iYcmQ90U0weadMQsw0,10777
4
4
  agent_runtime_core/registry.py,sha256=hrbEdNNdqEz7-uN-82qofsXFTZBRDxZ2Ht9qwmp1qkw,1476
5
5
  agent_runtime_core/runner.py,sha256=M3It72UhfmLt17jVnSvObiSfQ1_RN4JVUIJsjnRd2Ps,12771
6
+ agent_runtime_core/steps.py,sha256=XpVFK7P-ZOpr7NwaP7XFygduIpjrKld-OIig7dHNMKE,11994
6
7
  agent_runtime_core/testing.py,sha256=ordECGprBappLBMWxlETvuf2AoIPNomJFeSedXaY30E,11131
7
8
  agent_runtime_core/events/__init__.py,sha256=Gg7cMQHWfLTQ4Xik09KSg7cWbQDmW_MuF5_jl-yZkHU,1575
8
9
  agent_runtime_core/events/base.py,sha256=NfHYyoczxr40Er5emROi_aY_07m5hDrKsn31pdWY2DY,1950
@@ -13,10 +14,10 @@ agent_runtime_core/llm/__init__.py,sha256=LyFFDtk4HhvUXct0nTeKuYuWzVmVqLDSVRpnPA
13
14
  agent_runtime_core/llm/anthropic.py,sha256=pt9QAjrv2dIPSAY3Pv6N_BzxL1tbhL-kPWsQ-DcHMLI,7516
14
15
  agent_runtime_core/llm/litellm_client.py,sha256=c-O-lE08cT3ne0xSOvSDezPL6hCiA69p3HnB451Ipe4,5193
15
16
  agent_runtime_core/llm/openai.py,sha256=qBZkkndDgYQ6LG-9bHS2za5KJTGSgL-c_7h0bD3_5lg,6862
16
- agent_runtime_core/persistence/__init__.py,sha256=u3sYJSu4mTnszkt01qxN3Cn7_bMWvzFtgXDRK26LblM,2029
17
- agent_runtime_core/persistence/base.py,sha256=7p9HYWYY4pjmDvQgLh11Fie_XmMnkimkCG7tUQt0zUQ,9444
17
+ agent_runtime_core/persistence/__init__.py,sha256=l9_1Mzhy9_Y-IIKuBKTR3Z8r2TPyr0a6b1HEdyZf1_I,2772
18
+ agent_runtime_core/persistence/base.py,sha256=k0wuzTCffPJ609dj9hIhnaqnNI1Qr3pCzJ-6E1YkSRU,21616
18
19
  agent_runtime_core/persistence/file.py,sha256=oDB4_ZQkwHTCT1uoqpw5jOleK69YXCQwlTPsW86Yb-I,17785
19
- agent_runtime_core/persistence/manager.py,sha256=wXwOX9fa3EoDcXi-rz9QRX8uA1BLw-mvM6LMIS2Jr44,9692
20
+ agent_runtime_core/persistence/manager.py,sha256=UL_eFsFM28nXM6O9PTHdzKX9Qxh9v2gBGd1m9Bs0vog,14309
20
21
  agent_runtime_core/queue/__init__.py,sha256=m8gapXACPGApLj0RIDpVe5cQYuvKq1QsY2_mXzZcULQ,1527
21
22
  agent_runtime_core/queue/base.py,sha256=QW1eWbwBX_tmVD8yJobFJtlxLd_RtUWHTuXGessuxy8,3959
22
23
  agent_runtime_core/queue/memory.py,sha256=G65NJ2QU8sB2WQ7myHXc8LzSFowEzBXtCt78WmhvxO8,5416
@@ -30,7 +31,7 @@ agent_runtime_core/state/sqlite.py,sha256=HKZwDiC_7F1W8Z_Pz8roEs91XhQ9rUHfGpuQ7W
30
31
  agent_runtime_core/tracing/__init__.py,sha256=u1QicGc39e30gWyQD4cQWxGGjITnkwoOPUhNrG6aNyI,1266
31
32
  agent_runtime_core/tracing/langfuse.py,sha256=Rj2sUlatk5sFro0y68tw5X6fQcSwWxcBOSOjB0F7JTU,3660
32
33
  agent_runtime_core/tracing/noop.py,sha256=SpsbpsUcNG6C3xZG3uyiNPUHY8etloISx3w56Q8D3KE,751
33
- agent_runtime_core-0.3.0.dist-info/METADATA,sha256=5F-OYNqSvqmwMQGbf0jfLayLw8Vs34AMSEjGEHxkr88,12488
34
- agent_runtime_core-0.3.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
35
- agent_runtime_core-0.3.0.dist-info/licenses/LICENSE,sha256=PcOO8aiOZ4H2MWYeKIis3o6xTCT1hNkDyCxHZhh1NeM,1070
36
- agent_runtime_core-0.3.0.dist-info/RECORD,,
34
+ agent_runtime_core-0.5.0.dist-info/METADATA,sha256=36z0El8gHA_A2Spm9gPsydMSbS6kYV7OLZdqIh5D8OM,23493
35
+ agent_runtime_core-0.5.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
36
+ agent_runtime_core-0.5.0.dist-info/licenses/LICENSE,sha256=PcOO8aiOZ4H2MWYeKIis3o6xTCT1hNkDyCxHZhh1NeM,1070
37
+ agent_runtime_core-0.5.0.dist-info/RECORD,,
@@ -1,461 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: agent-runtime-core
3
- Version: 0.3.0
4
- Summary: Framework-agnostic Python library for executing AI agents with consistent patterns
5
- Project-URL: Homepage, https://github.com/colstrom/agent_runtime_core
6
- Project-URL: Repository, https://github.com/colstrom/agent_runtime_core
7
- Author: Chris Olstrom
8
- License-Expression: MIT
9
- License-File: LICENSE
10
- Keywords: agents,ai,async,llm,runtime
11
- Classifier: Development Status :: 3 - Alpha
12
- Classifier: Intended Audience :: Developers
13
- Classifier: License :: OSI Approved :: MIT License
14
- Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.11
16
- Classifier: Programming Language :: Python :: 3.12
17
- Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
18
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
- Requires-Python: >=3.11
20
- Provides-Extra: all
21
- Requires-Dist: anthropic>=0.18.0; extra == 'all'
22
- Requires-Dist: langfuse>=2.0.0; extra == 'all'
23
- Requires-Dist: litellm>=1.0.0; extra == 'all'
24
- Requires-Dist: openai>=1.0.0; extra == 'all'
25
- Requires-Dist: redis>=5.0.0; extra == 'all'
26
- Provides-Extra: anthropic
27
- Requires-Dist: anthropic>=0.18.0; extra == 'anthropic'
28
- Provides-Extra: dev
29
- Requires-Dist: mypy>=1.0.0; extra == 'dev'
30
- Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
31
- Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
32
- Requires-Dist: pytest>=8.0.0; extra == 'dev'
33
- Requires-Dist: ruff>=0.1.0; extra == 'dev'
34
- Provides-Extra: langfuse
35
- Requires-Dist: langfuse>=2.0.0; extra == 'langfuse'
36
- Provides-Extra: litellm
37
- Requires-Dist: litellm>=1.0.0; extra == 'litellm'
38
- Provides-Extra: openai
39
- Requires-Dist: openai>=1.0.0; extra == 'openai'
40
- Provides-Extra: redis
41
- Requires-Dist: redis>=5.0.0; extra == 'redis'
42
- Description-Content-Type: text/markdown
43
-
44
- # agent-runtime-core
45
-
46
- [![PyPI version](https://badge.fury.io/py/agent-runtime-core.svg)](https://badge.fury.io/py/agent-runtime-core)
47
- [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
48
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
49
-
50
- A lightweight, framework-agnostic Python library for building AI agent systems. Provides the core abstractions and implementations needed to build production-ready AI agents without tying you to any specific framework.
51
-
52
- ## Features
53
-
54
- - 🔌 **Framework Agnostic** - Works with LangGraph, CrewAI, OpenAI Agents, or your own custom loops
55
- - 🤖 **Model Agnostic** - OpenAI, Anthropic, or any provider via LiteLLM
56
- - 📦 **Zero Required Dependencies** - Core library has no dependencies; add only what you need
57
- - 🔄 **Async First** - Built for modern async Python with full sync support
58
- - 🛠️ **Pluggable Backends** - Memory, Redis, or SQLite for queues, events, and state
59
- - 📊 **Observable** - Built-in tracing with optional Langfuse integration
60
- - 🧩 **Composable** - Mix and match components to build your ideal agent system
61
-
62
- ## Installation
63
-
64
- ```bash
65
- # Core library (no dependencies)
66
- pip install agent-runtime-core
67
-
68
- # With specific LLM providers
69
- pip install agent-runtime-core[openai]
70
- pip install agent-runtime-core[anthropic]
71
- pip install agent-runtime-core[litellm]
72
-
73
- # With Redis backend support
74
- pip install agent-runtime-core[redis]
75
-
76
- # With observability
77
- pip install agent-runtime-core[langfuse]
78
-
79
- # Everything
80
- pip install agent-runtime-core[all]
81
- ```
82
-
83
- ## Quick Start
84
-
85
- ### Basic Configuration
86
-
87
- ```python
88
- from agent_runtime import configure, get_config
89
-
90
- # Configure the runtime
91
- configure(
92
- model_provider="openai",
93
- openai_api_key="sk-...", # Or use OPENAI_API_KEY env var
94
- default_model="gpt-4o",
95
- )
96
-
97
- # Access configuration anywhere
98
- config = get_config()
99
- print(config.model_provider) # "openai"
100
- ```
101
-
102
- ### Creating an Agent
103
-
104
- ```python
105
- from agent_runtime import (
106
- AgentRuntime,
107
- RunContext,
108
- RunResult,
109
- EventType,
110
- register_runtime,
111
- )
112
-
113
- class MyAgent(AgentRuntime):
114
- """A simple conversational agent."""
115
-
116
- @property
117
- def key(self) -> str:
118
- return "my-agent"
119
-
120
- async def run(self, ctx: RunContext) -> RunResult:
121
- # Access input messages
122
- messages = ctx.input_messages
123
-
124
- # Get an LLM client
125
- from agent_runtime.llm import get_llm_client
126
- llm = get_llm_client()
127
-
128
- # Generate a response
129
- response = await llm.generate(messages)
130
-
131
- # Emit events for observability
132
- await ctx.emit(EventType.ASSISTANT_MESSAGE, {
133
- "content": response.message["content"],
134
- })
135
-
136
- # Return the result
137
- return RunResult(
138
- final_output={"response": response.message["content"]},
139
- final_messages=[response.message],
140
- )
141
-
142
- # Register the agent
143
- register_runtime(MyAgent())
144
- ```
145
-
146
- ### Using Tools
147
-
148
- ```python
149
- from agent_runtime import Tool, ToolRegistry, RunContext, RunResult
150
-
151
- # Define tools
152
- def get_weather(location: str) -> str:
153
- """Get the current weather for a location."""
154
- return f"The weather in {location} is sunny, 72°F"
155
-
156
- def search_web(query: str) -> str:
157
- """Search the web for information."""
158
- return f"Search results for: {query}"
159
-
160
- # Create a tool registry
161
- tools = ToolRegistry()
162
- tools.register(Tool.from_function(get_weather))
163
- tools.register(Tool.from_function(search_web))
164
-
165
- class ToolAgent(AgentRuntime):
166
- @property
167
- def key(self) -> str:
168
- return "tool-agent"
169
-
170
- async def run(self, ctx: RunContext) -> RunResult:
171
- from agent_runtime.llm import get_llm_client
172
- llm = get_llm_client()
173
-
174
- messages = list(ctx.input_messages)
175
-
176
- while True:
177
- # Generate with tools
178
- response = await llm.generate(
179
- messages,
180
- tools=tools.to_openai_format(),
181
- )
182
-
183
- messages.append(response.message)
184
-
185
- # Check for tool calls
186
- if not response.tool_calls:
187
- break
188
-
189
- # Execute tools
190
- for tool_call in response.tool_calls:
191
- result = await tools.execute(
192
- tool_call["function"]["name"],
193
- tool_call["function"]["arguments"],
194
- )
195
-
196
- await ctx.emit(EventType.TOOL_RESULT, {
197
- "tool_call_id": tool_call["id"],
198
- "result": result,
199
- })
200
-
201
- messages.append({
202
- "role": "tool",
203
- "tool_call_id": tool_call["id"],
204
- "content": str(result),
205
- })
206
-
207
- return RunResult(
208
- final_output={"response": response.message["content"]},
209
- final_messages=messages,
210
- )
211
- ```
212
-
213
- ### Running Agents
214
-
215
- ```python
216
- from agent_runtime import AgentRunner, RunnerConfig, get_runtime
217
- import asyncio
218
-
219
- async def main():
220
- # Get a registered agent
221
- agent = get_runtime("my-agent")
222
-
223
- # Create a runner
224
- runner = AgentRunner(
225
- config=RunnerConfig(
226
- run_timeout_seconds=300,
227
- max_retries=3,
228
- )
229
- )
230
-
231
- # Execute a run
232
- result = await runner.execute(
233
- agent=agent,
234
- run_id="run-123",
235
- input_data={
236
- "messages": [
237
- {"role": "user", "content": "Hello!"}
238
- ]
239
- },
240
- )
241
-
242
- print(result.final_output)
243
-
244
- asyncio.run(main())
245
- ```
246
-
247
- ## Core Concepts
248
-
249
- ### AgentRuntime
250
-
251
- The base class for all agents. Implement the `run` method to define your agent's behavior:
252
-
253
- ```python
254
- class AgentRuntime(ABC):
255
- @property
256
- @abstractmethod
257
- def key(self) -> str:
258
- """Unique identifier for this agent."""
259
- pass
260
-
261
- @abstractmethod
262
- async def run(self, ctx: RunContext) -> RunResult:
263
- """Execute the agent logic."""
264
- pass
265
- ```
266
-
267
- ### RunContext
268
-
269
- Provides access to the current run's state and utilities:
270
-
271
- ```python
272
- class RunContext:
273
- run_id: UUID # Unique run identifier
274
- input_messages: list # Input messages
275
- metadata: dict # Run metadata
276
- tools: ToolRegistry # Available tools
277
-
278
- async def emit(self, event_type: EventType, payload: dict) -> None:
279
- """Emit an event."""
280
-
281
- async def checkpoint(self, state: dict) -> None:
282
- """Save a checkpoint."""
283
-
284
- def is_cancelled(self) -> bool:
285
- """Check if run was cancelled."""
286
- ```
287
-
288
- ### RunResult
289
-
290
- The result of an agent run:
291
-
292
- ```python
293
- @dataclass
294
- class RunResult:
295
- final_output: dict # Structured output
296
- final_messages: list = None # Conversation history
297
- error: ErrorInfo = None # Error details if failed
298
- ```
299
-
300
- ### Event Types
301
-
302
- Built-in event types for observability:
303
-
304
- - `EventType.RUN_STARTED` - Run execution began
305
- - `EventType.RUN_SUCCEEDED` - Run completed successfully
306
- - `EventType.RUN_FAILED` - Run failed with error
307
- - `EventType.TOOL_CALL` - Tool was invoked
308
- - `EventType.TOOL_RESULT` - Tool returned result
309
- - `EventType.ASSISTANT_MESSAGE` - LLM generated message
310
- - `EventType.CHECKPOINT` - State checkpoint saved
311
-
312
- ## Backend Options
313
-
314
- ### Queue Backends
315
-
316
- ```python
317
- from agent_runtime.queue import MemoryQueue, RedisQueue
318
-
319
- # In-memory (for development)
320
- queue = MemoryQueue()
321
-
322
- # Redis (for production)
323
- queue = RedisQueue(redis_url="redis://localhost:6379/0")
324
- ```
325
-
326
- ### Event Bus Backends
327
-
328
- ```python
329
- from agent_runtime.events import MemoryEventBus, RedisEventBus
330
-
331
- # In-memory
332
- event_bus = MemoryEventBus()
333
-
334
- # Redis Pub/Sub
335
- event_bus = RedisEventBus(redis_url="redis://localhost:6379/0")
336
- ```
337
-
338
- ### State Store Backends
339
-
340
- ```python
341
- from agent_runtime.state import MemoryStateStore, RedisStateStore, SQLiteStateStore
342
-
343
- # In-memory
344
- state = MemoryStateStore()
345
-
346
- # Redis
347
- state = RedisStateStore(redis_url="redis://localhost:6379/0")
348
-
349
- # SQLite (persistent, single-node)
350
- state = SQLiteStateStore(db_path="./agent_state.db")
351
- ```
352
-
353
- ## LLM Clients
354
-
355
- ### OpenAI
356
-
357
- ```python
358
- from agent_runtime.llm import OpenAIClient
359
-
360
- client = OpenAIClient(
361
- api_key="sk-...", # Or use OPENAI_API_KEY env var
362
- default_model="gpt-4o",
363
- )
364
-
365
- response = await client.generate([
366
- {"role": "user", "content": "Hello!"}
367
- ])
368
- ```
369
-
370
- ### Anthropic
371
-
372
- ```python
373
- from agent_runtime.llm import AnthropicClient
374
-
375
- client = AnthropicClient(
376
- api_key="sk-ant-...", # Or use ANTHROPIC_API_KEY env var
377
- default_model="claude-3-5-sonnet-20241022",
378
- )
379
- ```
380
-
381
- ### LiteLLM (Any Provider)
382
-
383
- ```python
384
- from agent_runtime.llm import LiteLLMClient
385
-
386
- # Use any LiteLLM-supported model
387
- client = LiteLLMClient(default_model="gpt-4o")
388
- client = LiteLLMClient(default_model="claude-3-5-sonnet-20241022")
389
- client = LiteLLMClient(default_model="ollama/llama2")
390
- ```
391
-
392
- ## Tracing & Observability
393
-
394
- ### Langfuse Integration
395
-
396
- ```python
397
- from agent_runtime import configure
398
-
399
- configure(
400
- langfuse_enabled=True,
401
- langfuse_public_key="pk-...",
402
- langfuse_secret_key="sk-...",
403
- )
404
- ```
405
-
406
- ### Custom Trace Sink
407
-
408
- ```python
409
- from agent_runtime import TraceSink
410
-
411
- class MyTraceSink(TraceSink):
412
- async def trace(self, event: dict) -> None:
413
- # Send to your observability platform
414
- print(f"Trace: {event}")
415
- ```
416
-
417
- ## Integration with Django
418
-
419
- For Django applications, use [django-agent-runtime](https://pypi.org/project/django-agent-runtime/) which provides:
420
-
421
- - Django models for conversations, runs, and events
422
- - REST API endpoints
423
- - Server-Sent Events (SSE) for real-time streaming
424
- - Management commands for running workers
425
- - PostgreSQL-backed queue and event bus
426
-
427
- ```bash
428
- pip install django-agent-runtime
429
- ```
430
-
431
- ## API Reference
432
-
433
- ### Configuration
434
-
435
- | Setting | Type | Default | Description |
436
- |---------|------|---------|-------------|
437
- | `model_provider` | str | `"openai"` | LLM provider: openai, anthropic, litellm |
438
- | `default_model` | str | `"gpt-4o"` | Default model to use |
439
- | `queue_backend` | str | `"memory"` | Queue backend: memory, redis |
440
- | `event_bus_backend` | str | `"memory"` | Event bus: memory, redis |
441
- | `state_store_backend` | str | `"memory"` | State store: memory, redis, sqlite |
442
- | `redis_url` | str | `None` | Redis connection URL |
443
- | `langfuse_enabled` | bool | `False` | Enable Langfuse tracing |
444
-
445
- ### Registry Functions
446
-
447
- ```python
448
- register_runtime(runtime: AgentRuntime) -> None
449
- get_runtime(key: str) -> AgentRuntime
450
- list_runtimes() -> list[str]
451
- unregister_runtime(key: str) -> None
452
- clear_registry() -> None
453
- ```
454
-
455
- ## Contributing
456
-
457
- Contributions are welcome! Please feel free to submit a Pull Request.
458
-
459
- ## License
460
-
461
- MIT License - see [LICENSE](LICENSE) for details.