django-agent-runtime 0.3.6__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.
- django_agent_runtime/__init__.py +25 -0
- django_agent_runtime/admin.py +155 -0
- django_agent_runtime/api/__init__.py +26 -0
- django_agent_runtime/api/permissions.py +109 -0
- django_agent_runtime/api/serializers.py +114 -0
- django_agent_runtime/api/views.py +472 -0
- django_agent_runtime/apps.py +26 -0
- django_agent_runtime/conf.py +241 -0
- django_agent_runtime/examples/__init__.py +10 -0
- django_agent_runtime/examples/langgraph_adapter.py +164 -0
- django_agent_runtime/examples/langgraph_tools.py +179 -0
- django_agent_runtime/examples/simple_chat.py +69 -0
- django_agent_runtime/examples/tool_agent.py +157 -0
- django_agent_runtime/management/__init__.py +2 -0
- django_agent_runtime/management/commands/__init__.py +2 -0
- django_agent_runtime/management/commands/runagent.py +419 -0
- django_agent_runtime/migrations/0001_initial.py +117 -0
- django_agent_runtime/migrations/0002_persistence_models.py +129 -0
- django_agent_runtime/migrations/0003_persistenceconversation_active_branch_id_and_more.py +212 -0
- django_agent_runtime/migrations/0004_add_anonymous_session_id.py +18 -0
- django_agent_runtime/migrations/__init__.py +2 -0
- django_agent_runtime/models/__init__.py +54 -0
- django_agent_runtime/models/base.py +450 -0
- django_agent_runtime/models/concrete.py +146 -0
- django_agent_runtime/persistence/__init__.py +60 -0
- django_agent_runtime/persistence/helpers.py +148 -0
- django_agent_runtime/persistence/models.py +506 -0
- django_agent_runtime/persistence/stores.py +1191 -0
- django_agent_runtime/runtime/__init__.py +23 -0
- django_agent_runtime/runtime/events/__init__.py +65 -0
- django_agent_runtime/runtime/events/base.py +135 -0
- django_agent_runtime/runtime/events/db.py +129 -0
- django_agent_runtime/runtime/events/redis.py +228 -0
- django_agent_runtime/runtime/events/sync.py +140 -0
- django_agent_runtime/runtime/interfaces.py +475 -0
- django_agent_runtime/runtime/llm/__init__.py +91 -0
- django_agent_runtime/runtime/llm/anthropic.py +249 -0
- django_agent_runtime/runtime/llm/litellm_adapter.py +173 -0
- django_agent_runtime/runtime/llm/openai.py +230 -0
- django_agent_runtime/runtime/queue/__init__.py +75 -0
- django_agent_runtime/runtime/queue/base.py +158 -0
- django_agent_runtime/runtime/queue/postgres.py +248 -0
- django_agent_runtime/runtime/queue/redis_streams.py +336 -0
- django_agent_runtime/runtime/queue/sync.py +277 -0
- django_agent_runtime/runtime/registry.py +186 -0
- django_agent_runtime/runtime/runner.py +540 -0
- django_agent_runtime/runtime/tracing/__init__.py +48 -0
- django_agent_runtime/runtime/tracing/langfuse.py +117 -0
- django_agent_runtime/runtime/tracing/noop.py +36 -0
- django_agent_runtime/urls.py +39 -0
- django_agent_runtime-0.3.6.dist-info/METADATA +723 -0
- django_agent_runtime-0.3.6.dist-info/RECORD +55 -0
- django_agent_runtime-0.3.6.dist-info/WHEEL +5 -0
- django_agent_runtime-0.3.6.dist-info/licenses/LICENSE +22 -0
- django_agent_runtime-0.3.6.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Helper functions for configuring persistence in Django.
|
|
3
|
+
|
|
4
|
+
Provides convenient ways to get a PersistenceManager configured
|
|
5
|
+
with Django-backed stores for the current request/user.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Optional
|
|
9
|
+
|
|
10
|
+
from agent_runtime_core.persistence import (
|
|
11
|
+
PersistenceConfig,
|
|
12
|
+
PersistenceManager,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
from django_agent_runtime.persistence.stores import (
|
|
16
|
+
DjangoMemoryStore,
|
|
17
|
+
DjangoConversationStore,
|
|
18
|
+
DjangoTaskStore,
|
|
19
|
+
DjangoPreferencesStore,
|
|
20
|
+
DjangoKnowledgeStore,
|
|
21
|
+
DjangoAuditStore,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def get_persistence_config(user) -> PersistenceConfig:
|
|
26
|
+
"""
|
|
27
|
+
Get a PersistenceConfig configured with Django stores for a user.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
user: Django user instance
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
PersistenceConfig with all Django stores configured
|
|
34
|
+
|
|
35
|
+
Example:
|
|
36
|
+
from django_agent_runtime.persistence import get_persistence_config
|
|
37
|
+
from agent_runtime_core.persistence import PersistenceManager
|
|
38
|
+
|
|
39
|
+
config = get_persistence_config(request.user)
|
|
40
|
+
manager = PersistenceManager(config)
|
|
41
|
+
|
|
42
|
+
# Use the manager
|
|
43
|
+
await manager.memory.set("key", "value")
|
|
44
|
+
"""
|
|
45
|
+
return PersistenceConfig(
|
|
46
|
+
memory_store=DjangoMemoryStore(user=user),
|
|
47
|
+
conversation_store=DjangoConversationStore(user=user),
|
|
48
|
+
task_store=DjangoTaskStore(user=user),
|
|
49
|
+
preferences_store=DjangoPreferencesStore(user=user),
|
|
50
|
+
knowledge_store=DjangoKnowledgeStore(user=user),
|
|
51
|
+
audit_store=DjangoAuditStore(user=user),
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def get_persistence_manager(user) -> PersistenceManager:
|
|
56
|
+
"""
|
|
57
|
+
Get a PersistenceManager configured with Django stores for a user.
|
|
58
|
+
|
|
59
|
+
This is a convenience function that creates both the config and manager.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
user: Django user instance
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
PersistenceManager ready to use
|
|
66
|
+
|
|
67
|
+
Example:
|
|
68
|
+
from django_agent_runtime.persistence import get_persistence_manager
|
|
69
|
+
|
|
70
|
+
async def my_view(request):
|
|
71
|
+
manager = get_persistence_manager(request.user)
|
|
72
|
+
|
|
73
|
+
# Store memory
|
|
74
|
+
await manager.memory.set("last_query", "hello world")
|
|
75
|
+
|
|
76
|
+
# Get preferences
|
|
77
|
+
theme = await manager.preferences.get("theme")
|
|
78
|
+
"""
|
|
79
|
+
config = get_persistence_config(user)
|
|
80
|
+
return PersistenceManager(config)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class PersistenceMiddleware:
|
|
84
|
+
"""
|
|
85
|
+
Django middleware that attaches a PersistenceManager to the request.
|
|
86
|
+
|
|
87
|
+
Add to MIDDLEWARE in settings.py:
|
|
88
|
+
MIDDLEWARE = [
|
|
89
|
+
...
|
|
90
|
+
'django_agent_runtime.persistence.helpers.PersistenceMiddleware',
|
|
91
|
+
]
|
|
92
|
+
|
|
93
|
+
Then access in views:
|
|
94
|
+
async def my_view(request):
|
|
95
|
+
await request.persistence.memory.set("key", "value")
|
|
96
|
+
|
|
97
|
+
Note: Only works for authenticated users. For anonymous users,
|
|
98
|
+
request.persistence will be None.
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
def __init__(self, get_response):
|
|
102
|
+
self.get_response = get_response
|
|
103
|
+
|
|
104
|
+
def __call__(self, request):
|
|
105
|
+
# Attach persistence manager for authenticated users
|
|
106
|
+
if hasattr(request, 'user') and request.user.is_authenticated:
|
|
107
|
+
request.persistence = get_persistence_manager(request.user)
|
|
108
|
+
else:
|
|
109
|
+
request.persistence = None
|
|
110
|
+
|
|
111
|
+
response = self.get_response(request)
|
|
112
|
+
return response
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def get_store_factories(user_getter):
|
|
116
|
+
"""
|
|
117
|
+
Get factory functions for lazy store instantiation.
|
|
118
|
+
|
|
119
|
+
Useful when you need to defer user resolution (e.g., in class-based views).
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
user_getter: Callable that returns the current user
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
Dict of factory functions suitable for PersistenceConfig
|
|
126
|
+
|
|
127
|
+
Example:
|
|
128
|
+
from django_agent_runtime.persistence.helpers import get_store_factories
|
|
129
|
+
|
|
130
|
+
# In a class-based view
|
|
131
|
+
factories = get_store_factories(lambda: self.request.user)
|
|
132
|
+
config = PersistenceConfig(
|
|
133
|
+
memory_store_factory=factories['memory'],
|
|
134
|
+
conversation_store_factory=factories['conversation'],
|
|
135
|
+
task_store_factory=factories['task'],
|
|
136
|
+
preferences_store_factory=factories['preferences'],
|
|
137
|
+
knowledge_store_factory=factories['knowledge'],
|
|
138
|
+
audit_store_factory=factories['audit'],
|
|
139
|
+
)
|
|
140
|
+
"""
|
|
141
|
+
return {
|
|
142
|
+
'memory': lambda: DjangoMemoryStore(user=user_getter()),
|
|
143
|
+
'conversation': lambda: DjangoConversationStore(user=user_getter()),
|
|
144
|
+
'task': lambda: DjangoTaskStore(user=user_getter()),
|
|
145
|
+
'preferences': lambda: DjangoPreferencesStore(user=user_getter()),
|
|
146
|
+
'knowledge': lambda: DjangoKnowledgeStore(user=user_getter()),
|
|
147
|
+
'audit': lambda: DjangoAuditStore(user=user_getter()),
|
|
148
|
+
}
|
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Django models for the persistence layer.
|
|
3
|
+
|
|
4
|
+
These models back the Django implementations of the agent-runtime-core
|
|
5
|
+
persistence stores.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import uuid
|
|
9
|
+
from django.db import models
|
|
10
|
+
from django.conf import settings
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Memory(models.Model):
|
|
14
|
+
"""
|
|
15
|
+
Key-value memory storage for agents.
|
|
16
|
+
|
|
17
|
+
Stores arbitrary JSON-serializable values keyed by string.
|
|
18
|
+
Scoped to a user for multi-tenant support.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
22
|
+
user = models.ForeignKey(
|
|
23
|
+
settings.AUTH_USER_MODEL,
|
|
24
|
+
on_delete=models.CASCADE,
|
|
25
|
+
related_name="agent_memories",
|
|
26
|
+
)
|
|
27
|
+
key = models.CharField(max_length=255, db_index=True)
|
|
28
|
+
value = models.JSONField()
|
|
29
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
|
30
|
+
updated_at = models.DateTimeField(auto_now=True)
|
|
31
|
+
|
|
32
|
+
class Meta:
|
|
33
|
+
app_label = "django_agent_runtime"
|
|
34
|
+
db_table = "agent_runtime_memory"
|
|
35
|
+
unique_together = [("user", "key")]
|
|
36
|
+
verbose_name = "Agent Memory"
|
|
37
|
+
verbose_name_plural = "Agent Memories"
|
|
38
|
+
|
|
39
|
+
def __str__(self):
|
|
40
|
+
return f"{self.key} ({self.user})"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class PersistenceConversation(models.Model):
|
|
44
|
+
"""
|
|
45
|
+
Conversation storage for the persistence layer.
|
|
46
|
+
|
|
47
|
+
This is separate from AgentConversation to support the agent-runtime-core
|
|
48
|
+
persistence interface which has different semantics.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
52
|
+
user = models.ForeignKey(
|
|
53
|
+
settings.AUTH_USER_MODEL,
|
|
54
|
+
on_delete=models.CASCADE,
|
|
55
|
+
related_name="persistence_conversations",
|
|
56
|
+
)
|
|
57
|
+
title = models.CharField(max_length=255, blank=True)
|
|
58
|
+
agent_key = models.CharField(max_length=100, blank=True, db_index=True)
|
|
59
|
+
summary = models.TextField(blank=True)
|
|
60
|
+
metadata = models.JSONField(default=dict, blank=True)
|
|
61
|
+
created_at = models.DateTimeField(auto_now_add=True, db_index=True)
|
|
62
|
+
updated_at = models.DateTimeField(auto_now=True)
|
|
63
|
+
|
|
64
|
+
# Branching/forking support
|
|
65
|
+
parent_conversation_id = models.UUIDField(null=True, blank=True, db_index=True)
|
|
66
|
+
active_branch_id = models.UUIDField(null=True, blank=True)
|
|
67
|
+
|
|
68
|
+
class Meta:
|
|
69
|
+
app_label = "django_agent_runtime"
|
|
70
|
+
db_table = "agent_runtime_persistence_conversation"
|
|
71
|
+
ordering = ["-updated_at"]
|
|
72
|
+
verbose_name = "Persistence Conversation"
|
|
73
|
+
verbose_name_plural = "Persistence Conversations"
|
|
74
|
+
|
|
75
|
+
def __str__(self):
|
|
76
|
+
return f"{self.title or 'Untitled'} ({self.id})"
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class PersistenceMessage(models.Model):
|
|
80
|
+
"""
|
|
81
|
+
Message within a persistence conversation.
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
85
|
+
conversation = models.ForeignKey(
|
|
86
|
+
PersistenceConversation,
|
|
87
|
+
on_delete=models.CASCADE,
|
|
88
|
+
related_name="messages",
|
|
89
|
+
)
|
|
90
|
+
role = models.CharField(max_length=20) # system, user, assistant, tool
|
|
91
|
+
content = models.JSONField() # Can be string, dict, or list
|
|
92
|
+
tool_calls = models.JSONField(default=list, blank=True)
|
|
93
|
+
tool_call_id = models.CharField(max_length=255, blank=True)
|
|
94
|
+
model = models.CharField(max_length=100, blank=True)
|
|
95
|
+
usage = models.JSONField(default=dict, blank=True)
|
|
96
|
+
metadata = models.JSONField(default=dict, blank=True)
|
|
97
|
+
timestamp = models.DateTimeField(auto_now_add=True, db_index=True)
|
|
98
|
+
|
|
99
|
+
# Branching support
|
|
100
|
+
parent_message_id = models.UUIDField(null=True, blank=True, db_index=True)
|
|
101
|
+
branch_id = models.UUIDField(null=True, blank=True, db_index=True)
|
|
102
|
+
|
|
103
|
+
class Meta:
|
|
104
|
+
app_label = "django_agent_runtime"
|
|
105
|
+
db_table = "agent_runtime_persistence_message"
|
|
106
|
+
ordering = ["timestamp"]
|
|
107
|
+
verbose_name = "Persistence Message"
|
|
108
|
+
verbose_name_plural = "Persistence Messages"
|
|
109
|
+
|
|
110
|
+
def __str__(self):
|
|
111
|
+
return f"{self.role}: {str(self.content)[:50]}"
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class TaskStateChoices(models.TextChoices):
|
|
115
|
+
"""Task state choices matching agent_runtime_core.persistence.TaskState."""
|
|
116
|
+
|
|
117
|
+
NOT_STARTED = "not_started", "Not Started"
|
|
118
|
+
IN_PROGRESS = "in_progress", "In Progress"
|
|
119
|
+
COMPLETE = "complete", "Complete"
|
|
120
|
+
CANCELLED = "cancelled", "Cancelled"
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class PersistenceTaskList(models.Model):
|
|
124
|
+
"""
|
|
125
|
+
Task list for tracking agent work.
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
129
|
+
user = models.ForeignKey(
|
|
130
|
+
settings.AUTH_USER_MODEL,
|
|
131
|
+
on_delete=models.CASCADE,
|
|
132
|
+
related_name="persistence_task_lists",
|
|
133
|
+
)
|
|
134
|
+
name = models.CharField(max_length=255)
|
|
135
|
+
conversation_id = models.UUIDField(null=True, blank=True, db_index=True)
|
|
136
|
+
run_id = models.UUIDField(null=True, blank=True, db_index=True)
|
|
137
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
|
138
|
+
updated_at = models.DateTimeField(auto_now=True)
|
|
139
|
+
|
|
140
|
+
class Meta:
|
|
141
|
+
app_label = "django_agent_runtime"
|
|
142
|
+
db_table = "agent_runtime_persistence_task_list"
|
|
143
|
+
ordering = ["-updated_at"]
|
|
144
|
+
verbose_name = "Persistence Task List"
|
|
145
|
+
verbose_name_plural = "Persistence Task Lists"
|
|
146
|
+
|
|
147
|
+
def __str__(self):
|
|
148
|
+
return self.name
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class PersistenceTask(models.Model):
|
|
152
|
+
"""
|
|
153
|
+
Individual task within a task list.
|
|
154
|
+
"""
|
|
155
|
+
|
|
156
|
+
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
157
|
+
task_list = models.ForeignKey(
|
|
158
|
+
PersistenceTaskList,
|
|
159
|
+
on_delete=models.CASCADE,
|
|
160
|
+
related_name="tasks",
|
|
161
|
+
)
|
|
162
|
+
name = models.CharField(max_length=255)
|
|
163
|
+
description = models.TextField(blank=True)
|
|
164
|
+
state = models.CharField(
|
|
165
|
+
max_length=20,
|
|
166
|
+
choices=TaskStateChoices.choices,
|
|
167
|
+
default=TaskStateChoices.NOT_STARTED,
|
|
168
|
+
)
|
|
169
|
+
parent_id = models.UUIDField(null=True, blank=True)
|
|
170
|
+
metadata = models.JSONField(default=dict, blank=True)
|
|
171
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
|
172
|
+
updated_at = models.DateTimeField(auto_now=True)
|
|
173
|
+
|
|
174
|
+
# Dependencies and scheduling
|
|
175
|
+
dependencies = models.JSONField(default=list, blank=True) # List of task UUIDs
|
|
176
|
+
priority = models.IntegerField(default=0) # Higher = more important
|
|
177
|
+
due_at = models.DateTimeField(null=True, blank=True)
|
|
178
|
+
completed_at = models.DateTimeField(null=True, blank=True)
|
|
179
|
+
|
|
180
|
+
# Checkpoint for resumable long-running operations
|
|
181
|
+
checkpoint_data = models.JSONField(default=dict, blank=True)
|
|
182
|
+
checkpoint_at = models.DateTimeField(null=True, blank=True)
|
|
183
|
+
|
|
184
|
+
# Execution tracking
|
|
185
|
+
attempts = models.IntegerField(default=0)
|
|
186
|
+
last_error = models.TextField(blank=True)
|
|
187
|
+
|
|
188
|
+
class Meta:
|
|
189
|
+
app_label = "django_agent_runtime"
|
|
190
|
+
db_table = "agent_runtime_persistence_task"
|
|
191
|
+
ordering = ["created_at"]
|
|
192
|
+
verbose_name = "Persistence Task"
|
|
193
|
+
verbose_name_plural = "Persistence Tasks"
|
|
194
|
+
|
|
195
|
+
def __str__(self):
|
|
196
|
+
return f"{self.name} ({self.state})"
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
class Preferences(models.Model):
|
|
200
|
+
"""
|
|
201
|
+
User preferences storage for agents.
|
|
202
|
+
|
|
203
|
+
Stores configuration and preferences that persist across sessions.
|
|
204
|
+
"""
|
|
205
|
+
|
|
206
|
+
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
207
|
+
user = models.ForeignKey(
|
|
208
|
+
settings.AUTH_USER_MODEL,
|
|
209
|
+
on_delete=models.CASCADE,
|
|
210
|
+
related_name="agent_preferences",
|
|
211
|
+
)
|
|
212
|
+
key = models.CharField(max_length=255, db_index=True)
|
|
213
|
+
value = models.JSONField()
|
|
214
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
|
215
|
+
updated_at = models.DateTimeField(auto_now=True)
|
|
216
|
+
|
|
217
|
+
class Meta:
|
|
218
|
+
app_label = "django_agent_runtime"
|
|
219
|
+
db_table = "agent_runtime_preferences"
|
|
220
|
+
unique_together = [("user", "key")]
|
|
221
|
+
verbose_name = "Agent Preference"
|
|
222
|
+
verbose_name_plural = "Agent Preferences"
|
|
223
|
+
|
|
224
|
+
def __str__(self):
|
|
225
|
+
return f"{self.key} ({self.user})"
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
# =============================================================================
|
|
229
|
+
# Knowledge Store Models
|
|
230
|
+
# =============================================================================
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
class FactTypeChoices(models.TextChoices):
|
|
234
|
+
"""Fact type choices matching agent_runtime_core.persistence.FactType."""
|
|
235
|
+
|
|
236
|
+
USER = "user", "User"
|
|
237
|
+
PROJECT = "project", "Project"
|
|
238
|
+
PREFERENCE = "preference", "Preference"
|
|
239
|
+
CONTEXT = "context", "Context"
|
|
240
|
+
CUSTOM = "custom", "Custom"
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
class Fact(models.Model):
|
|
244
|
+
"""
|
|
245
|
+
A learned fact about user, project, or context.
|
|
246
|
+
"""
|
|
247
|
+
|
|
248
|
+
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
249
|
+
user = models.ForeignKey(
|
|
250
|
+
settings.AUTH_USER_MODEL,
|
|
251
|
+
on_delete=models.CASCADE,
|
|
252
|
+
related_name="agent_facts",
|
|
253
|
+
)
|
|
254
|
+
key = models.CharField(max_length=255, db_index=True)
|
|
255
|
+
value = models.JSONField()
|
|
256
|
+
fact_type = models.CharField(
|
|
257
|
+
max_length=20,
|
|
258
|
+
choices=FactTypeChoices.choices,
|
|
259
|
+
default=FactTypeChoices.CUSTOM,
|
|
260
|
+
db_index=True,
|
|
261
|
+
)
|
|
262
|
+
confidence = models.FloatField(default=1.0) # 0.0 to 1.0
|
|
263
|
+
source = models.CharField(max_length=255, blank=True)
|
|
264
|
+
expires_at = models.DateTimeField(null=True, blank=True, db_index=True)
|
|
265
|
+
metadata = models.JSONField(default=dict, blank=True)
|
|
266
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
|
267
|
+
updated_at = models.DateTimeField(auto_now=True)
|
|
268
|
+
|
|
269
|
+
class Meta:
|
|
270
|
+
app_label = "django_agent_runtime"
|
|
271
|
+
db_table = "agent_runtime_fact"
|
|
272
|
+
unique_together = [("user", "key")]
|
|
273
|
+
verbose_name = "Fact"
|
|
274
|
+
verbose_name_plural = "Facts"
|
|
275
|
+
|
|
276
|
+
def __str__(self):
|
|
277
|
+
return f"{self.key}: {str(self.value)[:50]}"
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
class Summary(models.Model):
|
|
281
|
+
"""
|
|
282
|
+
A summary of a conversation or set of interactions.
|
|
283
|
+
"""
|
|
284
|
+
|
|
285
|
+
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
286
|
+
user = models.ForeignKey(
|
|
287
|
+
settings.AUTH_USER_MODEL,
|
|
288
|
+
on_delete=models.CASCADE,
|
|
289
|
+
related_name="agent_summaries",
|
|
290
|
+
)
|
|
291
|
+
content = models.TextField()
|
|
292
|
+
conversation_id = models.UUIDField(null=True, blank=True, db_index=True)
|
|
293
|
+
conversation_ids = models.JSONField(default=list, blank=True) # For multi-conversation summaries
|
|
294
|
+
start_time = models.DateTimeField(null=True, blank=True)
|
|
295
|
+
end_time = models.DateTimeField(null=True, blank=True)
|
|
296
|
+
metadata = models.JSONField(default=dict, blank=True)
|
|
297
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
|
298
|
+
|
|
299
|
+
class Meta:
|
|
300
|
+
app_label = "django_agent_runtime"
|
|
301
|
+
db_table = "agent_runtime_summary"
|
|
302
|
+
ordering = ["-created_at"]
|
|
303
|
+
verbose_name = "Summary"
|
|
304
|
+
verbose_name_plural = "Summaries"
|
|
305
|
+
|
|
306
|
+
def __str__(self):
|
|
307
|
+
return f"Summary: {self.content[:50]}"
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
class Embedding(models.Model):
|
|
311
|
+
"""
|
|
312
|
+
A vector embedding for semantic search.
|
|
313
|
+
|
|
314
|
+
Note: For optimal performance with large datasets, consider using
|
|
315
|
+
pgvector extension for PostgreSQL.
|
|
316
|
+
"""
|
|
317
|
+
|
|
318
|
+
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
319
|
+
user = models.ForeignKey(
|
|
320
|
+
settings.AUTH_USER_MODEL,
|
|
321
|
+
on_delete=models.CASCADE,
|
|
322
|
+
related_name="agent_embeddings",
|
|
323
|
+
)
|
|
324
|
+
vector = models.JSONField() # List of floats; use pgvector for production
|
|
325
|
+
content = models.TextField() # Original text
|
|
326
|
+
content_type = models.CharField(max_length=50, default="text", db_index=True)
|
|
327
|
+
source_id = models.UUIDField(null=True, blank=True, db_index=True)
|
|
328
|
+
model = models.CharField(max_length=100, blank=True)
|
|
329
|
+
dimensions = models.IntegerField(default=0)
|
|
330
|
+
metadata = models.JSONField(default=dict, blank=True)
|
|
331
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
|
332
|
+
|
|
333
|
+
class Meta:
|
|
334
|
+
app_label = "django_agent_runtime"
|
|
335
|
+
db_table = "agent_runtime_embedding"
|
|
336
|
+
verbose_name = "Embedding"
|
|
337
|
+
verbose_name_plural = "Embeddings"
|
|
338
|
+
|
|
339
|
+
def __str__(self):
|
|
340
|
+
return f"Embedding: {self.content[:50]}"
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
# =============================================================================
|
|
344
|
+
# Audit Store Models
|
|
345
|
+
# =============================================================================
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
class AuditEventTypeChoices(models.TextChoices):
|
|
349
|
+
"""Audit event type choices matching agent_runtime_core.persistence.AuditEventType."""
|
|
350
|
+
|
|
351
|
+
CONVERSATION_START = "conversation_start", "Conversation Start"
|
|
352
|
+
CONVERSATION_END = "conversation_end", "Conversation End"
|
|
353
|
+
MESSAGE_SENT = "message_sent", "Message Sent"
|
|
354
|
+
MESSAGE_RECEIVED = "message_received", "Message Received"
|
|
355
|
+
TOOL_CALL = "tool_call", "Tool Call"
|
|
356
|
+
TOOL_RESULT = "tool_result", "Tool Result"
|
|
357
|
+
TOOL_ERROR = "tool_error", "Tool Error"
|
|
358
|
+
AGENT_START = "agent_start", "Agent Start"
|
|
359
|
+
AGENT_END = "agent_end", "Agent End"
|
|
360
|
+
AGENT_ERROR = "agent_error", "Agent Error"
|
|
361
|
+
CHECKPOINT_SAVED = "checkpoint_saved", "Checkpoint Saved"
|
|
362
|
+
CHECKPOINT_RESTORED = "checkpoint_restored", "Checkpoint Restored"
|
|
363
|
+
CUSTOM = "custom", "Custom"
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
class ErrorSeverityChoices(models.TextChoices):
|
|
367
|
+
"""Error severity choices matching agent_runtime_core.persistence.ErrorSeverity."""
|
|
368
|
+
|
|
369
|
+
DEBUG = "debug", "Debug"
|
|
370
|
+
INFO = "info", "Info"
|
|
371
|
+
WARNING = "warning", "Warning"
|
|
372
|
+
ERROR = "error", "Error"
|
|
373
|
+
CRITICAL = "critical", "Critical"
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
class AuditEntry(models.Model):
|
|
377
|
+
"""
|
|
378
|
+
An audit log entry for tracking interactions.
|
|
379
|
+
"""
|
|
380
|
+
|
|
381
|
+
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
382
|
+
user = models.ForeignKey(
|
|
383
|
+
settings.AUTH_USER_MODEL,
|
|
384
|
+
on_delete=models.CASCADE,
|
|
385
|
+
related_name="agent_audit_entries",
|
|
386
|
+
)
|
|
387
|
+
event_type = models.CharField(
|
|
388
|
+
max_length=30,
|
|
389
|
+
choices=AuditEventTypeChoices.choices,
|
|
390
|
+
db_index=True,
|
|
391
|
+
)
|
|
392
|
+
timestamp = models.DateTimeField(auto_now_add=True, db_index=True)
|
|
393
|
+
|
|
394
|
+
# Context
|
|
395
|
+
conversation_id = models.UUIDField(null=True, blank=True, db_index=True)
|
|
396
|
+
run_id = models.UUIDField(null=True, blank=True, db_index=True)
|
|
397
|
+
agent_key = models.CharField(max_length=100, blank=True, db_index=True)
|
|
398
|
+
|
|
399
|
+
# Event details
|
|
400
|
+
action = models.CharField(max_length=255, blank=True)
|
|
401
|
+
details = models.JSONField(default=dict, blank=True)
|
|
402
|
+
|
|
403
|
+
# Actor information
|
|
404
|
+
actor_type = models.CharField(max_length=20, default="agent")
|
|
405
|
+
actor_id = models.CharField(max_length=255, blank=True)
|
|
406
|
+
|
|
407
|
+
# Request/response tracking
|
|
408
|
+
request_id = models.CharField(max_length=255, blank=True)
|
|
409
|
+
parent_event_id = models.UUIDField(null=True, blank=True)
|
|
410
|
+
|
|
411
|
+
metadata = models.JSONField(default=dict, blank=True)
|
|
412
|
+
|
|
413
|
+
class Meta:
|
|
414
|
+
app_label = "django_agent_runtime"
|
|
415
|
+
db_table = "agent_runtime_audit_entry"
|
|
416
|
+
ordering = ["-timestamp"]
|
|
417
|
+
verbose_name = "Audit Entry"
|
|
418
|
+
verbose_name_plural = "Audit Entries"
|
|
419
|
+
|
|
420
|
+
def __str__(self):
|
|
421
|
+
return f"{self.event_type}: {self.action}"
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
class ErrorRecord(models.Model):
|
|
425
|
+
"""
|
|
426
|
+
A record of an error for debugging.
|
|
427
|
+
"""
|
|
428
|
+
|
|
429
|
+
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
430
|
+
user = models.ForeignKey(
|
|
431
|
+
settings.AUTH_USER_MODEL,
|
|
432
|
+
on_delete=models.CASCADE,
|
|
433
|
+
related_name="agent_error_records",
|
|
434
|
+
)
|
|
435
|
+
timestamp = models.DateTimeField(auto_now_add=True, db_index=True)
|
|
436
|
+
severity = models.CharField(
|
|
437
|
+
max_length=10,
|
|
438
|
+
choices=ErrorSeverityChoices.choices,
|
|
439
|
+
default=ErrorSeverityChoices.ERROR,
|
|
440
|
+
db_index=True,
|
|
441
|
+
)
|
|
442
|
+
|
|
443
|
+
# Error details
|
|
444
|
+
error_type = models.CharField(max_length=255, blank=True)
|
|
445
|
+
message = models.TextField(blank=True)
|
|
446
|
+
stack_trace = models.TextField(blank=True)
|
|
447
|
+
|
|
448
|
+
# Context
|
|
449
|
+
conversation_id = models.UUIDField(null=True, blank=True, db_index=True)
|
|
450
|
+
run_id = models.UUIDField(null=True, blank=True, db_index=True)
|
|
451
|
+
agent_key = models.CharField(max_length=100, blank=True, db_index=True)
|
|
452
|
+
context = models.JSONField(default=dict, blank=True)
|
|
453
|
+
|
|
454
|
+
# Resolution tracking
|
|
455
|
+
resolved = models.BooleanField(default=False, db_index=True)
|
|
456
|
+
resolved_at = models.DateTimeField(null=True, blank=True)
|
|
457
|
+
resolution_notes = models.TextField(blank=True)
|
|
458
|
+
|
|
459
|
+
metadata = models.JSONField(default=dict, blank=True)
|
|
460
|
+
|
|
461
|
+
class Meta:
|
|
462
|
+
app_label = "django_agent_runtime"
|
|
463
|
+
db_table = "agent_runtime_error_record"
|
|
464
|
+
ordering = ["-timestamp"]
|
|
465
|
+
verbose_name = "Error Record"
|
|
466
|
+
verbose_name_plural = "Error Records"
|
|
467
|
+
|
|
468
|
+
def __str__(self):
|
|
469
|
+
return f"{self.severity}: {self.error_type}"
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
class PerformanceMetric(models.Model):
|
|
473
|
+
"""
|
|
474
|
+
A performance metric for monitoring.
|
|
475
|
+
"""
|
|
476
|
+
|
|
477
|
+
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
|
478
|
+
user = models.ForeignKey(
|
|
479
|
+
settings.AUTH_USER_MODEL,
|
|
480
|
+
on_delete=models.CASCADE,
|
|
481
|
+
related_name="agent_performance_metrics",
|
|
482
|
+
)
|
|
483
|
+
name = models.CharField(max_length=100, db_index=True)
|
|
484
|
+
value = models.FloatField()
|
|
485
|
+
unit = models.CharField(max_length=20, blank=True)
|
|
486
|
+
timestamp = models.DateTimeField(auto_now_add=True, db_index=True)
|
|
487
|
+
|
|
488
|
+
# Context
|
|
489
|
+
conversation_id = models.UUIDField(null=True, blank=True, db_index=True)
|
|
490
|
+
run_id = models.UUIDField(null=True, blank=True, db_index=True)
|
|
491
|
+
agent_key = models.CharField(max_length=100, blank=True, db_index=True)
|
|
492
|
+
|
|
493
|
+
# Additional dimensions for grouping/filtering
|
|
494
|
+
tags = models.JSONField(default=dict, blank=True)
|
|
495
|
+
|
|
496
|
+
metadata = models.JSONField(default=dict, blank=True)
|
|
497
|
+
|
|
498
|
+
class Meta:
|
|
499
|
+
app_label = "django_agent_runtime"
|
|
500
|
+
db_table = "agent_runtime_performance_metric"
|
|
501
|
+
ordering = ["-timestamp"]
|
|
502
|
+
verbose_name = "Performance Metric"
|
|
503
|
+
verbose_name_plural = "Performance Metrics"
|
|
504
|
+
|
|
505
|
+
def __str__(self):
|
|
506
|
+
return f"{self.name}: {self.value} {self.unit}"
|