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
@@ -0,0 +1,98 @@
"""AI conversations tools and research version"""
from alembic import op
import sqlalchemy as sa
revision = '0002'
down_revision = '0001'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('ai_settings',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('base_url', sa.Text(), nullable=False),
sa.Column('api_key_encrypted', sa.Text(), nullable=True),
sa.Column('model', sa.String(length=200), nullable=False),
sa.Column('protocol', sa.String(length=30), nullable=False),
sa.Column('enabled', sa.Boolean(), nullable=False),
sa.Column('revision', sa.Integer(), nullable=False),
sa.Column('tested_revision', sa.Integer(), nullable=True),
sa.Column('test_results', sa.JSON(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.create_table('ai_conversations',
sa.Column('id', sa.String(length=36), nullable=False),
sa.Column('admin_id', sa.Integer(), nullable=False),
sa.Column('title', sa.String(length=100), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['admin_id'], ['admins.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('ai_runs',
sa.Column('id', sa.String(length=36), nullable=False),
sa.Column('conversation_id', sa.String(length=36), nullable=False),
sa.Column('request_id', sa.String(length=100), nullable=False),
sa.Column('status', sa.String(length=30), nullable=False),
sa.Column('context', sa.JSON(), nullable=False),
sa.Column('model', sa.String(length=200), nullable=False),
sa.Column('settings_revision', sa.Integer(), nullable=False),
sa.Column('model_messages', sa.JSON(), nullable=False),
sa.Column('history_start', sa.Integer(), nullable=False),
sa.Column('usage', sa.JSON(), nullable=False),
sa.Column('elapsed_ms', sa.Integer(), nullable=False),
sa.Column('error', sa.Text(), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['conversation_id'], ['ai_conversations.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('conversation_id', 'request_id')
)
op.create_index(op.f('ix_ai_runs_conversation_id'), 'ai_runs', ['conversation_id'], unique=False)
op.create_table('ai_messages',
sa.Column('id', sa.String(length=36), nullable=False),
sa.Column('conversation_id', sa.String(length=36), nullable=False),
sa.Column('run_id', sa.String(length=36), nullable=False),
sa.Column('role', sa.String(length=20), nullable=False),
sa.Column('parts', sa.JSON(), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['conversation_id'], ['ai_conversations.id'], ),
sa.ForeignKeyConstraint(['run_id'], ['ai_runs.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_ai_messages_conversation_id'), 'ai_messages', ['conversation_id'], unique=False)
op.create_index(op.f('ix_ai_messages_run_id'), 'ai_messages', ['run_id'], unique=False)
op.create_table('ai_tool_calls',
sa.Column('id', sa.String(length=36), nullable=False),
sa.Column('run_id', sa.String(length=36), nullable=False),
sa.Column('admin_id', sa.Integer(), nullable=False),
sa.Column('call_id', sa.String(length=200), nullable=False),
sa.Column('name', sa.String(length=100), nullable=False),
sa.Column('arguments', sa.JSON(), nullable=False),
sa.Column('preview', sa.JSON(), nullable=False),
sa.Column('result', sa.JSON(), nullable=True),
sa.Column('status', sa.String(length=30), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['admin_id'], ['admins.id'], ),
sa.ForeignKeyConstraint(['run_id'], ['ai_runs.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('run_id', 'call_id')
)
op.create_index(op.f('ix_ai_tool_calls_run_id'), 'ai_tool_calls', ['run_id'], unique=False)
op.add_column('research', sa.Column('version', sa.Integer(), server_default='1', nullable=False))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('research', 'version')
op.drop_index(op.f('ix_ai_tool_calls_run_id'), table_name='ai_tool_calls')
op.drop_table('ai_tool_calls')
op.drop_index(op.f('ix_ai_messages_run_id'), table_name='ai_messages')
op.drop_index(op.f('ix_ai_messages_conversation_id'), table_name='ai_messages')
op.drop_table('ai_messages')
op.drop_index(op.f('ix_ai_runs_conversation_id'), table_name='ai_runs')
op.drop_table('ai_runs')
op.drop_table('ai_conversations')
op.drop_table('ai_settings')
# ### end Alembic commands ###