agent-runtime-core 0.8.0__py3-none-any.whl → 0.9.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.
- agent_runtime_core/__init__.py +65 -3
- agent_runtime_core/agentic_loop.py +275 -15
- agent_runtime_core/config.py +4 -0
- agent_runtime_core/contexts.py +72 -4
- agent_runtime_core/llm/anthropic.py +83 -0
- agent_runtime_core/multi_agent.py +1408 -16
- agent_runtime_core/persistence/__init__.py +8 -0
- agent_runtime_core/persistence/base.py +318 -1
- agent_runtime_core/persistence/file.py +226 -2
- agent_runtime_core/privacy.py +250 -0
- {agent_runtime_core-0.8.0.dist-info → agent_runtime_core-0.9.0.dist-info}/METADATA +2 -1
- {agent_runtime_core-0.8.0.dist-info → agent_runtime_core-0.9.0.dist-info}/RECORD +14 -13
- {agent_runtime_core-0.8.0.dist-info → agent_runtime_core-0.9.0.dist-info}/WHEEL +0 -0
- {agent_runtime_core-0.8.0.dist-info → agent_runtime_core-0.9.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Privacy and user isolation abstractions for agent_runtime_core.
|
|
3
|
+
|
|
4
|
+
This module provides framework-agnostic definitions for:
|
|
5
|
+
|
|
6
|
+
1. **PrivacyConfig** - Settings that control what data is persisted and when.
|
|
7
|
+
Defaults to maximum privacy (auth required for all persistent data).
|
|
8
|
+
|
|
9
|
+
2. **UserContext** - Represents the current user (authenticated or anonymous).
|
|
10
|
+
Used to scope data access and enforce privacy rules.
|
|
11
|
+
|
|
12
|
+
3. **MemoryScope** - Defines how memory is scoped (conversation, user, system).
|
|
13
|
+
|
|
14
|
+
These abstractions are designed to be implemented by framework-specific code
|
|
15
|
+
(e.g., django_agent_runtime) while providing consistent privacy guarantees.
|
|
16
|
+
|
|
17
|
+
Example:
|
|
18
|
+
from agent_runtime_core.privacy import PrivacyConfig, UserContext, MemoryScope
|
|
19
|
+
|
|
20
|
+
# Maximum privacy (default)
|
|
21
|
+
config = PrivacyConfig()
|
|
22
|
+
assert config.require_auth_for_memory == True
|
|
23
|
+
assert config.require_auth_for_conversations == True
|
|
24
|
+
|
|
25
|
+
# Authenticated user
|
|
26
|
+
user = UserContext(
|
|
27
|
+
user_id="user-123",
|
|
28
|
+
is_authenticated=True,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# Anonymous user (no persistent data allowed by default)
|
|
32
|
+
anon = UserContext.anonymous()
|
|
33
|
+
assert anon.is_authenticated == False
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
from dataclasses import dataclass, field
|
|
37
|
+
from enum import Enum
|
|
38
|
+
from typing import Any, Optional
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class MemoryScope(str, Enum):
|
|
42
|
+
"""
|
|
43
|
+
Defines how memory is scoped.
|
|
44
|
+
|
|
45
|
+
CONVERSATION: Memory is scoped to a single conversation.
|
|
46
|
+
Lost when conversation ends. Safest option.
|
|
47
|
+
|
|
48
|
+
USER: Memory persists across conversations for a user.
|
|
49
|
+
Requires authentication. Good for preferences, learned facts.
|
|
50
|
+
|
|
51
|
+
SYSTEM: Memory is shared across all agents in a system for a user.
|
|
52
|
+
Requires authentication. Good for cross-agent knowledge sharing.
|
|
53
|
+
"""
|
|
54
|
+
CONVERSATION = "conversation"
|
|
55
|
+
USER = "user"
|
|
56
|
+
SYSTEM = "system"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@dataclass
|
|
60
|
+
class PrivacyConfig:
|
|
61
|
+
"""
|
|
62
|
+
Configuration for privacy and data persistence.
|
|
63
|
+
|
|
64
|
+
All settings default to maximum privacy (auth required for everything).
|
|
65
|
+
Framework implementations should respect these settings.
|
|
66
|
+
|
|
67
|
+
Attributes:
|
|
68
|
+
require_auth_for_memory: If True, memory is only stored for authenticated users.
|
|
69
|
+
Anonymous users get no persistent memory. Default: True.
|
|
70
|
+
|
|
71
|
+
require_auth_for_conversations: If True, conversations are only persisted for
|
|
72
|
+
authenticated users. Anonymous conversations
|
|
73
|
+
are ephemeral. Default: True.
|
|
74
|
+
|
|
75
|
+
require_auth_for_tool_tracking: If True, tool calls are only logged for
|
|
76
|
+
authenticated users. Default: True.
|
|
77
|
+
|
|
78
|
+
default_memory_scope: Default scope for new memories. Default: CONVERSATION.
|
|
79
|
+
|
|
80
|
+
allow_cross_agent_memory: If True, agents in a system can share memories
|
|
81
|
+
about a user. Requires SYSTEM scope. Default: True.
|
|
82
|
+
|
|
83
|
+
memory_retention_days: How long to retain user memories. None = forever.
|
|
84
|
+
Default: None.
|
|
85
|
+
|
|
86
|
+
conversation_retention_days: How long to retain conversations. None = forever.
|
|
87
|
+
Default: None.
|
|
88
|
+
|
|
89
|
+
metadata: Additional configuration metadata.
|
|
90
|
+
|
|
91
|
+
Example:
|
|
92
|
+
# Maximum privacy (default)
|
|
93
|
+
config = PrivacyConfig()
|
|
94
|
+
|
|
95
|
+
# Allow anonymous conversations but not memory
|
|
96
|
+
config = PrivacyConfig(
|
|
97
|
+
require_auth_for_conversations=False,
|
|
98
|
+
require_auth_for_memory=True,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Strict retention policy
|
|
102
|
+
config = PrivacyConfig(
|
|
103
|
+
memory_retention_days=30,
|
|
104
|
+
conversation_retention_days=90,
|
|
105
|
+
)
|
|
106
|
+
"""
|
|
107
|
+
require_auth_for_memory: bool = True
|
|
108
|
+
require_auth_for_conversations: bool = True
|
|
109
|
+
require_auth_for_tool_tracking: bool = True
|
|
110
|
+
default_memory_scope: MemoryScope = MemoryScope.CONVERSATION
|
|
111
|
+
allow_cross_agent_memory: bool = True
|
|
112
|
+
memory_retention_days: Optional[int] = None
|
|
113
|
+
conversation_retention_days: Optional[int] = None
|
|
114
|
+
metadata: dict = field(default_factory=dict)
|
|
115
|
+
|
|
116
|
+
def allows_memory(self, user: "UserContext") -> bool:
|
|
117
|
+
"""Check if memory storage is allowed for this user."""
|
|
118
|
+
if self.require_auth_for_memory:
|
|
119
|
+
return user.is_authenticated
|
|
120
|
+
return True
|
|
121
|
+
|
|
122
|
+
def allows_conversation_persistence(self, user: "UserContext") -> bool:
|
|
123
|
+
"""Check if conversation persistence is allowed for this user."""
|
|
124
|
+
if self.require_auth_for_conversations:
|
|
125
|
+
return user.is_authenticated
|
|
126
|
+
return True
|
|
127
|
+
|
|
128
|
+
def allows_tool_tracking(self, user: "UserContext") -> bool:
|
|
129
|
+
"""Check if tool call tracking is allowed for this user."""
|
|
130
|
+
if self.require_auth_for_tool_tracking:
|
|
131
|
+
return user.is_authenticated
|
|
132
|
+
return True
|
|
133
|
+
|
|
134
|
+
def to_dict(self) -> dict:
|
|
135
|
+
"""Serialize to dictionary."""
|
|
136
|
+
return {
|
|
137
|
+
"require_auth_for_memory": self.require_auth_for_memory,
|
|
138
|
+
"require_auth_for_conversations": self.require_auth_for_conversations,
|
|
139
|
+
"require_auth_for_tool_tracking": self.require_auth_for_tool_tracking,
|
|
140
|
+
"default_memory_scope": self.default_memory_scope.value,
|
|
141
|
+
"allow_cross_agent_memory": self.allow_cross_agent_memory,
|
|
142
|
+
"memory_retention_days": self.memory_retention_days,
|
|
143
|
+
"conversation_retention_days": self.conversation_retention_days,
|
|
144
|
+
"metadata": self.metadata,
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
@classmethod
|
|
148
|
+
def from_dict(cls, data: dict) -> "PrivacyConfig":
|
|
149
|
+
"""Deserialize from dictionary."""
|
|
150
|
+
return cls(
|
|
151
|
+
require_auth_for_memory=data.get("require_auth_for_memory", True),
|
|
152
|
+
require_auth_for_conversations=data.get("require_auth_for_conversations", True),
|
|
153
|
+
require_auth_for_tool_tracking=data.get("require_auth_for_tool_tracking", True),
|
|
154
|
+
default_memory_scope=MemoryScope(data.get("default_memory_scope", "conversation")),
|
|
155
|
+
allow_cross_agent_memory=data.get("allow_cross_agent_memory", True),
|
|
156
|
+
memory_retention_days=data.get("memory_retention_days"),
|
|
157
|
+
conversation_retention_days=data.get("conversation_retention_days"),
|
|
158
|
+
metadata=data.get("metadata", {}),
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
@dataclass
|
|
163
|
+
class UserContext:
|
|
164
|
+
"""
|
|
165
|
+
Represents the current user for privacy and data isolation.
|
|
166
|
+
|
|
167
|
+
This is a framework-agnostic representation of a user. Framework
|
|
168
|
+
implementations (e.g., Django) should create UserContext from their
|
|
169
|
+
native user objects.
|
|
170
|
+
|
|
171
|
+
Attributes:
|
|
172
|
+
user_id: Unique identifier for the user. None for anonymous users.
|
|
173
|
+
is_authenticated: Whether the user is authenticated.
|
|
174
|
+
username: Optional username for display purposes.
|
|
175
|
+
email: Optional email address.
|
|
176
|
+
metadata: Additional user metadata (roles, permissions, etc.)
|
|
177
|
+
|
|
178
|
+
Example:
|
|
179
|
+
# From Django user
|
|
180
|
+
user_ctx = UserContext(
|
|
181
|
+
user_id=str(request.user.id),
|
|
182
|
+
is_authenticated=request.user.is_authenticated,
|
|
183
|
+
username=request.user.username,
|
|
184
|
+
email=request.user.email,
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
# Anonymous user
|
|
188
|
+
user_ctx = UserContext.anonymous()
|
|
189
|
+
|
|
190
|
+
# Check permissions
|
|
191
|
+
if privacy_config.allows_memory(user_ctx):
|
|
192
|
+
store.save_memory(...)
|
|
193
|
+
"""
|
|
194
|
+
user_id: Optional[str] = None
|
|
195
|
+
is_authenticated: bool = False
|
|
196
|
+
username: Optional[str] = None
|
|
197
|
+
email: Optional[str] = None
|
|
198
|
+
metadata: dict = field(default_factory=dict)
|
|
199
|
+
|
|
200
|
+
@classmethod
|
|
201
|
+
def anonymous(cls) -> "UserContext":
|
|
202
|
+
"""Create an anonymous user context."""
|
|
203
|
+
return cls(
|
|
204
|
+
user_id=None,
|
|
205
|
+
is_authenticated=False,
|
|
206
|
+
username=None,
|
|
207
|
+
email=None,
|
|
208
|
+
metadata={"anonymous": True},
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
@classmethod
|
|
212
|
+
def from_user_id(cls, user_id: str, **kwargs) -> "UserContext":
|
|
213
|
+
"""Create an authenticated user context from a user ID."""
|
|
214
|
+
return cls(
|
|
215
|
+
user_id=user_id,
|
|
216
|
+
is_authenticated=True,
|
|
217
|
+
**kwargs,
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
def to_dict(self) -> dict:
|
|
221
|
+
"""Serialize to dictionary."""
|
|
222
|
+
return {
|
|
223
|
+
"user_id": self.user_id,
|
|
224
|
+
"is_authenticated": self.is_authenticated,
|
|
225
|
+
"username": self.username,
|
|
226
|
+
"email": self.email,
|
|
227
|
+
"metadata": self.metadata,
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
@classmethod
|
|
231
|
+
def from_dict(cls, data: dict) -> "UserContext":
|
|
232
|
+
"""Deserialize from dictionary."""
|
|
233
|
+
return cls(
|
|
234
|
+
user_id=data.get("user_id"),
|
|
235
|
+
is_authenticated=data.get("is_authenticated", False),
|
|
236
|
+
username=data.get("username"),
|
|
237
|
+
email=data.get("email"),
|
|
238
|
+
metadata=data.get("metadata", {}),
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
def __str__(self) -> str:
|
|
242
|
+
if self.is_authenticated:
|
|
243
|
+
return f"User({self.username or self.user_id})"
|
|
244
|
+
return "AnonymousUser"
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
# Default instances for convenience
|
|
248
|
+
DEFAULT_PRIVACY_CONFIG = PrivacyConfig()
|
|
249
|
+
ANONYMOUS_USER = UserContext.anonymous()
|
|
250
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-runtime-core
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Summary: Framework-agnostic Python library for executing AI agents with consistent patterns
|
|
5
5
|
Project-URL: Homepage, https://github.com/makemore/agent-runtime-core
|
|
6
6
|
Project-URL: Repository, https://github.com/makemore/agent-runtime-core
|
|
@@ -92,6 +92,7 @@ A lightweight, framework-agnostic Python library for building AI agent systems.
|
|
|
92
92
|
|
|
93
93
|
| Version | Date | Changes |
|
|
94
94
|
|---------|------|---------|
|
|
95
|
+
| **0.9.0** | 2026-01-28 | **Multi-Agent & Debug** - Shared memory with privacy controls, journey mode, structured handback protocol, stuck/loop detection, fallback routing, cost/context tracking in debug mode |
|
|
95
96
|
| **0.8.0** | 2026-01-28 | **File Ingestion** - Pluggable file processors (PDF, images, DOCX, XLSX, CSV), OCR providers (Tesseract, Google Vision, AWS Textract, Azure), AI vision (OpenAI, Anthropic, Gemini), file read/write tools |
|
|
96
97
|
| **0.7.1** | 2026-01-24 | RAG module, vector stores (sqlite-vec, Vertex AI), memory system, multi-agent support, agentic loop, JSON runtime |
|
|
97
98
|
| **0.6.0** | 2025-01-23 | Enhanced registry with factory functions and class registration |
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
agent_runtime_core/__init__.py,sha256=
|
|
2
|
-
agent_runtime_core/agentic_loop.py,sha256=
|
|
3
|
-
agent_runtime_core/config.py,sha256=
|
|
1
|
+
agent_runtime_core/__init__.py,sha256=80m5og5XW2cGvFlU2dQ4aj8RZ_Z0gQdswstmkhxVleM,8656
|
|
2
|
+
agent_runtime_core/agentic_loop.py,sha256=vEfC4UVfTZ06Ec00Dl7azqP6mbx7Lk7oyvvrXuZJksI,21763
|
|
3
|
+
agent_runtime_core/config.py,sha256=tYJam_EbLBZW7wW07RTn3A7xF1TWKsBKGxOp02KRudU,7426
|
|
4
4
|
agent_runtime_core/config_schema.py,sha256=1t2ZF5Rk2oRbeYpRATMdFgbvgTPtedIQO6xej4cELh0,10576
|
|
5
|
-
agent_runtime_core/contexts.py,sha256=
|
|
5
|
+
agent_runtime_core/contexts.py,sha256=ws4St30698DR6E-ce9ou0wJwFxUE3S_pPXNcXrlDB-Q,14474
|
|
6
6
|
agent_runtime_core/interfaces.py,sha256=QvRFPRc2Fwqv_sv-3nExCoaiqwBf_HsQo9yzCYE_Hm0,15498
|
|
7
7
|
agent_runtime_core/json_runtime.py,sha256=b1BnGAQMORB4YULsKcCR0hEaCvln3Bz2dP228yq5BIQ,17358
|
|
8
|
-
agent_runtime_core/multi_agent.py,sha256=
|
|
8
|
+
agent_runtime_core/multi_agent.py,sha256=Lq5Brjan-alJPNkhLtBEaN9PWPG3QoDbGHagBBMYrzA,68091
|
|
9
|
+
agent_runtime_core/privacy.py,sha256=47b_5FrUBhNrONaziLlVvUOxtmzaMSYGkrVN6krFDjw,8983
|
|
9
10
|
agent_runtime_core/registry.py,sha256=QmazCAcHTsPt236Z_xEBJjdppm6jUuufE-gfvcGMUCk,3959
|
|
10
11
|
agent_runtime_core/runner.py,sha256=ydzyGJHCyz1wjs-sN5dx4RlJsYK0U-Or12BL_Fg8-aQ,19595
|
|
11
12
|
agent_runtime_core/steps.py,sha256=XpVFK7P-ZOpr7NwaP7XFygduIpjrKld-OIig7dHNMKE,11994
|
|
@@ -24,16 +25,16 @@ agent_runtime_core/files/processors.py,sha256=KudeacTDxaVyUtCjBpIg1OuByi4_71WP9R
|
|
|
24
25
|
agent_runtime_core/files/tools.py,sha256=Dky2CxFLUL8GICIwU1kbNV-IwnszWr1WXhJ3FItGRd4,10856
|
|
25
26
|
agent_runtime_core/files/vision.py,sha256=nM8xKx-yEblwPFr5tM9JRrFkitTPLDkLU1fSDHLvuW8,10119
|
|
26
27
|
agent_runtime_core/llm/__init__.py,sha256=7-tA1FmPkhY1l-lHhzd84MQf2bjs26bcgb8oAlglc58,4605
|
|
27
|
-
agent_runtime_core/llm/anthropic.py,sha256=
|
|
28
|
+
agent_runtime_core/llm/anthropic.py,sha256=vHnTsByHze6nTxt89o5rNOdG4YI7uHZBQzyJyEp6LNI,15679
|
|
28
29
|
agent_runtime_core/llm/litellm_client.py,sha256=c-O-lE08cT3ne0xSOvSDezPL6hCiA69p3HnB451Ipe4,5193
|
|
29
30
|
agent_runtime_core/llm/models_config.py,sha256=i275wtsWeR-LHdFrObPI19PtCIGvMDKTEKpue5TuYIk,5342
|
|
30
31
|
agent_runtime_core/llm/openai.py,sha256=qBZkkndDgYQ6LG-9bHS2za5KJTGSgL-c_7h0bD3_5lg,6862
|
|
31
32
|
agent_runtime_core/memory/__init__.py,sha256=7dgoXMr3IIjKsKKbxVgQBrrhZHqmJRIx64mcbF8jgUM,2178
|
|
32
33
|
agent_runtime_core/memory/manager.py,sha256=ba8ZKb1aF9Pc-zZB4O_22b6zb6ELpvo_LhpSs959L5U,18474
|
|
33
34
|
agent_runtime_core/memory/mixin.py,sha256=Afq7rhW1SmZgii6b3gUbM3peDzMwfMxQ0DstHzGfuDM,9683
|
|
34
|
-
agent_runtime_core/persistence/__init__.py,sha256=
|
|
35
|
-
agent_runtime_core/persistence/base.py,sha256=
|
|
36
|
-
agent_runtime_core/persistence/file.py,sha256=
|
|
35
|
+
agent_runtime_core/persistence/__init__.py,sha256=TeGcQSfNGGBAc_aEWmSkxh6U-rG_Gbelyk2CAke8Lwg,3008
|
|
36
|
+
agent_runtime_core/persistence/base.py,sha256=zyKQDTKMX9rHucota1RI6zWQzmiOd_R6qHCaLZfyvXk,32015
|
|
37
|
+
agent_runtime_core/persistence/file.py,sha256=QfhRdPI4bEDJJaKogG-kYdD0HkWpNEOE2-3oEtMlUZQ,36005
|
|
37
38
|
agent_runtime_core/persistence/manager.py,sha256=UL_eFsFM28nXM6O9PTHdzKX9Qxh9v2gBGd1m9Bs0vog,14309
|
|
38
39
|
agent_runtime_core/queue/__init__.py,sha256=m8gapXACPGApLj0RIDpVe5cQYuvKq1QsY2_mXzZcULQ,1527
|
|
39
40
|
agent_runtime_core/queue/base.py,sha256=QW1eWbwBX_tmVD8yJobFJtlxLd_RtUWHTuXGessuxy8,3959
|
|
@@ -57,7 +58,7 @@ agent_runtime_core/vectorstore/base.py,sha256=y1ZZCbAMkFkbHwOqzaK0JUBAVjbnNwwdSn
|
|
|
57
58
|
agent_runtime_core/vectorstore/embeddings.py,sha256=WTTiId9Q6I7cxHuiInYHEV8EWS2HyRYRW1YDPALGUVY,7749
|
|
58
59
|
agent_runtime_core/vectorstore/sqlite_vec.py,sha256=B4KPYdSkm-af-uqltqMga1uXslC19Uaeuy1sXfKOjyo,10552
|
|
59
60
|
agent_runtime_core/vectorstore/vertex.py,sha256=a1Ps_gMYqTlWUkNALpgMVEX6r6Zw_8gN5pZ59-vH7Ww,9695
|
|
60
|
-
agent_runtime_core-0.
|
|
61
|
-
agent_runtime_core-0.
|
|
62
|
-
agent_runtime_core-0.
|
|
63
|
-
agent_runtime_core-0.
|
|
61
|
+
agent_runtime_core-0.9.0.dist-info/METADATA,sha256=GPWqR2T9BOXyN9ZSC-wO6lFtbuiAoFHo24pL5Zw9sCA,32643
|
|
62
|
+
agent_runtime_core-0.9.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
63
|
+
agent_runtime_core-0.9.0.dist-info/licenses/LICENSE,sha256=fDlWep3_mUrj8KHV_jk275tHVEW7_9sJRhkNuGCZ_TA,1068
|
|
64
|
+
agent_runtime_core-0.9.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|