"""ORM model for DeerFlow-native assistant knowledge bases.""" from __future__ import annotations from datetime import UTC, datetime from sqlalchemy import Float, Index, Integer, LargeBinary, String, UniqueConstraint from sqlalchemy.orm import Mapped, mapped_column from deerflow.persistence.base import Base from deerflow.persistence.types import BeijingDateTime, PortableJSON, PortableLongText def _now() -> datetime: return datetime.now(UTC) class AssistantKnowledgeBaseRow(Base): __tablename__ = "assistant_knowledge_base" id: Mapped[str] = mapped_column(String(36), primary_key=True) name: Mapped[str] = mapped_column(String(255), default="知识梳理") description: Mapped[str | None] = mapped_column(String(2048), nullable=True) # ``global`` is the full-library aggregation base. ``custom`` bases are # user-created assistant knowledge bases fed from WeKnora export packages. # Nullable keeps startup column reconciliation safe for existing databases. base_kind: Mapped[str | None] = mapped_column(String(24), nullable=True, index=True) status: Mapped[str] = mapped_column(String(64), default="active") created_by: Mapped[str | None] = mapped_column(String(64), nullable=True) created_at: Mapped[datetime] = mapped_column(BeijingDateTime(), default=_now) updated_at: Mapped[datetime] = mapped_column(BeijingDateTime(), default=_now, onupdate=_now) class AssistantKnowledgeSourceRow(Base): __tablename__ = "assistant_knowledge_sources" __table_args__ = (UniqueConstraint("base_id", "source_type", "source_key", name="uq_assistant_knowledge_source"),) id: Mapped[str] = mapped_column(String(36), primary_key=True) base_id: Mapped[str] = mapped_column(String(36), index=True) source_type: Mapped[str] = mapped_column(String(32), index=True) source_key: Mapped[str] = mapped_column(String(255)) knowledge_base_mapping_id: Mapped[str | None] = mapped_column(String(36), nullable=True) skill_name: Mapped[str | None] = mapped_column(String(255), nullable=True) upload_batch_id: Mapped[str | None] = mapped_column(String(36), nullable=True) source_name: Mapped[str] = mapped_column(String(255), default="") last_import_job_id: Mapped[str | None] = mapped_column(String(36), nullable=True) status: Mapped[str] = mapped_column(String(24), default="active") metadata_json: Mapped[dict | None] = mapped_column(PortableJSON(), default=dict, nullable=True) created_at: Mapped[datetime] = mapped_column(BeijingDateTime(), default=_now) updated_at: Mapped[datetime] = mapped_column(BeijingDateTime(), default=_now, onupdate=_now) class AssistantKnowledgeImportJobRow(Base): __tablename__ = "assistant_knowledge_import_jobs" id: Mapped[str] = mapped_column(String(36), primary_key=True) base_id: Mapped[str] = mapped_column(String(36), index=True) source_id: Mapped[str] = mapped_column(String(36), index=True) trigger: Mapped[str] = mapped_column(String(48), default="manual_from_weknora") status: Mapped[str] = mapped_column(String(32), default="queued", index=True) phase: Mapped[str] = mapped_column(String(32), default="exporting") counts_json: Mapped[dict | None] = mapped_column(PortableJSON(), default=dict, nullable=True) last_error_message: Mapped[str | None] = mapped_column(String(2048), nullable=True) created_by: Mapped[str | None] = mapped_column(String(64), nullable=True) created_at: Mapped[datetime] = mapped_column(BeijingDateTime(), default=_now) completed_at: Mapped[datetime | None] = mapped_column(BeijingDateTime(), nullable=True) class AssistantKnowledgeWikiPageRow(Base): __tablename__ = "assistant_knowledge_wiki_pages" metadata_json: Mapped[dict | None] = mapped_column(PortableJSON(), default=dict, nullable=True) __table_args__ = (UniqueConstraint("base_id", "slug", name="uq_assistant_wiki_slug"),) id: Mapped[str] = mapped_column(String(36), primary_key=True) base_id: Mapped[str] = mapped_column(String(36), index=True) slug: Mapped[str] = mapped_column(String(512), index=True) title: Mapped[str] = mapped_column(String(512), index=True) page_type: Mapped[str] = mapped_column(String(32), index=True) current_revision_id: Mapped[str | None] = mapped_column(String(36), nullable=True) content_markdown: Mapped[str] = mapped_column(PortableLongText(), default="") summary: Mapped[str] = mapped_column(String(2048), default="") status: Mapped[str] = mapped_column(String(24), default="active") search_text: Mapped[str] = mapped_column(PortableLongText(), default="") updated_at: Mapped[datetime] = mapped_column(BeijingDateTime(), default=_now, onupdate=_now) class AssistantKnowledgeWikiRevisionRow(Base): __tablename__ = "assistant_knowledge_wiki_revisions" __table_args__ = (UniqueConstraint("page_id", "revision_no", name="uq_assistant_wiki_revision"),) id: Mapped[str] = mapped_column(String(36), primary_key=True) page_id: Mapped[str] = mapped_column(String(36), index=True) revision_no: Mapped[int] = mapped_column(Integer) content_markdown: Mapped[str] = mapped_column(PortableLongText(), default="") summary: Mapped[str] = mapped_column(String(2048), default="") source_id: Mapped[str | None] = mapped_column(String(36), nullable=True) import_job_id: Mapped[str | None] = mapped_column(String(36), nullable=True) change_type: Mapped[str] = mapped_column(String(32), default="import") status: Mapped[str] = mapped_column(String(24), default="published") created_by: Mapped[str | None] = mapped_column(String(64), nullable=True) created_at: Mapped[datetime] = mapped_column(BeijingDateTime(), default=_now) published_at: Mapped[datetime | None] = mapped_column(BeijingDateTime(), nullable=True) class AssistantKnowledgeVectorRow(Base): __tablename__ = "assistant_knowledge_vectors" __table_args__ = ( Index("ix_assistant_knowledge_vector_base_fingerprint", "base_id", "embedding_fingerprint"), Index("ix_assistant_knowledge_vector_page", "page_id"), Index("ix_assistant_knowledge_vector_source", "source_id"), ) id: Mapped[str] = mapped_column(String(36), primary_key=True) base_id: Mapped[str] = mapped_column(String(36), index=True) page_id: Mapped[str] = mapped_column(String(36), index=True) source_id: Mapped[str] = mapped_column(String(36), index=True) import_job_id: Mapped[str] = mapped_column(String(36), index=True) source_vector_id: Mapped[str | None] = mapped_column(String(255), nullable=True) source_chunk_id: Mapped[str | None] = mapped_column(String(255), nullable=True) section_index: Mapped[int] = mapped_column(Integer, nullable=False, default=0) heading: Mapped[str | None] = mapped_column(String(1024), nullable=True) section_content: Mapped[str] = mapped_column(PortableLongText(), nullable=False, default="") content_hash: Mapped[str] = mapped_column(String(64), nullable=False, index=True) embedding_model: Mapped[str | None] = mapped_column(String(255), nullable=True) embedding_fingerprint: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True) embedding_dimensions: Mapped[int] = mapped_column(Integer, nullable=False) vector_blob: Mapped[bytes] = mapped_column(LargeBinary, nullable=False) created_at: Mapped[datetime] = mapped_column(BeijingDateTime(), default=_now) class AssistantKnowledgeEntityRow(Base): __tablename__ = "assistant_knowledge_entities" __table_args__ = (UniqueConstraint("base_id", "entity_type", "normalized_name", name="uq_assistant_entity"),) id: Mapped[str] = mapped_column(String(36), primary_key=True) base_id: Mapped[str] = mapped_column(String(36), index=True) entity_type: Mapped[str] = mapped_column(String(64), index=True) normalized_name: Mapped[str] = mapped_column(String(512)) display_name: Mapped[str] = mapped_column(String(512), index=True) aliases_json: Mapped[list | None] = mapped_column(PortableJSON(), default=list, nullable=True) attributes_json: Mapped[dict | None] = mapped_column(PortableJSON(), default=dict, nullable=True) wiki_page_id: Mapped[str | None] = mapped_column(String(36), nullable=True) status: Mapped[str] = mapped_column(String(24), default="active") class AssistantKnowledgeEntityContributionRow(Base): __tablename__ = "assistant_knowledge_entity_contributions" id: Mapped[str] = mapped_column(String(36), primary_key=True) entity_id: Mapped[str] = mapped_column(String(36), index=True) source_id: Mapped[str] = mapped_column(String(36), index=True) import_job_id: Mapped[str] = mapped_column(String(36), index=True) source_wiki_slug: Mapped[str | None] = mapped_column(String(512), nullable=True) source_chunk_id: Mapped[str | None] = mapped_column(String(255), nullable=True) source_skill_name: Mapped[str | None] = mapped_column(String(255), nullable=True) evidence_json: Mapped[list | None] = mapped_column(PortableJSON(), default=list, nullable=True) confidence: Mapped[float] = mapped_column(Float, default=1.0) class AssistantKnowledgeRelationRow(Base): __tablename__ = "assistant_knowledge_relations" __table_args__ = (UniqueConstraint("base_id", "source_entity_id", "predicate", "target_entity_id", name="uq_assistant_relation"),) id: Mapped[str] = mapped_column(String(36), primary_key=True) base_id: Mapped[str] = mapped_column(String(36), index=True) source_entity_id: Mapped[str] = mapped_column(String(36), index=True) predicate: Mapped[str] = mapped_column(String(128), index=True) target_entity_id: Mapped[str] = mapped_column(String(36), index=True) description: Mapped[str] = mapped_column(String(2048), default="") wiki_page_id: Mapped[str | None] = mapped_column(String(36), nullable=True) status: Mapped[str] = mapped_column(String(24), default="active") class AssistantKnowledgeRelationContributionRow(Base): __tablename__ = "assistant_knowledge_relation_contributions" id: Mapped[str] = mapped_column(String(36), primary_key=True) relation_id: Mapped[str] = mapped_column(String(36), index=True) source_id: Mapped[str] = mapped_column(String(36), index=True) import_job_id: Mapped[str] = mapped_column(String(36), index=True) source_wiki_slug: Mapped[str | None] = mapped_column(String(512), nullable=True) graph_edge_id: Mapped[str | None] = mapped_column(String(255), nullable=True) evidence_json: Mapped[list | None] = mapped_column(PortableJSON(), default=list, nullable=True) confidence: Mapped[float] = mapped_column(Float, default=1.0)