Increase platform abstraction cohesion
This commit is contained in:
243
core/models.py
243
core/models.py
@@ -1129,6 +1129,14 @@ class MemoryItem(models.Model):
|
||||
related_name="memory_items",
|
||||
help_text="Conversation scope this memory item belongs to.",
|
||||
)
|
||||
person = models.ForeignKey(
|
||||
Person,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="memory_items",
|
||||
help_text="Optional person this memory is about for person-centric recall.",
|
||||
)
|
||||
memory_kind = models.CharField(
|
||||
max_length=16,
|
||||
choices=MEMORY_KIND_CHOICES,
|
||||
@@ -1145,6 +1153,25 @@ class MemoryItem(models.Model):
|
||||
blank=True,
|
||||
help_text="Structured memory payload (schema can evolve by type).",
|
||||
)
|
||||
provenance = models.JSONField(
|
||||
default=dict,
|
||||
blank=True,
|
||||
help_text="Source metadata for this memory (agent/tool/message references).",
|
||||
)
|
||||
confidence_score = models.FloatField(
|
||||
default=0.5,
|
||||
help_text="Confidence score for this memory (0.0-1.0).",
|
||||
)
|
||||
expires_at = models.DateTimeField(
|
||||
null=True,
|
||||
blank=True,
|
||||
help_text="Optional expiry timestamp for stale memory decay.",
|
||||
)
|
||||
last_verified_at = models.DateTimeField(
|
||||
null=True,
|
||||
blank=True,
|
||||
help_text="Last operator verification timestamp.",
|
||||
)
|
||||
source_request = models.ForeignKey(
|
||||
AIRequest,
|
||||
on_delete=models.SET_NULL,
|
||||
@@ -1161,6 +1188,111 @@ class MemoryItem(models.Model):
|
||||
help_text="Last update timestamp.",
|
||||
)
|
||||
|
||||
class Meta:
|
||||
indexes = [
|
||||
models.Index(fields=["user", "status", "updated_at"]),
|
||||
models.Index(fields=["user", "person", "status", "updated_at"]),
|
||||
models.Index(fields=["user", "conversation", "status", "updated_at"]),
|
||||
]
|
||||
|
||||
|
||||
class MemorySourceReference(models.Model):
|
||||
memory = models.ForeignKey(
|
||||
MemoryItem,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="source_references",
|
||||
)
|
||||
message_event = models.ForeignKey(
|
||||
"MessageEvent",
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="memory_source_references",
|
||||
)
|
||||
message = models.ForeignKey(
|
||||
Message,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="memory_source_references",
|
||||
)
|
||||
source_request = models.ForeignKey(
|
||||
AIRequest,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="memory_source_references",
|
||||
)
|
||||
source_label = models.CharField(max_length=255, blank=True, default="")
|
||||
source_uri = models.CharField(max_length=1024, blank=True, default="")
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
indexes = [
|
||||
models.Index(fields=["memory", "created_at"]),
|
||||
models.Index(fields=["source_uri"]),
|
||||
]
|
||||
|
||||
|
||||
class MemoryChangeRequest(models.Model):
|
||||
ACTION_CHOICES = (
|
||||
("create", "Create"),
|
||||
("update", "Update"),
|
||||
("delete", "Delete"),
|
||||
)
|
||||
STATUS_CHOICES = (
|
||||
("pending", "Pending"),
|
||||
("approved", "Approved"),
|
||||
("rejected", "Rejected"),
|
||||
("applied", "Applied"),
|
||||
)
|
||||
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
user = models.ForeignKey(
|
||||
User,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="memory_change_requests",
|
||||
)
|
||||
memory = models.ForeignKey(
|
||||
MemoryItem,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="change_requests",
|
||||
)
|
||||
conversation = models.ForeignKey(
|
||||
WorkspaceConversation,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="memory_change_requests",
|
||||
)
|
||||
person = models.ForeignKey(
|
||||
Person,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="memory_change_requests",
|
||||
)
|
||||
action = models.CharField(max_length=16, choices=ACTION_CHOICES)
|
||||
status = models.CharField(max_length=16, choices=STATUS_CHOICES, default="pending")
|
||||
proposed_memory_kind = models.CharField(max_length=16, blank=True, default="")
|
||||
proposed_content = models.JSONField(default=dict, blank=True)
|
||||
proposed_confidence_score = models.FloatField(null=True, blank=True)
|
||||
proposed_expires_at = models.DateTimeField(null=True, blank=True)
|
||||
reason = models.TextField(blank=True, default="")
|
||||
requested_by_identifier = models.CharField(max_length=255, blank=True, default="")
|
||||
reviewed_by_identifier = models.CharField(max_length=255, blank=True, default="")
|
||||
reviewed_at = models.DateTimeField(null=True, blank=True)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
class Meta:
|
||||
indexes = [
|
||||
models.Index(fields=["user", "status", "created_at"]),
|
||||
models.Index(fields=["memory", "created_at"]),
|
||||
]
|
||||
|
||||
|
||||
class AIResultSignal(models.Model):
|
||||
"""
|
||||
@@ -2249,6 +2381,117 @@ class DerivedTaskEvent(models.Model):
|
||||
]
|
||||
|
||||
|
||||
class TaskArtifactLink(models.Model):
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
task = models.ForeignKey(
|
||||
DerivedTask,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="artifact_links",
|
||||
)
|
||||
kind = models.CharField(max_length=64, default="note")
|
||||
uri = models.CharField(max_length=1024, blank=True, default="")
|
||||
path = models.CharField(max_length=1024, blank=True, default="")
|
||||
summary = models.TextField(blank=True, default="")
|
||||
created_by_identifier = models.CharField(max_length=255, blank=True, default="")
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
indexes = [
|
||||
models.Index(fields=["task", "created_at"]),
|
||||
models.Index(fields=["kind", "created_at"]),
|
||||
]
|
||||
|
||||
|
||||
class KnowledgeArticle(models.Model):
|
||||
STATUS_CHOICES = (
|
||||
("draft", "Draft"),
|
||||
("published", "Published"),
|
||||
("archived", "Archived"),
|
||||
)
|
||||
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
user = models.ForeignKey(
|
||||
User,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="knowledge_articles",
|
||||
)
|
||||
related_task = models.ForeignKey(
|
||||
DerivedTask,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="knowledge_articles",
|
||||
)
|
||||
title = models.CharField(max_length=255)
|
||||
slug = models.SlugField(max_length=255)
|
||||
markdown = models.TextField(blank=True, default="")
|
||||
tags = models.JSONField(default=list, blank=True)
|
||||
status = models.CharField(max_length=16, choices=STATUS_CHOICES, default="draft")
|
||||
owner_identifier = models.CharField(max_length=255, blank=True, default="")
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
class Meta:
|
||||
constraints = [
|
||||
models.UniqueConstraint(
|
||||
fields=["user", "slug"],
|
||||
name="unique_knowledge_article_slug_per_user",
|
||||
),
|
||||
]
|
||||
indexes = [
|
||||
models.Index(fields=["user", "status", "updated_at"]),
|
||||
models.Index(fields=["related_task", "updated_at"]),
|
||||
]
|
||||
|
||||
|
||||
class KnowledgeRevision(models.Model):
|
||||
article = models.ForeignKey(
|
||||
KnowledgeArticle,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="revisions",
|
||||
)
|
||||
revision = models.PositiveIntegerField()
|
||||
author_tool = models.CharField(max_length=255, blank=True, default="")
|
||||
author_identifier = models.CharField(max_length=255, blank=True, default="")
|
||||
summary = models.TextField(blank=True, default="")
|
||||
markdown = models.TextField(blank=True, default="")
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
constraints = [
|
||||
models.UniqueConstraint(
|
||||
fields=["article", "revision"],
|
||||
name="unique_knowledge_revision_per_article",
|
||||
)
|
||||
]
|
||||
ordering = ["article", "revision"]
|
||||
|
||||
|
||||
class MCPToolAuditLog(models.Model):
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
tool_name = models.CharField(max_length=255)
|
||||
user = models.ForeignKey(
|
||||
User,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="mcp_tool_audit_logs",
|
||||
)
|
||||
request_args = models.JSONField(default=dict, blank=True)
|
||||
response_meta = models.JSONField(default=dict, blank=True)
|
||||
ok = models.BooleanField(default=True)
|
||||
error = models.TextField(blank=True, default="")
|
||||
duration_ms = models.PositiveIntegerField(default=0)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
indexes = [
|
||||
models.Index(fields=["tool_name", "created_at"]),
|
||||
models.Index(fields=["user", "created_at"]),
|
||||
models.Index(fields=["ok", "created_at"]),
|
||||
]
|
||||
|
||||
|
||||
class ExternalSyncEvent(models.Model):
|
||||
STATUS_CHOICES = (
|
||||
("pending", "Pending"),
|
||||
|
||||
Reference in New Issue
Block a user