docs: clarify Daedalus-Pallas integration auth model
All checks were successful
CVE Scan & Docker Build / security-scan (push) Successful in 51s
CVE Scan & Docker Build / build-and-push (push) Successful in 2m27s

Refine the phase-2 integration spec to reflect implementation details:

- Change `resolved_libraries` from `set[str]` to ordered `list[str]`
- Document `MCPToken.allowed_libraries` as JSONField (not M2M) since
  Library lives in Neo4j, not Django's ORM
- Clarify that `Library.workspace_id` is a content-routing attribute,
  not an authorization axis
- Describe retirement of the three-branch `_WORKSPACE_SCOPE_CLAUSE` in
  favor of a single `lib.uid IN $resolved_libraries` check
- Specify team JWT resolution via `TeamWorkspaceAssignment` DB join
- Note admin UI materializes full Library UID list explicitly
This commit is contained in:
2026-05-10 11:59:44 -04:00
parent e9f6eeb1a3
commit 16fb7ff4dc
35 changed files with 1839 additions and 2035 deletions

View File

@@ -1,4 +1,4 @@
# Generated by Django 5.2.12 on 2026-03-10 16:59
# Generated by Django 5.2.13 on 2026-05-10 15:31
import django.db.models.deletion
import llm_manager.encryption
@@ -22,7 +22,7 @@ class Migration(migrations.Migration):
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('name', models.CharField(max_length=100, unique=True)),
('api_type', models.CharField(choices=[('openai', 'OpenAI Compatible'), ('azure', 'Azure OpenAI'), ('ollama', 'Ollama'), ('anthropic', 'Anthropic'), ('llama-cpp', 'Llama.cpp'), ('vllm', 'vLLM')], max_length=20)),
('api_type', models.CharField(choices=[('openai', 'OpenAI Compatible'), ('azure', 'Azure OpenAI'), ('ollama', 'Ollama'), ('anthropic', 'Anthropic'), ('llama-cpp', 'Llama.cpp'), ('vllm', 'vLLM'), ('bedrock', 'Amazon Bedrock')], max_length=20)),
('base_url', models.URLField()),
('api_key', llm_manager.encryption.EncryptedCharField(blank=True, default='', max_length=500)),
('is_active', models.BooleanField(default=True)),
@@ -64,6 +64,7 @@ class Migration(migrations.Migration):
('is_system_embedding_model', models.BooleanField(default=False, help_text='Mark this as the system-wide embedding model. Only ONE embedding model should have this set to True.')),
('is_system_chat_model', models.BooleanField(default=False, help_text='Mark this as the system-wide chat model. Only ONE chat model should have this set to True.')),
('is_system_reranker_model', models.BooleanField(default=False, help_text='Mark this as the system-wide reranker model. Only ONE reranker model should have this set to True.')),
('is_system_vision_model', models.BooleanField(default=False, help_text='Mark this as the system-wide vision model for image analysis. Only ONE vision model should have this set to True.')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('api', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='models', to='llm_manager.llmapi')),
@@ -82,7 +83,7 @@ class Migration(migrations.Migration):
('cached_tokens', models.PositiveIntegerField(default=0)),
('total_cost', models.DecimalField(decimal_places=6, default=Decimal('0'), help_text='Total cost in USD', max_digits=12)),
('session_id', models.CharField(blank=True, db_index=True, max_length=100)),
('purpose', models.CharField(choices=[('responder', 'RAG Responder'), ('reviewer', 'RAG Reviewer'), ('embeddings', 'Document Embeddings'), ('search', 'Vector Search'), ('reranking', 'Re-ranking'), ('multimodal_embed', 'Multimodal Embedding'), ('other', 'Other')], db_index=True, default='other', max_length=50)),
('purpose', models.CharField(choices=[('responder', 'RAG Responder'), ('reviewer', 'RAG Reviewer'), ('embeddings', 'Document Embeddings'), ('search', 'Vector Search'), ('reranking', 'Re-ranking'), ('multimodal_embed', 'Multimodal Embedding'), ('vision_analysis', 'Vision Analysis'), ('other', 'Other')], db_index=True, default='other', max_length=50)),
('request_metadata', models.JSONField(blank=True, help_text='Additional context (prompt, temperature, etc.)', null=True)),
('model', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='usage_records', to='llm_manager.llmmodel')),
('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='llm_usage', to=settings.AUTH_USER_MODEL)),
@@ -107,6 +108,10 @@ class Migration(migrations.Migration):
model_name='llmmodel',
index=models.Index(fields=['is_system_reranker_model', 'model_type'], name='llm_manager_is_syst_cc73c6_idx'),
),
migrations.AddIndex(
model_name='llmmodel',
index=models.Index(fields=['is_system_vision_model', 'model_type'], name='llm_manager_is_syst_d190bb_idx'),
),
migrations.AlterUniqueTogether(
name='llmmodel',
unique_together={('api', 'name')},

View File

@@ -1,34 +0,0 @@
"""
Add 'bedrock' to LLMApi.api_type choices.
Django migrations track field changes including choices — this migration
updates the api_type field to include the new Amazon Bedrock option.
"""
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("llm_manager", "0001_initial"),
]
operations = [
migrations.AlterField(
model_name="llmapi",
name="api_type",
field=models.CharField(
choices=[
("openai", "OpenAI Compatible"),
("azure", "Azure OpenAI"),
("ollama", "Ollama"),
("anthropic", "Anthropic"),
("llama-cpp", "Llama.cpp"),
("vllm", "vLLM"),
("bedrock", "Amazon Bedrock"),
],
max_length=20,
),
),
]

View File

@@ -1,52 +0,0 @@
"""
Add is_system_vision_model to LLMModel and vision_analysis purpose to LLMUsage.
"""
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("llm_manager", "0002_add_bedrock_api_type"),
]
operations = [
migrations.AddField(
model_name="llmmodel",
name="is_system_vision_model",
field=models.BooleanField(
default=False,
help_text=(
"Mark this as the system-wide vision model for image analysis. "
"Only ONE vision model should have this set to True."
),
),
),
migrations.AddIndex(
model_name="llmmodel",
index=models.Index(
fields=["is_system_vision_model", "model_type"],
name="llm_manager__is_syst_b2f4e7_idx",
),
),
migrations.AlterField(
model_name="llmusage",
name="purpose",
field=models.CharField(
choices=[
("responder", "RAG Responder"),
("reviewer", "RAG Reviewer"),
("embeddings", "Document Embeddings"),
("search", "Vector Search"),
("reranking", "Re-ranking"),
("multimodal_embed", "Multimodal Embedding"),
("vision_analysis", "Vision Analysis"),
("other", "Other"),
],
db_index=True,
default="other",
max_length=50,
),
),
]

View File

@@ -1,18 +0,0 @@
# Generated by Django 5.2.11 on 2026-03-22 15:15
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("llm_manager", "0003_add_vision_model_and_usage"),
]
operations = [
migrations.RenameIndex(
model_name="llmmodel",
new_name="llm_manager_is_syst_d190bb_idx",
old_name="llm_manager__is_syst_b2f4e7_idx",
),
]