-
Notifications
You must be signed in to change notification settings - Fork 33
feat(chat): 支持单模型组成team实现聊天 #268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
e35dece
54e86b8
341a36a
7ec2c27
66f8e30
326db41
51c868b
4acb79c
e2b3836
9bfdc43
037974a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| # SPDX-FileCopyrightText: 2025 Weibo, Inc. | ||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| """Add subtask_attachments table for file upload support | ||
|
|
||
| Revision ID: add_subtask_attachments | ||
| Revises: | ||
| Create Date: 2025-12-03 | ||
|
|
||
| """ | ||
| from typing import Sequence, Union | ||
|
|
||
| from alembic import op | ||
| import sqlalchemy as sa | ||
|
|
||
|
|
||
| # revision identifiers, used by Alembic. | ||
| revision: str = 'add_subtask_attachments' | ||
| down_revision: Union[str, None] = 'a1b2c3d4e5f6' | ||
| branch_labels: Union[str, Sequence[str], None] = None | ||
| depends_on: Union[str, Sequence[str], None] = None | ||
|
|
||
|
|
||
| def upgrade() -> None: | ||
| """Create subtask_attachments table.""" | ||
| op.create_table( | ||
| 'subtask_attachments', | ||
| sa.Column('id', sa.Integer(), nullable=False, autoincrement=True), | ||
| sa.Column('subtask_id', sa.Integer(), nullable=True), | ||
| sa.Column('user_id', sa.Integer(), nullable=False), | ||
| sa.Column('original_filename', sa.String(255), nullable=False), | ||
| sa.Column('file_extension', sa.String(20), nullable=False), | ||
| sa.Column('file_size', sa.Integer(), nullable=False), | ||
| sa.Column('mime_type', sa.String(100), nullable=False), | ||
| sa.Column('binary_data', sa.LargeBinary(), nullable=False), | ||
| sa.Column('extracted_text', sa.Text(), nullable=True), | ||
| sa.Column('text_length', sa.Integer(), nullable=True), | ||
| sa.Column('status', sa.Enum('uploading', 'parsing', 'ready', 'failed', name='attachmentstatus'), nullable=False), | ||
| sa.Column('error_message', sa.String(500), nullable=True), | ||
| sa.Column('created_at', sa.DateTime(), nullable=True), | ||
| sa.PrimaryKeyConstraint('id'), | ||
| sa.ForeignKeyConstraint(['subtask_id'], ['subtasks.id'], ondelete='CASCADE'), | ||
| mysql_charset='utf8mb4', | ||
| mysql_collate='utf8mb4_unicode_ci', | ||
| mysql_engine='InnoDB' | ||
| ) | ||
|
|
||
| # Create indexes | ||
| op.create_index('ix_subtask_attachments_id', 'subtask_attachments', ['id']) | ||
| op.create_index('ix_subtask_attachments_subtask_id', 'subtask_attachments', ['subtask_id']) | ||
| op.create_index('ix_subtask_attachments_user_id', 'subtask_attachments', ['user_id']) | ||
|
|
||
|
|
||
| def downgrade() -> None: | ||
| """Drop subtask_attachments table.""" | ||
| op.drop_index('ix_subtask_attachments_user_id', table_name='subtask_attachments') | ||
| op.drop_index('ix_subtask_attachments_subtask_id', table_name='subtask_attachments') | ||
| op.drop_index('ix_subtask_attachments_id', table_name='subtask_attachments') | ||
| op.drop_table('subtask_attachments') | ||
|
|
||
| # Drop the enum type | ||
| op.execute("DROP TYPE IF EXISTS attachmentstatus") |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,65 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # SPDX-FileCopyrightText: 2025 Weibo, Inc. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # SPDX-License-Identifier: Apache-2.0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Fix binary_data column size to LONGBLOB for large file support | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Revision ID: fix_binary_data_size | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Revises: add_subtask_attachments | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Create Date: 2025-12-03 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| This migration changes the binary_data column from BLOB (64KB max) to LONGBLOB (4GB max) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| to support larger file uploads like PDFs and documents. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from typing import Sequence, Union | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from alembic import op | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import sqlalchemy as sa | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from sqlalchemy.dialects import mysql | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # revision identifiers, used by Alembic. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| revision: str = 'fix_binary_data_size' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| down_revision: Union[str, None] = 'add_subtask_attachments' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| branch_labels: Union[str, Sequence[str], None] = None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| depends_on: Union[str, Sequence[str], None] = None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def upgrade() -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Change binary_data column to LONGBLOB for MySQL.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Use MySQL-specific LONGBLOB type for large file support | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| op.alter_column( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'subtask_attachments', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'binary_data', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| existing_type=sa.LargeBinary(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type_=mysql.LONGBLOB(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| existing_nullable=False | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Also change extracted_text to LONGTEXT for large documents | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| op.alter_column( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'subtask_attachments', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'extracted_text', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| existing_type=sa.Text(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type_=mysql.LONGTEXT(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| existing_nullable=True | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def downgrade() -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Revert to original column types.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| op.alter_column( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'subtask_attachments', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'binary_data', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| existing_type=mysql.LONGBLOB(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type_=sa.LargeBinary(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| existing_nullable=False | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| op.alter_column( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'subtask_attachments', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'extracted_text', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| existing_type=mysql.LONGTEXT(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type_=sa.Text(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| existing_nullable=True | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def downgrade() -> None: | |
| """Revert to original column types.""" | |
| op.alter_column( | |
| 'subtask_attachments', | |
| 'binary_data', | |
| existing_type=mysql.LONGBLOB(), | |
| type_=sa.LargeBinary(), | |
| existing_nullable=False | |
| ) | |
| op.alter_column( | |
| 'subtask_attachments', | |
| 'extracted_text', | |
| existing_type=mysql.LONGTEXT(), | |
| type_=sa.Text(), | |
| existing_nullable=True | |
| ) | |
| def downgrade() -> None: | |
| """Revert to original column types. | |
| WARNING: This downgrade will fail or truncate data if any attachments | |
| exceed BLOB (64KB) or TEXT (64KB) limits. Ensure no large files exist | |
| before downgrading, or manually delete large attachments first. | |
| """ | |
| op.alter_column( | |
| 'subtask_attachments', | |
| 'binary_data', | |
| existing_type=mysql.LONGBLOB(), | |
| type_=sa.LargeBinary(), | |
| existing_nullable=False | |
| ) | |
| op.alter_column( | |
| 'subtask_attachments', | |
| 'extracted_text', | |
| existing_type=mysql.LONGTEXT(), | |
| type_=sa.Text(), | |
| existing_nullable=True | |
| ) |
🤖 Prompt for AI Agents
In backend/alembic/versions/fix_binary_data_size_fix_binary_data_column_size.py
around lines 49 to 65, the downgrade changes LONGBLOB→LargeBinary and
LONGTEXT→Text which can truncate data for values exceeding BLOB/Text limits; add
a clear warning comment immediately above the downgrade function documenting
this risk, instructing operators to backup the database, verify no column values
exceed target sizes (or refuse to run downgrade until verified), and recommend
an alternative migration strategy or manual cleanup to prevent data loss during
downgrade.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: wecode-ai/Wegent
Length of output: 42
🏁 Script executed:
Repository: wecode-ai/Wegent
Length of output: 739
🏁 Script executed:
Repository: wecode-ai/Wegent
Length of output: 8285
🏁 Script executed:
Repository: wecode-ai/Wegent
Length of output: 2045
🏁 Script executed:
Repository: wecode-ai/Wegent
Length of output: 2213
🏁 Script executed:
Repository: wecode-ai/Wegent
Length of output: 2323
🏁 Script executed:
Repository: wecode-ai/Wegent
Length of output: 712
Add dialect checks or document MySQL-only database requirement.
The migration switches from database-agnostic types (
sa.LargeBinary,sa.Text) to MySQL-specific types (mysql.LONGBLOB,mysql.LONGTEXT). While the table creation uses MySQL options, the original columns were intentionally defined with generic SQLAlchemy types. This migration creates vendor lock-in without explicit documentation.Either add dialect checks to handle multiple databases:
Or add a module-level docstring clarifying that MySQL is the only supported database:
🤖 Prompt for AI Agents