mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-07-21 20:06:06 +00:00
feat(tenancy): harden shared cloud runtime boundaries
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
import hashlib
|
||||
import uuid
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
from .base import Base
|
||||
@@ -15,6 +18,17 @@ class PluginSetting(Base):
|
||||
)
|
||||
plugin_author = sqlalchemy.Column(sqlalchemy.String(255), primary_key=True)
|
||||
plugin_name = sqlalchemy.Column(sqlalchemy.String(255), primary_key=True)
|
||||
installation_uuid = sqlalchemy.Column(
|
||||
sqlalchemy.String(36),
|
||||
nullable=False,
|
||||
default=lambda: str(uuid.uuid4()),
|
||||
)
|
||||
artifact_digest = sqlalchemy.Column(
|
||||
sqlalchemy.String(64),
|
||||
nullable=False,
|
||||
default=lambda: hashlib.sha256(f'pending:{uuid.uuid4()}'.encode()).hexdigest(),
|
||||
)
|
||||
runtime_revision = sqlalchemy.Column(sqlalchemy.Integer, nullable=False, default=1)
|
||||
enabled = sqlalchemy.Column(sqlalchemy.Boolean, nullable=False, default=True)
|
||||
priority = sqlalchemy.Column(sqlalchemy.Integer, nullable=False, default=0)
|
||||
config = sqlalchemy.Column(sqlalchemy.JSON, nullable=False, default=dict)
|
||||
@@ -28,4 +42,15 @@ class PluginSetting(Base):
|
||||
onupdate=sqlalchemy.func.now(),
|
||||
)
|
||||
|
||||
__table_args__ = (sqlalchemy.Index('ix_plugin_settings_workspace_enabled', 'workspace_uuid', 'enabled'),)
|
||||
__table_args__ = (
|
||||
sqlalchemy.UniqueConstraint('installation_uuid', name='uq_plugin_settings_installation_uuid'),
|
||||
sqlalchemy.CheckConstraint('runtime_revision >= 1', name='ck_plugin_settings_runtime_revision_positive'),
|
||||
sqlalchemy.CheckConstraint('length(artifact_digest) = 64', name='ck_plugin_settings_artifact_digest_length'),
|
||||
sqlalchemy.Index('ix_plugin_settings_workspace_enabled', 'workspace_uuid', 'enabled'),
|
||||
sqlalchemy.Index(
|
||||
'ix_plugin_settings_workspace_installation',
|
||||
'workspace_uuid',
|
||||
'installation_uuid',
|
||||
unique=True,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -29,6 +29,9 @@ class KnowledgeBase(Base):
|
||||
)
|
||||
creation_settings = sqlalchemy.Column(sqlalchemy.JSON, nullable=True, default=None)
|
||||
retrieval_settings = sqlalchemy.Column(sqlalchemy.JSON, nullable=True, default=None)
|
||||
# Server-selected pgvector dimension. ``None`` means no embedding has been
|
||||
# written yet; the first pgvector upsert binds it atomically.
|
||||
embedding_dimension = sqlalchemy.Column(sqlalchemy.Integer, nullable=True)
|
||||
|
||||
# Field sets for different operations
|
||||
MUTABLE_FIELDS = {'name', 'description', 'retrieval_settings'}
|
||||
@@ -40,6 +43,7 @@ class KnowledgeBase(Base):
|
||||
ALL_DB_FIELDS = CREATE_FIELDS | {
|
||||
'workspace_uuid',
|
||||
'legacy_vector_collection',
|
||||
'embedding_dimension',
|
||||
'emoji',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
@@ -57,6 +61,10 @@ class KnowledgeBase(Base):
|
||||
sqlite_where=sqlalchemy.text('collection_id IS NOT NULL'),
|
||||
postgresql_where=sqlalchemy.text('collection_id IS NOT NULL'),
|
||||
),
|
||||
sqlalchemy.CheckConstraint(
|
||||
'embedding_dimension IS NULL OR embedding_dimension > 0',
|
||||
name='ck_knowledge_bases_embedding_dimension_positive',
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user