Increase platform abstraction cohesion

This commit is contained in:
2026-03-06 17:47:58 +00:00
parent 438e561da0
commit 8c091b1e6d
55 changed files with 6555 additions and 440 deletions

View File

@@ -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"),