agent-runtime-core 0.2.1__py3-none-any.whl → 0.4.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.
Files changed (38) hide show
  1. {agent_runtime → agent_runtime_core}/__init__.py +8 -8
  2. {agent_runtime → agent_runtime_core}/config.py +1 -1
  3. {agent_runtime → agent_runtime_core}/events/__init__.py +5 -5
  4. {agent_runtime → agent_runtime_core}/events/memory.py +1 -1
  5. {agent_runtime → agent_runtime_core}/events/redis.py +1 -1
  6. {agent_runtime → agent_runtime_core}/events/sqlite.py +1 -1
  7. {agent_runtime → agent_runtime_core}/llm/__init__.py +6 -6
  8. {agent_runtime → agent_runtime_core}/llm/anthropic.py +4 -4
  9. {agent_runtime → agent_runtime_core}/llm/litellm_client.py +2 -2
  10. {agent_runtime → agent_runtime_core}/llm/openai.py +4 -4
  11. {agent_runtime → agent_runtime_core}/persistence/__init__.py +48 -12
  12. agent_runtime_core/persistence/base.py +737 -0
  13. {agent_runtime → agent_runtime_core}/persistence/file.py +1 -1
  14. {agent_runtime → agent_runtime_core}/persistence/manager.py +122 -14
  15. {agent_runtime → agent_runtime_core}/queue/__init__.py +5 -5
  16. {agent_runtime → agent_runtime_core}/queue/memory.py +1 -1
  17. {agent_runtime → agent_runtime_core}/queue/redis.py +1 -1
  18. {agent_runtime → agent_runtime_core}/queue/sqlite.py +1 -1
  19. {agent_runtime → agent_runtime_core}/registry.py +1 -1
  20. {agent_runtime → agent_runtime_core}/runner.py +6 -6
  21. {agent_runtime → agent_runtime_core}/state/__init__.py +5 -5
  22. {agent_runtime → agent_runtime_core}/state/memory.py +1 -1
  23. {agent_runtime → agent_runtime_core}/state/redis.py +1 -1
  24. {agent_runtime → agent_runtime_core}/state/sqlite.py +1 -1
  25. {agent_runtime → agent_runtime_core}/testing.py +1 -1
  26. {agent_runtime → agent_runtime_core}/tracing/__init__.py +4 -4
  27. {agent_runtime → agent_runtime_core}/tracing/langfuse.py +1 -1
  28. {agent_runtime → agent_runtime_core}/tracing/noop.py +1 -1
  29. {agent_runtime_core-0.2.1.dist-info → agent_runtime_core-0.4.0.dist-info}/METADATA +352 -42
  30. agent_runtime_core-0.4.0.dist-info/RECORD +36 -0
  31. agent_runtime/persistence/base.py +0 -332
  32. agent_runtime_core-0.2.1.dist-info/RECORD +0 -36
  33. {agent_runtime → agent_runtime_core}/events/base.py +0 -0
  34. {agent_runtime → agent_runtime_core}/interfaces.py +0 -0
  35. {agent_runtime → agent_runtime_core}/queue/base.py +0 -0
  36. {agent_runtime → agent_runtime_core}/state/base.py +0 -0
  37. {agent_runtime_core-0.2.1.dist-info → agent_runtime_core-0.4.0.dist-info}/WHEEL +0 -0
  38. {agent_runtime_core-0.2.1.dist-info → agent_runtime_core-0.4.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,332 +0,0 @@
1
- """
2
- Abstract base classes for persistence backends.
3
-
4
- These interfaces define the contract that all storage backends must implement.
5
- Projects depending on agent-runtime-core can provide their own implementations
6
- (e.g., database-backed, cloud storage, etc.).
7
-
8
- For Django/database implementations:
9
- - The `scope` parameter can be ignored if you use user/tenant context instead
10
- - Store implementations receive context through their constructor (e.g., user, org)
11
- - The abstract methods still accept scope for interface compatibility, but
12
- implementations can choose to ignore it
13
-
14
- Example Django implementation:
15
- class DjangoMemoryStore(MemoryStore):
16
- def __init__(self, user):
17
- self.user = user
18
-
19
- async def get(self, key: str, scope: Scope = Scope.PROJECT) -> Optional[Any]:
20
- # Ignore scope, use self.user instead
21
- try:
22
- entry = await Memory.objects.aget(user=self.user, key=key)
23
- return entry.value
24
- except Memory.DoesNotExist:
25
- return None
26
- """
27
-
28
- from abc import ABC, abstractmethod
29
- from dataclasses import dataclass, field
30
- from datetime import datetime
31
- from enum import Enum
32
- from typing import Any, Optional, AsyncIterator
33
- from uuid import UUID
34
-
35
-
36
- class Scope(str, Enum):
37
- """
38
- Storage scope for memory and other persistent data.
39
-
40
- For file-based storage:
41
- - GLOBAL: User's home directory (~/.agent_runtime/)
42
- - PROJECT: Current working directory (./.agent_runtime/)
43
- - SESSION: In-memory only, not persisted
44
-
45
- For database-backed storage, implementations may ignore this
46
- and use user/tenant context from the store constructor instead.
47
- """
48
-
49
- GLOBAL = "global"
50
- PROJECT = "project"
51
- SESSION = "session"
52
-
53
-
54
- class TaskState(str, Enum):
55
- """State of a task."""
56
-
57
- NOT_STARTED = "not_started"
58
- IN_PROGRESS = "in_progress"
59
- COMPLETE = "complete"
60
- CANCELLED = "cancelled"
61
-
62
-
63
- @dataclass
64
- class ToolCall:
65
- """A tool call made during a conversation."""
66
-
67
- id: str
68
- name: str
69
- arguments: dict
70
- timestamp: datetime = field(default_factory=datetime.utcnow)
71
-
72
-
73
- @dataclass
74
- class ToolResult:
75
- """Result of a tool call."""
76
-
77
- tool_call_id: str
78
- result: Any
79
- error: Optional[str] = None
80
- timestamp: datetime = field(default_factory=datetime.utcnow)
81
-
82
-
83
- @dataclass
84
- class ConversationMessage:
85
- """A message in a conversation with full state."""
86
-
87
- id: UUID
88
- role: str # system, user, assistant, tool
89
- content: str | dict | list
90
- timestamp: datetime = field(default_factory=datetime.utcnow)
91
-
92
- # For assistant messages with tool calls
93
- tool_calls: list[ToolCall] = field(default_factory=list)
94
-
95
- # For tool result messages
96
- tool_call_id: Optional[str] = None
97
-
98
- # Metadata
99
- model: Optional[str] = None
100
- usage: dict = field(default_factory=dict) # token counts
101
- metadata: dict = field(default_factory=dict)
102
-
103
-
104
- @dataclass
105
- class Conversation:
106
- """A complete conversation with all state."""
107
-
108
- id: UUID
109
- title: Optional[str] = None
110
- messages: list[ConversationMessage] = field(default_factory=list)
111
-
112
- # Metadata
113
- created_at: datetime = field(default_factory=datetime.utcnow)
114
- updated_at: datetime = field(default_factory=datetime.utcnow)
115
- metadata: dict = field(default_factory=dict)
116
-
117
- # Associated agent
118
- agent_key: Optional[str] = None
119
-
120
- # Summary for long conversations
121
- summary: Optional[str] = None
122
-
123
-
124
- @dataclass
125
- class Task:
126
- """A task in a task list."""
127
-
128
- id: UUID
129
- name: str
130
- description: str = ""
131
- state: TaskState = TaskState.NOT_STARTED
132
- parent_id: Optional[UUID] = None
133
- created_at: datetime = field(default_factory=datetime.utcnow)
134
- updated_at: datetime = field(default_factory=datetime.utcnow)
135
- metadata: dict = field(default_factory=dict)
136
-
137
-
138
- @dataclass
139
- class TaskList:
140
- """A list of tasks."""
141
-
142
- id: UUID
143
- name: str
144
- tasks: list[Task] = field(default_factory=list)
145
- created_at: datetime = field(default_factory=datetime.utcnow)
146
- updated_at: datetime = field(default_factory=datetime.utcnow)
147
-
148
- # Associated conversation/run
149
- conversation_id: Optional[UUID] = None
150
- run_id: Optional[UUID] = None
151
-
152
-
153
- class MemoryStore(ABC):
154
- """
155
- Abstract interface for key-value memory storage.
156
-
157
- Memory stores handle persistent key-value data that agents can
158
- use to remember information across sessions.
159
- """
160
-
161
- @abstractmethod
162
- async def get(self, key: str, scope: Scope = Scope.PROJECT) -> Optional[Any]:
163
- """Get a value by key."""
164
- ...
165
-
166
- @abstractmethod
167
- async def set(self, key: str, value: Any, scope: Scope = Scope.PROJECT) -> None:
168
- """Set a value by key."""
169
- ...
170
-
171
- @abstractmethod
172
- async def delete(self, key: str, scope: Scope = Scope.PROJECT) -> bool:
173
- """Delete a key. Returns True if key existed."""
174
- ...
175
-
176
- @abstractmethod
177
- async def list_keys(self, scope: Scope = Scope.PROJECT, prefix: Optional[str] = None) -> list[str]:
178
- """List all keys, optionally filtered by prefix."""
179
- ...
180
-
181
- @abstractmethod
182
- async def clear(self, scope: Scope = Scope.PROJECT) -> None:
183
- """Clear all keys in the given scope."""
184
- ...
185
-
186
- async def close(self) -> None:
187
- """Close any connections. Override if needed."""
188
- pass
189
-
190
-
191
- class ConversationStore(ABC):
192
- """
193
- Abstract interface for conversation history storage.
194
-
195
- Conversation stores handle full conversation state including
196
- messages, tool calls, and metadata.
197
- """
198
-
199
- @abstractmethod
200
- async def save(self, conversation: Conversation, scope: Scope = Scope.PROJECT) -> None:
201
- """Save or update a conversation."""
202
- ...
203
-
204
- @abstractmethod
205
- async def get(self, conversation_id: UUID, scope: Scope = Scope.PROJECT) -> Optional[Conversation]:
206
- """Get a conversation by ID."""
207
- ...
208
-
209
- @abstractmethod
210
- async def delete(self, conversation_id: UUID, scope: Scope = Scope.PROJECT) -> bool:
211
- """Delete a conversation. Returns True if it existed."""
212
- ...
213
-
214
- @abstractmethod
215
- async def list_conversations(
216
- self,
217
- scope: Scope = Scope.PROJECT,
218
- limit: int = 100,
219
- offset: int = 0,
220
- agent_key: Optional[str] = None,
221
- ) -> list[Conversation]:
222
- """List conversations, optionally filtered by agent."""
223
- ...
224
-
225
- @abstractmethod
226
- async def add_message(
227
- self,
228
- conversation_id: UUID,
229
- message: ConversationMessage,
230
- scope: Scope = Scope.PROJECT,
231
- ) -> None:
232
- """Add a message to an existing conversation."""
233
- ...
234
-
235
- @abstractmethod
236
- async def get_messages(
237
- self,
238
- conversation_id: UUID,
239
- scope: Scope = Scope.PROJECT,
240
- limit: Optional[int] = None,
241
- before: Optional[datetime] = None,
242
- ) -> list[ConversationMessage]:
243
- """Get messages from a conversation."""
244
- ...
245
-
246
- async def close(self) -> None:
247
- """Close any connections. Override if needed."""
248
- pass
249
-
250
-
251
- class TaskStore(ABC):
252
- """
253
- Abstract interface for task list storage.
254
-
255
- Task stores handle task lists and their state for tracking
256
- agent progress on complex work.
257
- """
258
-
259
- @abstractmethod
260
- async def save(self, task_list: TaskList, scope: Scope = Scope.PROJECT) -> None:
261
- """Save or update a task list."""
262
- ...
263
-
264
- @abstractmethod
265
- async def get(self, task_list_id: UUID, scope: Scope = Scope.PROJECT) -> Optional[TaskList]:
266
- """Get a task list by ID."""
267
- ...
268
-
269
- @abstractmethod
270
- async def delete(self, task_list_id: UUID, scope: Scope = Scope.PROJECT) -> bool:
271
- """Delete a task list. Returns True if it existed."""
272
- ...
273
-
274
- @abstractmethod
275
- async def get_by_conversation(
276
- self,
277
- conversation_id: UUID,
278
- scope: Scope = Scope.PROJECT,
279
- ) -> Optional[TaskList]:
280
- """Get the task list associated with a conversation."""
281
- ...
282
-
283
- @abstractmethod
284
- async def update_task(
285
- self,
286
- task_list_id: UUID,
287
- task_id: UUID,
288
- state: Optional[TaskState] = None,
289
- name: Optional[str] = None,
290
- description: Optional[str] = None,
291
- scope: Scope = Scope.PROJECT,
292
- ) -> None:
293
- """Update a specific task in a task list."""
294
- ...
295
-
296
- async def close(self) -> None:
297
- """Close any connections. Override if needed."""
298
- pass
299
-
300
-
301
- class PreferencesStore(ABC):
302
- """
303
- Abstract interface for preferences storage.
304
-
305
- Preferences stores handle user and agent configuration
306
- that persists across sessions.
307
- """
308
-
309
- @abstractmethod
310
- async def get(self, key: str, scope: Scope = Scope.GLOBAL) -> Optional[Any]:
311
- """Get a preference value."""
312
- ...
313
-
314
- @abstractmethod
315
- async def set(self, key: str, value: Any, scope: Scope = Scope.GLOBAL) -> None:
316
- """Set a preference value."""
317
- ...
318
-
319
- @abstractmethod
320
- async def delete(self, key: str, scope: Scope = Scope.GLOBAL) -> bool:
321
- """Delete a preference. Returns True if it existed."""
322
- ...
323
-
324
- @abstractmethod
325
- async def get_all(self, scope: Scope = Scope.GLOBAL) -> dict[str, Any]:
326
- """Get all preferences in the given scope."""
327
- ...
328
-
329
- async def close(self) -> None:
330
- """Close any connections. Override if needed."""
331
- pass
332
-
@@ -1,36 +0,0 @@
1
- agent_runtime/__init__.py,sha256=d-9hrmPS2JmaaDdZRfO5_B1HiJxLU_hMrXY-COXOxxs,3591
2
- agent_runtime/config.py,sha256=ZRjpILjsjeh_kl7873DtV2g_zaTrfdkb3NgdQ6ndb5Y,4981
3
- agent_runtime/interfaces.py,sha256=-VGZJHUkyF8kdO-BDkURyc-sLbObIHErIFw1Hzn3n14,10434
4
- agent_runtime/registry.py,sha256=sa0speDFxFCZlXoCge8cPNqWYUeWHyazs6tBer5Jg1w,1471
5
- agent_runtime/runner.py,sha256=Sb2FfSJvATaL7ideQZy2JhVZp0sSYGVIov93E-gxODU,12741
6
- agent_runtime/testing.py,sha256=aqN67RdbTdYf_rJfp5pEpn2s_tkeU-3oSpzTdADxH5g,11126
7
- agent_runtime/events/__init__.py,sha256=JNH-D40O6yz2evIf1_r2o3w7OQjLt4Yebn-sBNLzzh8,1550
8
- agent_runtime/events/base.py,sha256=NfHYyoczxr40Er5emROi_aY_07m5hDrKsn31pdWY2DY,1950
9
- agent_runtime/events/memory.py,sha256=7qseR6RtdaP833FxEHwyPw5TC7l4brJHr8uEx0mLc1Y,2486
10
- agent_runtime/events/redis.py,sha256=Z6WEvp_6jcIPi4ZgkGk5J61qxgGqllwk7jqJM4jcTXk,5869
11
- agent_runtime/events/sqlite.py,sha256=EiX1BMOqeS7BelmD8A6cvhz3fE4w7vJ2Wg4pFu1V2u0,5092
12
- agent_runtime/llm/__init__.py,sha256=JEk1Q2H6U9_Uid48YVm1wYR1W7po0vtjfjf2TTmQe_A,2431
13
- agent_runtime/llm/anthropic.py,sha256=ho3psMYAARpXyzqejgA1dx6Nk8io0TwCKb0mp_wsGyM,7496
14
- agent_runtime/llm/litellm_client.py,sha256=Pic3N4CHVoqzdHUbKlizBcuPP0xCKoeY6U2ZjsZIgWg,5183
15
- agent_runtime/llm/openai.py,sha256=cRk4WBpiVknqsy_cgPAGdC8Zj250nasqo1dNQN0uxlw,6842
16
- agent_runtime/persistence/__init__.py,sha256=YynbxYtCtaSurQS9Ikenj9n_4xSEh0T9K0kOpg3IW04,2009
17
- agent_runtime/persistence/base.py,sha256=7p9HYWYY4pjmDvQgLh11Fie_XmMnkimkCG7tUQt0zUQ,9444
18
- agent_runtime/persistence/file.py,sha256=uMNSNfXvHPMJzl3QTrU-CPt1cLCH8J9rkaThbq7kLf0,17780
19
- agent_runtime/persistence/manager.py,sha256=PP-imx6ygIlUSID8rMwR9CTeD02HjZ3mdqczgZvF1es,9682
20
- agent_runtime/queue/__init__.py,sha256=78k29iEl8brp71LrOnmTHhQzPMHkzGre-Xqdl1NlNr0,1502
21
- agent_runtime/queue/base.py,sha256=QW1eWbwBX_tmVD8yJobFJtlxLd_RtUWHTuXGessuxy8,3959
22
- agent_runtime/queue/memory.py,sha256=n7kiE0Fw_BFUdzMyoO1QPO0ATzz8zBYaMQex7GdceZw,5411
23
- agent_runtime/queue/redis.py,sha256=buTCgqNz77q7ae_eNIRRUEyhx_jCgJ0Q3Bqe1Hz5G-s,15617
24
- agent_runtime/queue/sqlite.py,sha256=DyV2h3C5WuI9d_FjOmleeYvL7BbttMHN1E9XcK-X15w,14333
25
- agent_runtime/state/__init__.py,sha256=W9juyZD8N0zj5ERkWroW7O0SLWnoYFcLjGuR4tfFKs4,1539
26
- agent_runtime/state/base.py,sha256=NqE3B0ySa-U2jkelgmkBbkmkaIQxfu4pDryoxkZTMrc,1593
27
- agent_runtime/state/memory.py,sha256=xOnlqM3ArXDKAdPx3PxdS9IGgJDSM-EKp_S1Hsit180,1561
28
- agent_runtime/state/redis.py,sha256=-lPi_2xKm7Bc4DVMJfSEAF7wJHctLV3ZMM9AYBeQKZU,3425
29
- agent_runtime/state/sqlite.py,sha256=NwuiTBXELb2tyOoH91MZqRJaCk9h8PskyY2VUc5EMr0,4868
30
- agent_runtime/tracing/__init__.py,sha256=m4WzfgJpnV5XCCoMpBYZdJU_JTkAdhEhl7M7tpf62RY,1246
31
- agent_runtime/tracing/langfuse.py,sha256=Z-2eEUHlxCC82JtXOAaoi-1zI6tQwEOWdpJgfCXcZH0,3655
32
- agent_runtime/tracing/noop.py,sha256=MOm5eTrnf3d4WhiWrwVU5Kd3GmJ1903V0U7U3Qwho7U,746
33
- agent_runtime_core-0.2.1.dist-info/METADATA,sha256=_YZWAHr9zovJKJ0d0Xhk04lPfU9PeaN9gmUFFvaQM58,12488
34
- agent_runtime_core-0.2.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
35
- agent_runtime_core-0.2.1.dist-info/licenses/LICENSE,sha256=PcOO8aiOZ4H2MWYeKIis3o6xTCT1hNkDyCxHZhh1NeM,1070
36
- agent_runtime_core-0.2.1.dist-info/RECORD,,
File without changes
File without changes
File without changes
File without changes