feat: 建立知识版本与检索追踪数据模型

This commit is contained in:
2026-07-11 18:59:29 +08:00
parent 0199dd8242
commit 73fdfed0e5
3 changed files with 586 additions and 2 deletions

View File

@@ -0,0 +1,319 @@
from __future__ import annotations
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql
revision = "0007_knowledge_agent_rebuild"
down_revision = "0006_expand_ai_request_log_text"
branch_labels = None
depends_on = None
def upgrade() -> None:
for column in [
sa.Column("source_title", sa.String(255), nullable=True),
sa.Column("knowledge_type", sa.String(30), nullable=False, server_default="general"),
sa.Column("review_mode", sa.String(30), nullable=False, server_default="manual"),
sa.Column("lifecycle_status", sa.String(30), nullable=False, server_default="active"),
sa.Column("source_status", sa.String(30), nullable=False, server_default="normal"),
sa.Column("source_error", mysql.MEDIUMTEXT(), nullable=True),
sa.Column("manifest_confirmed", sa.Integer(), nullable=False, server_default="0"),
sa.Column("current_version_id", sa.BigInteger(), nullable=True),
sa.Column("pending_version_id", sa.BigInteger(), nullable=True),
sa.Column("last_synced_at", sa.DateTime(), nullable=True),
sa.Column("last_published_at", sa.DateTime(), nullable=True),
sa.Column("migration_status", sa.String(30), nullable=False, server_default="pending"),
]:
op.add_column("sys_knowledge", column)
op.create_table(
"sys_knowledge_source_snapshot",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("knowledge_id", sa.BigInteger(), nullable=False),
sa.Column("sync_job_id", sa.BigInteger(), nullable=True),
sa.Column("source_title", sa.String(255), nullable=False),
sa.Column("source_content", mysql.LONGTEXT(), nullable=False),
sa.Column("content_hash", sa.String(64), nullable=False),
sa.Column("source_identifier", sa.String(255), nullable=False),
sa.Column("fetched_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.Column("created_by", sa.BigInteger(), nullable=True),
sa.ForeignKeyConstraint(["knowledge_id"], ["sys_knowledge.id"]),
sa.PrimaryKeyConstraint("id"),
)
_indexes("sys_knowledge_source_snapshot", "knowledge_id", "sync_job_id", "content_hash")
op.create_table(
"sys_knowledge_version",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("knowledge_id", sa.BigInteger(), nullable=False),
sa.Column("snapshot_id", sa.BigInteger(), nullable=False),
sa.Column("version_no", sa.Integer(), nullable=False),
sa.Column("status", sa.String(30), nullable=False),
sa.Column("quality_status", sa.String(30), nullable=False, server_default="pending"),
sa.Column("change_summary", mysql.MEDIUMTEXT(), nullable=True),
sa.Column("quality_report", mysql.MEDIUMTEXT(), nullable=True),
sa.Column("processing_rule_version", sa.String(50), nullable=False),
sa.Column("generation_model", sa.String(100), nullable=True),
sa.Column("created_by", sa.BigInteger(), nullable=True),
sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.Column("published_by", sa.BigInteger(), nullable=True),
sa.Column("published_at", sa.DateTime(), nullable=True),
sa.ForeignKeyConstraint(["knowledge_id"], ["sys_knowledge.id"]),
sa.ForeignKeyConstraint(["snapshot_id"], ["sys_knowledge_source_snapshot.id"]),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("knowledge_id", "version_no", name="uq_kb_version_no"),
)
_indexes("sys_knowledge_version", "knowledge_id", "status")
op.create_table(
"sys_knowledge_manifest",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("knowledge_id", sa.BigInteger(), nullable=False),
sa.Column("version_id", sa.BigInteger(), nullable=False),
sa.Column("purpose", mysql.MEDIUMTEXT(), nullable=False),
sa.Column("applicable_questions", mysql.MEDIUMTEXT(), nullable=False),
sa.Column("inapplicable_questions", mysql.MEDIUMTEXT(), nullable=False),
sa.Column("core_topics", mysql.MEDIUMTEXT(), nullable=False),
sa.Column("entities", mysql.MEDIUMTEXT(), nullable=True),
sa.Column("boundaries", mysql.MEDIUMTEXT(), nullable=True),
sa.Column("content_hash", sa.String(64), nullable=False),
sa.Column("change_level", sa.String(20), nullable=False, server_default="major"),
sa.Column("confirmed", sa.Integer(), nullable=False, server_default="0"),
sa.Column("confirmed_by", sa.BigInteger(), nullable=True),
sa.Column("confirmed_at", sa.DateTime(), nullable=True),
sa.ForeignKeyConstraint(["knowledge_id"], ["sys_knowledge.id"]),
sa.ForeignKeyConstraint(["version_id"], ["sys_knowledge_version.id"]),
sa.PrimaryKeyConstraint("id"),
)
_indexes("sys_knowledge_manifest", "knowledge_id", "version_id")
op.create_table(
"sys_knowledge_section",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("knowledge_id", sa.BigInteger(), nullable=False),
sa.Column("version_id", sa.BigInteger(), nullable=False),
sa.Column("section_key", sa.String(64), nullable=False),
sa.Column("title", sa.String(255), nullable=False),
sa.Column("content", mysql.LONGTEXT(), nullable=False),
sa.Column("source_start", sa.Integer(), nullable=False),
sa.Column("source_end", sa.Integer(), nullable=False),
sa.Column("sort_order", sa.Integer(), nullable=False),
sa.Column("content_hash", sa.String(64), nullable=False),
sa.ForeignKeyConstraint(["knowledge_id"], ["sys_knowledge.id"]),
sa.ForeignKeyConstraint(["version_id"], ["sys_knowledge_version.id"]),
sa.PrimaryKeyConstraint("id"),
)
_indexes("sys_knowledge_section", "knowledge_id", "version_id")
op.create_table(
"sys_knowledge_chunk",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("knowledge_id", sa.BigInteger(), nullable=False),
sa.Column("version_id", sa.BigInteger(), nullable=False),
sa.Column("section_id", sa.BigInteger(), nullable=False),
sa.Column("title", sa.String(255), nullable=False),
sa.Column("content", mysql.MEDIUMTEXT(), nullable=False),
sa.Column("normalized_text", mysql.MEDIUMTEXT(), nullable=False),
sa.Column("keywords", mysql.MEDIUMTEXT(), nullable=True),
sa.Column("synonyms", mysql.MEDIUMTEXT(), nullable=True),
sa.Column("source_start", sa.Integer(), nullable=False),
sa.Column("source_end", sa.Integer(), nullable=False),
sa.Column("sort_order", sa.Integer(), nullable=False),
sa.Column("content_hash", sa.String(64), nullable=False),
sa.ForeignKeyConstraint(["knowledge_id"], ["sys_knowledge.id"]),
sa.ForeignKeyConstraint(["version_id"], ["sys_knowledge_version.id"]),
sa.ForeignKeyConstraint(["section_id"], ["sys_knowledge_section.id"]),
sa.PrimaryKeyConstraint("id"),
)
_indexes("sys_knowledge_chunk", "knowledge_id", "version_id", "section_id")
op.create_table(
"sys_knowledge_card",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("knowledge_id", sa.BigInteger(), nullable=False),
sa.Column("version_id", sa.BigInteger(), nullable=False),
sa.Column("section_id", sa.BigInteger(), nullable=False),
sa.Column("title", sa.String(255), nullable=False),
sa.Column("summary", mysql.MEDIUMTEXT(), nullable=False),
sa.Column("core_conclusion", mysql.MEDIUMTEXT(), nullable=False),
sa.Column("applicable_questions", mysql.MEDIUMTEXT(), nullable=False),
sa.Column("inapplicable_questions", mysql.MEDIUMTEXT(), nullable=False),
sa.Column("keywords", mysql.MEDIUMTEXT(), nullable=False),
sa.Column("synonyms", mysql.MEDIUMTEXT(), nullable=True),
sa.Column("entities", mysql.MEDIUMTEXT(), nullable=True),
sa.Column("risk_level", sa.String(20), nullable=False, server_default="normal"),
sa.Column("source_range", sa.String(100), nullable=False),
sa.Column("content_hash", sa.String(64), nullable=False),
sa.Column("generation_model", sa.String(100), nullable=True),
sa.Column("generation_rule_version", sa.String(50), nullable=False),
sa.Column("review_status", sa.String(20), nullable=False, server_default="pending"),
sa.ForeignKeyConstraint(["knowledge_id"], ["sys_knowledge.id"]),
sa.ForeignKeyConstraint(["version_id"], ["sys_knowledge_version.id"]),
sa.ForeignKeyConstraint(["section_id"], ["sys_knowledge_section.id"]),
sa.PrimaryKeyConstraint("id"),
)
_indexes("sys_knowledge_card", "knowledge_id", "version_id", "section_id")
_create_job_and_log_tables()
def _create_job_and_log_tables() -> None:
op.create_table(
"sys_knowledge_sync_job",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("knowledge_id", sa.BigInteger(), nullable=False),
sa.Column("mode", sa.String(30), nullable=False),
sa.Column("status", sa.String(30), nullable=False),
sa.Column("stage", sa.String(50), nullable=False),
sa.Column("progress", sa.Integer(), nullable=False, server_default="0"),
sa.Column("source_error", mysql.MEDIUMTEXT(), nullable=True),
sa.Column("result_summary", mysql.MEDIUMTEXT(), nullable=True),
sa.Column("requested_by", sa.BigInteger(), nullable=False),
sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.Column("started_at", sa.DateTime(), nullable=True),
sa.Column("finished_at", sa.DateTime(), nullable=True),
sa.ForeignKeyConstraint(["knowledge_id"], ["sys_knowledge.id"]),
sa.PrimaryKeyConstraint("id"),
)
_indexes("sys_knowledge_sync_job", "knowledge_id", "status")
op.create_table(
"sys_knowledge_review_record",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("knowledge_id", sa.BigInteger(), nullable=False),
sa.Column("version_id", sa.BigInteger(), nullable=False),
sa.Column("card_id", sa.BigInteger(), nullable=True),
sa.Column("action", sa.String(30), nullable=False),
sa.Column("reason", mysql.MEDIUMTEXT(), nullable=True),
sa.Column("reviewed_by", sa.BigInteger(), nullable=False),
sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.ForeignKeyConstraint(["knowledge_id"], ["sys_knowledge.id"]),
sa.ForeignKeyConstraint(["version_id"], ["sys_knowledge_version.id"]),
sa.ForeignKeyConstraint(["card_id"], ["sys_knowledge_card.id"]),
sa.PrimaryKeyConstraint("id"),
)
_indexes("sys_knowledge_review_record", "knowledge_id", "version_id")
op.create_table(
"sys_knowledge_publish_log",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("knowledge_id", sa.BigInteger(), nullable=False),
sa.Column("from_version_id", sa.BigInteger(), nullable=True),
sa.Column("to_version_id", sa.BigInteger(), nullable=True),
sa.Column("action", sa.String(30), nullable=False),
sa.Column("keep_open", sa.Integer(), nullable=False, server_default="0"),
sa.Column("detail_json", mysql.MEDIUMTEXT(), nullable=True),
sa.Column("operated_by", sa.BigInteger(), nullable=False),
sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.ForeignKeyConstraint(["knowledge_id"], ["sys_knowledge.id"]),
sa.PrimaryKeyConstraint("id"),
)
_indexes("sys_knowledge_publish_log", "knowledge_id")
op.create_table(
"sys_knowledge_retrieval_log",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("session_id", sa.BigInteger(), nullable=True),
sa.Column("message_id", sa.BigInteger(), nullable=True),
sa.Column("user_id", sa.BigInteger(), nullable=True),
sa.Column("question", mysql.MEDIUMTEXT(), nullable=False),
sa.Column("catalog_snapshot", mysql.LONGTEXT(), nullable=False),
sa.Column("catalog_hash", sa.String(64), nullable=False),
sa.Column("safety_rule_version", sa.String(50), nullable=False),
sa.Column("knowledge_called", sa.Integer(), nullable=False, server_default="0"),
sa.Column("selected_knowledge_ids", sa.String(500), nullable=True),
sa.Column("query_terms", mysql.MEDIUMTEXT(), nullable=True),
sa.Column("tool_trace", mysql.LONGTEXT(), nullable=True),
sa.Column("final_section_ids", sa.String(500), nullable=True),
sa.Column("discarded_conflicts", mysql.MEDIUMTEXT(), nullable=True),
sa.Column("final_answer", mysql.LONGTEXT(), nullable=True),
sa.Column("status", sa.String(20), nullable=False),
sa.Column("tool_cost_ms", sa.Integer(), nullable=True),
sa.Column("total_cost_ms", sa.Integer(), nullable=True),
sa.Column("error_message", mysql.MEDIUMTEXT(), nullable=True),
sa.Column("attention_created", sa.Integer(), nullable=False, server_default="0"),
sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
_indexes("sys_knowledge_retrieval_log", "session_id", "message_id", "user_id")
op.create_table(
"sys_knowledge_retrieval_candidate",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("retrieval_log_id", sa.BigInteger(), nullable=False),
sa.Column("knowledge_id", sa.BigInteger(), nullable=False),
sa.Column("version_id", sa.BigInteger(), nullable=False),
sa.Column("chunk_id", sa.BigInteger(), nullable=False),
sa.Column("section_id", sa.BigInteger(), nullable=False),
sa.Column("lexical_score", sa.String(30), nullable=False),
sa.Column("rerank_score", sa.String(30), nullable=True),
sa.Column("selected", sa.Integer(), nullable=False, server_default="0"),
sa.Column("discard_reason", sa.String(255), nullable=True),
sa.ForeignKeyConstraint(["retrieval_log_id"], ["sys_knowledge_retrieval_log.id"]),
sa.PrimaryKeyConstraint("id"),
)
_indexes("sys_knowledge_retrieval_candidate", "retrieval_log_id", "knowledge_id", "version_id")
op.create_table(
"sys_human_attention_record",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("session_id", sa.BigInteger(), nullable=False),
sa.Column("message_id", sa.BigInteger(), nullable=False),
sa.Column("user_id", sa.BigInteger(), nullable=False),
sa.Column("trigger_message", mysql.MEDIUMTEXT(), nullable=False),
sa.Column("problem_summary", mysql.MEDIUMTEXT(), nullable=False),
sa.Column("trigger_reason", mysql.MEDIUMTEXT(), nullable=False),
sa.Column("priority", sa.String(20), nullable=False),
sa.Column("status", sa.String(20), nullable=False, server_default="pending"),
sa.Column("handler_id", sa.BigInteger(), nullable=True),
sa.Column("handler_note", mysql.MEDIUMTEXT(), nullable=True),
sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.Column("updated_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
_indexes("sys_human_attention_record", "session_id", "message_id", "user_id", "priority", "status")
op.create_table(
"sys_human_attention_history",
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
sa.Column("attention_id", sa.BigInteger(), nullable=False),
sa.Column("from_status", sa.String(20), nullable=True),
sa.Column("to_status", sa.String(20), nullable=False),
sa.Column("note", mysql.MEDIUMTEXT(), nullable=True),
sa.Column("operated_by", sa.BigInteger(), nullable=False),
sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
sa.ForeignKeyConstraint(["attention_id"], ["sys_human_attention_record.id"]),
sa.PrimaryKeyConstraint("id"),
)
_indexes("sys_human_attention_history", "attention_id")
def _indexes(table: str, *columns: str) -> None:
for column in columns:
op.create_index(f"ix_{table}_{column}", table, [column])
def downgrade() -> None:
for table in [
"sys_human_attention_history",
"sys_human_attention_record",
"sys_knowledge_retrieval_candidate",
"sys_knowledge_retrieval_log",
"sys_knowledge_publish_log",
"sys_knowledge_review_record",
"sys_knowledge_sync_job",
"sys_knowledge_card",
"sys_knowledge_chunk",
"sys_knowledge_section",
"sys_knowledge_manifest",
"sys_knowledge_version",
"sys_knowledge_source_snapshot",
]:
op.drop_table(table)
for column in [
"migration_status", "last_published_at", "last_synced_at", "pending_version_id",
"current_version_id", "manifest_confirmed", "source_error", "source_status",
"lifecycle_status", "review_mode", "knowledge_type", "source_title",
]:
op.drop_column("sys_knowledge", column)

View File

@@ -2,7 +2,23 @@ from app.models.admin import Admin, Role
from app.models.ai_config import ModelConfig, Prompt, SystemConfig from app.models.ai_config import ModelConfig, Prompt, SystemConfig
from app.models.base import Base from app.models.base import Base
from app.models.chat import ChatMessage, ChatSession from app.models.chat import ChatMessage, ChatSession
from app.models.knowledge import Knowledge, UserKnowledgePermission from app.models.knowledge import (
HumanAttentionHistory,
HumanAttentionRecord,
Knowledge,
KnowledgeCard,
KnowledgeChunk,
KnowledgeManifest,
KnowledgePublishLog,
KnowledgeRetrievalCandidate,
KnowledgeRetrievalLog,
KnowledgeReviewRecord,
KnowledgeSection,
KnowledgeSourceSnapshot,
KnowledgeSyncJob,
KnowledgeVersion,
UserKnowledgePermission,
)
from app.models.logs import AiRequestLog, OperationLog from app.models.logs import AiRequestLog, OperationLog
from app.models.user import User from app.models.user import User
@@ -13,6 +29,19 @@ __all__ = [
"ChatMessage", "ChatMessage",
"ChatSession", "ChatSession",
"Knowledge", "Knowledge",
"KnowledgeCard",
"KnowledgeChunk",
"KnowledgeManifest",
"KnowledgePublishLog",
"KnowledgeRetrievalCandidate",
"KnowledgeRetrievalLog",
"KnowledgeReviewRecord",
"KnowledgeSection",
"KnowledgeSourceSnapshot",
"KnowledgeSyncJob",
"KnowledgeVersion",
"HumanAttentionHistory",
"HumanAttentionRecord",
"ModelConfig", "ModelConfig",
"OperationLog", "OperationLog",
"Prompt", "Prompt",

View File

@@ -2,7 +2,7 @@ from __future__ import annotations
from datetime import datetime from datetime import datetime
from sqlalchemy import BigInteger, DateTime, ForeignKey, String from sqlalchemy import BigInteger, DateTime, ForeignKey, Integer, String, Text, UniqueConstraint, func
from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.models.base import Base, TimestampMixin from app.models.base import Base, TimestampMixin
@@ -17,6 +17,18 @@ class Knowledge(Base, TimestampMixin):
feishu_node_id: Mapped[str] = mapped_column(String(100), nullable=False) feishu_node_id: Mapped[str] = mapped_column(String(100), nullable=False)
status: Mapped[int] = mapped_column(default=1, nullable=False) status: Mapped[int] = mapped_column(default=1, nullable=False)
remark: Mapped[str | None] = mapped_column(String(255), nullable=True) remark: Mapped[str | None] = mapped_column(String(255), nullable=True)
source_title: Mapped[str | None] = mapped_column(String(255), nullable=True)
knowledge_type: Mapped[str] = mapped_column(String(30), default="general", nullable=False)
review_mode: Mapped[str] = mapped_column(String(30), default="manual", nullable=False)
lifecycle_status: Mapped[str] = mapped_column(String(30), default="active", nullable=False)
source_status: Mapped[str] = mapped_column(String(30), default="normal", nullable=False)
source_error: Mapped[str | None] = mapped_column(Text, nullable=True)
manifest_confirmed: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
current_version_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
pending_version_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
last_synced_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
last_published_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
migration_status: Mapped[str] = mapped_column(String(30), default="pending", nullable=False)
user_permissions: Mapped[list["UserKnowledgePermission"]] = relationship( user_permissions: Mapped[list["UserKnowledgePermission"]] = relationship(
"UserKnowledgePermission", back_populates="knowledge" "UserKnowledgePermission", back_populates="knowledge"
@@ -35,3 +47,227 @@ class UserKnowledgePermission(Base, TimestampMixin):
user: Mapped["User"] = relationship("User", back_populates="knowledge_permissions") user: Mapped["User"] = relationship("User", back_populates="knowledge_permissions")
knowledge: Mapped[Knowledge] = relationship("Knowledge", back_populates="user_permissions") knowledge: Mapped[Knowledge] = relationship("Knowledge", back_populates="user_permissions")
class KnowledgeSourceSnapshot(Base):
__tablename__ = "sys_knowledge_source_snapshot"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
knowledge_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge.id"), index=True, nullable=False)
sync_job_id: Mapped[int | None] = mapped_column(BigInteger, index=True, nullable=True)
source_title: Mapped[str] = mapped_column(String(255), nullable=False)
source_content: Mapped[str] = mapped_column(Text, nullable=False)
content_hash: Mapped[str] = mapped_column(String(64), index=True, nullable=False)
source_identifier: Mapped[str] = mapped_column(String(255), nullable=False)
fetched_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False)
created_by: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
class KnowledgeVersion(Base):
__tablename__ = "sys_knowledge_version"
__table_args__ = (UniqueConstraint("knowledge_id", "version_no", name="uq_kb_version_no"),)
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
knowledge_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge.id"), index=True, nullable=False)
snapshot_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge_source_snapshot.id"), nullable=False)
version_no: Mapped[int] = mapped_column(Integer, nullable=False)
status: Mapped[str] = mapped_column(String(30), index=True, nullable=False)
quality_status: Mapped[str] = mapped_column(String(30), default="pending", nullable=False)
change_summary: Mapped[str | None] = mapped_column(Text, nullable=True)
quality_report: Mapped[str | None] = mapped_column(Text, nullable=True)
processing_rule_version: Mapped[str] = mapped_column(String(50), nullable=False)
generation_model: Mapped[str | None] = mapped_column(String(100), nullable=True)
created_by: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False)
published_by: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
published_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
class KnowledgeManifest(Base):
__tablename__ = "sys_knowledge_manifest"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
knowledge_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge.id"), index=True, nullable=False)
version_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge_version.id"), index=True, nullable=False)
purpose: Mapped[str] = mapped_column(Text, nullable=False)
applicable_questions: Mapped[str] = mapped_column(Text, nullable=False)
inapplicable_questions: Mapped[str] = mapped_column(Text, nullable=False)
core_topics: Mapped[str] = mapped_column(Text, nullable=False)
entities: Mapped[str | None] = mapped_column(Text, nullable=True)
boundaries: Mapped[str | None] = mapped_column(Text, nullable=True)
content_hash: Mapped[str] = mapped_column(String(64), nullable=False)
change_level: Mapped[str] = mapped_column(String(20), default="major", nullable=False)
confirmed: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
confirmed_by: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
confirmed_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
class KnowledgeSection(Base):
__tablename__ = "sys_knowledge_section"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
knowledge_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge.id"), index=True, nullable=False)
version_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge_version.id"), index=True, nullable=False)
section_key: Mapped[str] = mapped_column(String(64), nullable=False)
title: Mapped[str] = mapped_column(String(255), nullable=False)
content: Mapped[str] = mapped_column(Text, nullable=False)
source_start: Mapped[int] = mapped_column(Integer, nullable=False)
source_end: Mapped[int] = mapped_column(Integer, nullable=False)
sort_order: Mapped[int] = mapped_column(Integer, nullable=False)
content_hash: Mapped[str] = mapped_column(String(64), nullable=False)
class KnowledgeChunk(Base):
__tablename__ = "sys_knowledge_chunk"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
knowledge_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge.id"), index=True, nullable=False)
version_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge_version.id"), index=True, nullable=False)
section_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge_section.id"), index=True, nullable=False)
title: Mapped[str] = mapped_column(String(255), nullable=False)
content: Mapped[str] = mapped_column(Text, nullable=False)
normalized_text: Mapped[str] = mapped_column(Text, nullable=False)
keywords: Mapped[str | None] = mapped_column(Text, nullable=True)
synonyms: Mapped[str | None] = mapped_column(Text, nullable=True)
source_start: Mapped[int] = mapped_column(Integer, nullable=False)
source_end: Mapped[int] = mapped_column(Integer, nullable=False)
sort_order: Mapped[int] = mapped_column(Integer, nullable=False)
content_hash: Mapped[str] = mapped_column(String(64), nullable=False)
class KnowledgeCard(Base):
__tablename__ = "sys_knowledge_card"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
knowledge_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge.id"), index=True, nullable=False)
version_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge_version.id"), index=True, nullable=False)
section_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge_section.id"), index=True, nullable=False)
title: Mapped[str] = mapped_column(String(255), nullable=False)
summary: Mapped[str] = mapped_column(Text, nullable=False)
core_conclusion: Mapped[str] = mapped_column(Text, nullable=False)
applicable_questions: Mapped[str] = mapped_column(Text, nullable=False)
inapplicable_questions: Mapped[str] = mapped_column(Text, nullable=False)
keywords: Mapped[str] = mapped_column(Text, nullable=False)
synonyms: Mapped[str | None] = mapped_column(Text, nullable=True)
entities: Mapped[str | None] = mapped_column(Text, nullable=True)
risk_level: Mapped[str] = mapped_column(String(20), default="normal", nullable=False)
source_range: Mapped[str] = mapped_column(String(100), nullable=False)
content_hash: Mapped[str] = mapped_column(String(64), nullable=False)
generation_model: Mapped[str | None] = mapped_column(String(100), nullable=True)
generation_rule_version: Mapped[str] = mapped_column(String(50), nullable=False)
review_status: Mapped[str] = mapped_column(String(20), default="pending", nullable=False)
class KnowledgeSyncJob(Base):
__tablename__ = "sys_knowledge_sync_job"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
knowledge_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge.id"), index=True, nullable=False)
mode: Mapped[str] = mapped_column(String(30), nullable=False)
status: Mapped[str] = mapped_column(String(30), index=True, nullable=False)
stage: Mapped[str] = mapped_column(String(50), nullable=False)
progress: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
source_error: Mapped[str | None] = mapped_column(Text, nullable=True)
result_summary: Mapped[str | None] = mapped_column(Text, nullable=True)
requested_by: Mapped[int] = mapped_column(BigInteger, nullable=False)
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False)
started_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
finished_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
class KnowledgeReviewRecord(Base):
__tablename__ = "sys_knowledge_review_record"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
knowledge_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge.id"), index=True, nullable=False)
version_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge_version.id"), index=True, nullable=False)
card_id: Mapped[int | None] = mapped_column(ForeignKey("sys_knowledge_card.id"), nullable=True)
action: Mapped[str] = mapped_column(String(30), nullable=False)
reason: Mapped[str | None] = mapped_column(Text, nullable=True)
reviewed_by: Mapped[int] = mapped_column(BigInteger, nullable=False)
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False)
class KnowledgePublishLog(Base):
__tablename__ = "sys_knowledge_publish_log"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
knowledge_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge.id"), index=True, nullable=False)
from_version_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
to_version_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
action: Mapped[str] = mapped_column(String(30), nullable=False)
keep_open: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
detail_json: Mapped[str | None] = mapped_column(Text, nullable=True)
operated_by: Mapped[int] = mapped_column(BigInteger, nullable=False)
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False)
class KnowledgeRetrievalLog(Base):
__tablename__ = "sys_knowledge_retrieval_log"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
session_id: Mapped[int | None] = mapped_column(BigInteger, index=True, nullable=True)
message_id: Mapped[int | None] = mapped_column(BigInteger, index=True, nullable=True)
user_id: Mapped[int | None] = mapped_column(BigInteger, index=True, nullable=True)
question: Mapped[str] = mapped_column(Text, nullable=False)
catalog_snapshot: Mapped[str] = mapped_column(Text, nullable=False)
catalog_hash: Mapped[str] = mapped_column(String(64), nullable=False)
safety_rule_version: Mapped[str] = mapped_column(String(50), nullable=False)
knowledge_called: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
selected_knowledge_ids: Mapped[str | None] = mapped_column(String(500), nullable=True)
query_terms: Mapped[str | None] = mapped_column(Text, nullable=True)
tool_trace: Mapped[str | None] = mapped_column(Text, nullable=True)
final_section_ids: Mapped[str | None] = mapped_column(String(500), nullable=True)
discarded_conflicts: Mapped[str | None] = mapped_column(Text, nullable=True)
final_answer: Mapped[str | None] = mapped_column(Text, nullable=True)
status: Mapped[str] = mapped_column(String(20), nullable=False)
tool_cost_ms: Mapped[int | None] = mapped_column(Integer, nullable=True)
total_cost_ms: Mapped[int | None] = mapped_column(Integer, nullable=True)
error_message: Mapped[str | None] = mapped_column(Text, nullable=True)
attention_created: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False)
class KnowledgeRetrievalCandidate(Base):
__tablename__ = "sys_knowledge_retrieval_candidate"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
retrieval_log_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge_retrieval_log.id"), index=True, nullable=False)
knowledge_id: Mapped[int] = mapped_column(BigInteger, index=True, nullable=False)
version_id: Mapped[int] = mapped_column(BigInteger, index=True, nullable=False)
chunk_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
section_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
lexical_score: Mapped[str] = mapped_column(String(30), nullable=False)
rerank_score: Mapped[str | None] = mapped_column(String(30), nullable=True)
selected: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
discard_reason: Mapped[str | None] = mapped_column(String(255), nullable=True)
class HumanAttentionRecord(Base):
__tablename__ = "sys_human_attention_record"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
session_id: Mapped[int] = mapped_column(BigInteger, index=True, nullable=False)
message_id: Mapped[int] = mapped_column(BigInteger, index=True, nullable=False)
user_id: Mapped[int] = mapped_column(BigInteger, index=True, nullable=False)
trigger_message: Mapped[str] = mapped_column(Text, nullable=False)
problem_summary: Mapped[str] = mapped_column(Text, nullable=False)
trigger_reason: Mapped[str] = mapped_column(Text, nullable=False)
priority: Mapped[str] = mapped_column(String(20), index=True, nullable=False)
status: Mapped[str] = mapped_column(String(20), index=True, default="pending", nullable=False)
handler_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
handler_note: Mapped[str | None] = mapped_column(Text, nullable=True)
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False)
updated_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), onupdate=func.now(), nullable=False)
class HumanAttentionHistory(Base):
__tablename__ = "sys_human_attention_history"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
attention_id: Mapped[int] = mapped_column(ForeignKey("sys_human_attention_record.id"), index=True, nullable=False)
from_status: Mapped[str | None] = mapped_column(String(20), nullable=True)
to_status: Mapped[str] = mapped_column(String(20), nullable=False)
note: Mapped[str | None] = mapped_column(Text, nullable=True)
operated_by: Mapped[int] = mapped_column(BigInteger, nullable=False)
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False)