feat: add AI research chatbot with confirmed business tools

This commit is contained in:
yuxuanhui
2026-09-07 23:02:55 +08:00
parent 3cd280d068
commit 79ab20b4ea
44 changed files with 4647 additions and 197 deletions
+79 -1
View File
@@ -2,7 +2,18 @@
from datetime import datetime, timezone
from sqlalchemy import JSON, Boolean, DateTime, Float, ForeignKey, Index, Integer, String, Text
from sqlalchemy import (
JSON,
Boolean,
DateTime,
Float,
ForeignKey,
Index,
Integer,
String,
Text,
UniqueConstraint,
)
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
@@ -83,6 +94,7 @@ class Research(Base):
favorite: Mapped[bool] = mapped_column(Boolean, default=False)
state: Mapped[str] = mapped_column(String(30), default="inbox", index=True)
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
version: Mapped[int] = mapped_column(Integer, default=1, server_default="1")
class Pnl(Base):
@@ -121,3 +133,69 @@ class JobItem(Base):
job_id: Mapped[str] = mapped_column(ForeignKey("sync_jobs.id"), primary_key=True)
alpha_id: Mapped[str] = mapped_column(String(100), primary_key=True)
error: Mapped[str | None] = mapped_column(Text)
class AISettings(Base):
__tablename__ = "ai_settings"
id: Mapped[int] = mapped_column(primary_key=True, default=1)
base_url: Mapped[str] = mapped_column(Text, default="")
api_key_encrypted: Mapped[str | None] = mapped_column(Text)
model: Mapped[str] = mapped_column(String(200), default="")
protocol: Mapped[str] = mapped_column(String(30), default="chat_completions")
enabled: Mapped[bool] = mapped_column(Boolean, default=False)
revision: Mapped[int] = mapped_column(Integer, default=1)
tested_revision: Mapped[int | None] = mapped_column(Integer)
test_results: Mapped[dict] = mapped_column(JSON, default=dict)
class AIConversation(Base):
__tablename__ = "ai_conversations"
id: Mapped[str] = mapped_column(String(36), primary_key=True)
admin_id: Mapped[int] = mapped_column(ForeignKey("admins.id"), default=1)
title: Mapped[str] = mapped_column(String(100), default="新会话")
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
class AIRun(Base):
__tablename__ = "ai_runs"
id: Mapped[str] = mapped_column(String(36), primary_key=True)
conversation_id: Mapped[str] = mapped_column(ForeignKey("ai_conversations.id"), index=True)
request_id: Mapped[str] = mapped_column(String(100))
status: Mapped[str] = mapped_column(String(30), default="running")
context: Mapped[dict] = mapped_column(JSON, default=dict)
model: Mapped[str] = mapped_column(String(200))
settings_revision: Mapped[int] = mapped_column(Integer)
model_messages: Mapped[list] = mapped_column(JSON, default=list)
history_start: Mapped[int] = mapped_column(Integer, default=0)
usage: Mapped[dict] = mapped_column(JSON, default=dict)
elapsed_ms: Mapped[int] = mapped_column(Integer, default=0)
error: Mapped[str | None] = mapped_column(Text)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
__table_args__ = (UniqueConstraint("conversation_id", "request_id"),)
class AIMessage(Base):
__tablename__ = "ai_messages"
id: Mapped[str] = mapped_column(String(36), primary_key=True)
conversation_id: Mapped[str] = mapped_column(ForeignKey("ai_conversations.id"), index=True)
run_id: Mapped[str] = mapped_column(ForeignKey("ai_runs.id"), index=True)
role: Mapped[str] = mapped_column(String(20))
parts: Mapped[list] = mapped_column(JSON, default=list)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
class AIToolCall(Base):
__tablename__ = "ai_tool_calls"
id: Mapped[str] = mapped_column(String(36), primary_key=True)
run_id: Mapped[str] = mapped_column(ForeignKey("ai_runs.id"), index=True)
admin_id: Mapped[int] = mapped_column(ForeignKey("admins.id"), default=1)
call_id: Mapped[str] = mapped_column(String(200))
name: Mapped[str] = mapped_column(String(100))
arguments: Mapped[dict] = mapped_column(JSON)
preview: Mapped[dict] = mapped_column(JSON, default=dict)
result: Mapped[dict | None] = mapped_column(JSON)
status: Mapped[str] = mapped_column(String(30), default="pending")
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
__table_args__ = (UniqueConstraint("run_id", "call_id"),)