mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-11 21:30:59 +00:00
refactor(core): remove pre-3.x legacy config migration system
The pkg/core/migrations system (m001-m043 DBMigration-style config migrations, MigrationStage, and the core.migration base class) only ever ran when upgrading from LangBot 3.x. The last 3.x release is over a year old and is no longer supported, so this dead code is removed entirely: - delete pkg/core/migrations/ (43 mXXX_*.py + __init__) - delete pkg/core/migration.py (base class + registry) - delete pkg/core/stages/migrate.py (MigrationStage) - drop 'MigrationStage' from boot.py stage_order - delete tests/unit_tests/core/test_migration.py (tested the removed base class)
This commit is contained in:
@@ -16,7 +16,6 @@ importutil.import_modules_in_pkg(stages)
|
|||||||
|
|
||||||
stage_order = [
|
stage_order = [
|
||||||
'LoadConfigStage',
|
'LoadConfigStage',
|
||||||
'MigrationStage',
|
|
||||||
'GenKeysStage',
|
'GenKeysStage',
|
||||||
'SetupLoggerStage',
|
'SetupLoggerStage',
|
||||||
'BuildAppStage',
|
'BuildAppStage',
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import abc
|
|
||||||
import typing
|
|
||||||
|
|
||||||
from . import app
|
|
||||||
|
|
||||||
|
|
||||||
preregistered_migrations: list[typing.Type[Migration]] = []
|
|
||||||
"""Currently not supported for extension"""
|
|
||||||
|
|
||||||
|
|
||||||
def migration_class(name: str, number: int):
|
|
||||||
"""Register a migration"""
|
|
||||||
|
|
||||||
def decorator(cls: typing.Type[Migration]) -> typing.Type[Migration]:
|
|
||||||
cls.name = name
|
|
||||||
cls.number = number
|
|
||||||
preregistered_migrations.append(cls)
|
|
||||||
return cls
|
|
||||||
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(abc.ABC):
|
|
||||||
"""A version migration"""
|
|
||||||
|
|
||||||
name: str
|
|
||||||
|
|
||||||
number: int
|
|
||||||
|
|
||||||
ap: app.Application
|
|
||||||
|
|
||||||
def __init__(self, ap: app.Application):
|
|
||||||
self.ap = ap
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""Determine if the current environment needs to run this migration"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
async def run(self):
|
|
||||||
"""Run migration"""
|
|
||||||
pass
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('sensitive-word-migration', 1)
|
|
||||||
class SensitiveWordMigration(migration.Migration):
|
|
||||||
"""敏感词迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return os.path.exists('data/config/sensitive-words.json') and not os.path.exists(
|
|
||||||
'data/metadata/sensitive-words.json'
|
|
||||||
)
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
# 移动文件
|
|
||||||
os.rename('data/config/sensitive-words.json', 'data/metadata/sensitive-words.json')
|
|
||||||
|
|
||||||
# 重新加载配置
|
|
||||||
await self.ap.sensitive_meta.load_config()
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('openai-config-migration', 2)
|
|
||||||
class OpenAIConfigMigration(migration.Migration):
|
|
||||||
"""OpenAI配置迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return 'openai-config' in self.ap.provider_cfg.data
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
old_openai_config = self.ap.provider_cfg.data['openai-config'].copy()
|
|
||||||
|
|
||||||
if 'keys' not in self.ap.provider_cfg.data:
|
|
||||||
self.ap.provider_cfg.data['keys'] = {}
|
|
||||||
|
|
||||||
if 'openai' not in self.ap.provider_cfg.data['keys']:
|
|
||||||
self.ap.provider_cfg.data['keys']['openai'] = []
|
|
||||||
|
|
||||||
self.ap.provider_cfg.data['keys']['openai'] = old_openai_config['api-keys']
|
|
||||||
|
|
||||||
self.ap.provider_cfg.data['model'] = old_openai_config['chat-completions-params']['model']
|
|
||||||
|
|
||||||
del old_openai_config['chat-completions-params']['model']
|
|
||||||
|
|
||||||
if 'requester' not in self.ap.provider_cfg.data:
|
|
||||||
self.ap.provider_cfg.data['requester'] = {}
|
|
||||||
|
|
||||||
if 'openai-chat-completions' not in self.ap.provider_cfg.data['requester']:
|
|
||||||
self.ap.provider_cfg.data['requester']['openai-chat-completions'] = {}
|
|
||||||
|
|
||||||
self.ap.provider_cfg.data['requester']['openai-chat-completions'] = {
|
|
||||||
'base-url': old_openai_config['base_url'],
|
|
||||||
'args': old_openai_config['chat-completions-params'],
|
|
||||||
'timeout': old_openai_config['request-timeout'],
|
|
||||||
}
|
|
||||||
|
|
||||||
del self.ap.provider_cfg.data['openai-config']
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('anthropic-requester-config-completion', 3)
|
|
||||||
class AnthropicRequesterConfigCompletionMigration(migration.Migration):
|
|
||||||
"""OpenAI配置迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return (
|
|
||||||
'anthropic-messages' not in self.ap.provider_cfg.data['requester']
|
|
||||||
or 'anthropic' not in self.ap.provider_cfg.data['keys']
|
|
||||||
)
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
if 'anthropic-messages' not in self.ap.provider_cfg.data['requester']:
|
|
||||||
self.ap.provider_cfg.data['requester']['anthropic-messages'] = {
|
|
||||||
'base-url': 'https://api.anthropic.com',
|
|
||||||
'args': {'max_tokens': 1024},
|
|
||||||
'timeout': 120,
|
|
||||||
}
|
|
||||||
|
|
||||||
if 'anthropic' not in self.ap.provider_cfg.data['keys']:
|
|
||||||
self.ap.provider_cfg.data['keys']['anthropic'] = []
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('moonshot-config-completion', 4)
|
|
||||||
class MoonshotConfigCompletionMigration(migration.Migration):
|
|
||||||
"""OpenAI配置迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return (
|
|
||||||
'moonshot-chat-completions' not in self.ap.provider_cfg.data['requester']
|
|
||||||
or 'moonshot' not in self.ap.provider_cfg.data['keys']
|
|
||||||
)
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
if 'moonshot-chat-completions' not in self.ap.provider_cfg.data['requester']:
|
|
||||||
self.ap.provider_cfg.data['requester']['moonshot-chat-completions'] = {
|
|
||||||
'base-url': 'https://api.moonshot.cn/v1',
|
|
||||||
'args': {},
|
|
||||||
'timeout': 120,
|
|
||||||
}
|
|
||||||
|
|
||||||
if 'moonshot' not in self.ap.provider_cfg.data['keys']:
|
|
||||||
self.ap.provider_cfg.data['keys']['moonshot'] = []
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('deepseek-config-completion', 5)
|
|
||||||
class DeepseekConfigCompletionMigration(migration.Migration):
|
|
||||||
"""OpenAI配置迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return (
|
|
||||||
'deepseek-chat-completions' not in self.ap.provider_cfg.data['requester']
|
|
||||||
or 'deepseek' not in self.ap.provider_cfg.data['keys']
|
|
||||||
)
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
if 'deepseek-chat-completions' not in self.ap.provider_cfg.data['requester']:
|
|
||||||
self.ap.provider_cfg.data['requester']['deepseek-chat-completions'] = {
|
|
||||||
'base-url': 'https://api.deepseek.com',
|
|
||||||
'args': {},
|
|
||||||
'timeout': 120,
|
|
||||||
}
|
|
||||||
|
|
||||||
if 'deepseek' not in self.ap.provider_cfg.data['keys']:
|
|
||||||
self.ap.provider_cfg.data['keys']['deepseek'] = []
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('vision-config', 6)
|
|
||||||
class VisionConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return 'enable-vision' not in self.ap.provider_cfg.data
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
if 'enable-vision' not in self.ap.provider_cfg.data:
|
|
||||||
self.ap.provider_cfg.data['enable-vision'] = False
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('qcg-center-url-config', 7)
|
|
||||||
class QCGCenterURLConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return 'qcg-center-url' not in self.ap.system_cfg.data
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
|
|
||||||
if 'qcg-center-url' not in self.ap.system_cfg.data:
|
|
||||||
self.ap.system_cfg.data['qcg-center-url'] = 'https://api.qchatgpt.rockchin.top/api/v2'
|
|
||||||
|
|
||||||
await self.ap.system_cfg.dump_config()
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('ad-fixwin-cfg-migration', 8)
|
|
||||||
class AdFixwinConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return isinstance(self.ap.pipeline_cfg.data['rate-limit']['fixwin']['default'], int)
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
|
|
||||||
for session_name in self.ap.pipeline_cfg.data['rate-limit']['fixwin']:
|
|
||||||
temp_dict = {
|
|
||||||
'window-size': 60,
|
|
||||||
'limit': self.ap.pipeline_cfg.data['rate-limit']['fixwin'][session_name],
|
|
||||||
}
|
|
||||||
|
|
||||||
self.ap.pipeline_cfg.data['rate-limit']['fixwin'][session_name] = temp_dict
|
|
||||||
|
|
||||||
await self.ap.pipeline_cfg.dump_config()
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('msg-truncator-cfg-migration', 9)
|
|
||||||
class MsgTruncatorConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return 'msg-truncate' not in self.ap.pipeline_cfg.data
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
|
|
||||||
self.ap.pipeline_cfg.data['msg-truncate'] = {
|
|
||||||
'method': 'round',
|
|
||||||
'round': {'max-round': 10},
|
|
||||||
}
|
|
||||||
|
|
||||||
await self.ap.pipeline_cfg.dump_config()
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('ollama-requester-config', 10)
|
|
||||||
class MsgTruncatorConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return 'ollama-chat' not in self.ap.provider_cfg.data['requester']
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
|
|
||||||
self.ap.provider_cfg.data['requester']['ollama-chat'] = {
|
|
||||||
'base-url': 'http://127.0.0.1:11434',
|
|
||||||
'args': {},
|
|
||||||
'timeout': 600,
|
|
||||||
}
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('command-prefix-config', 11)
|
|
||||||
class CommandPrefixConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return 'command-prefix' not in self.ap.command_cfg.data
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
|
|
||||||
self.ap.command_cfg.data['command-prefix'] = ['!', '!']
|
|
||||||
|
|
||||||
await self.ap.command_cfg.dump_config()
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('runner-config', 12)
|
|
||||||
class RunnerConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return 'runner' not in self.ap.provider_cfg.data
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
|
|
||||||
self.ap.provider_cfg.data['runner'] = 'local-agent'
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('http-api-config', 13)
|
|
||||||
class HttpApiConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return 'http-api' not in self.ap.system_cfg.data or 'persistence' not in self.ap.system_cfg.data
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
|
|
||||||
self.ap.system_cfg.data['http-api'] = {
|
|
||||||
'enable': True,
|
|
||||||
'host': '0.0.0.0',
|
|
||||||
'port': 5300,
|
|
||||||
'jwt-expire': 604800,
|
|
||||||
}
|
|
||||||
|
|
||||||
self.ap.system_cfg.data['persistence'] = {
|
|
||||||
'sqlite': {'path': 'data/persistence.db'},
|
|
||||||
'use': 'sqlite',
|
|
||||||
}
|
|
||||||
|
|
||||||
await self.ap.system_cfg.dump_config()
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('force-delay-config', 14)
|
|
||||||
class ForceDelayConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return isinstance(self.ap.platform_cfg.data['force-delay'], list)
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
|
|
||||||
self.ap.platform_cfg.data['force-delay'] = {
|
|
||||||
'min': self.ap.platform_cfg.data['force-delay'][0],
|
|
||||||
'max': self.ap.platform_cfg.data['force-delay'][1],
|
|
||||||
}
|
|
||||||
|
|
||||||
await self.ap.platform_cfg.dump_config()
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('gitee-ai-config', 15)
|
|
||||||
class GiteeAIConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return (
|
|
||||||
'gitee-ai-chat-completions' not in self.ap.provider_cfg.data['requester']
|
|
||||||
or 'gitee-ai' not in self.ap.provider_cfg.data['keys']
|
|
||||||
)
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.provider_cfg.data['requester']['gitee-ai-chat-completions'] = {
|
|
||||||
'base-url': 'https://ai.gitee.com/v1',
|
|
||||||
'args': {},
|
|
||||||
'timeout': 120,
|
|
||||||
}
|
|
||||||
|
|
||||||
self.ap.provider_cfg.data['keys']['gitee-ai'] = ['XXXXX']
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('dify-service-api-config', 16)
|
|
||||||
class DifyServiceAPICfgMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return 'dify-service-api' not in self.ap.provider_cfg.data
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.provider_cfg.data['dify-service-api'] = {
|
|
||||||
'base-url': 'https://api.dify.ai/v1',
|
|
||||||
'app-type': 'chat',
|
|
||||||
'chat': {'api-key': 'app-1234567890'},
|
|
||||||
'workflow': {'api-key': 'app-1234567890', 'output-key': 'summary'},
|
|
||||||
}
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('dify-api-timeout-params', 17)
|
|
||||||
class DifyAPITimeoutParamsMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return (
|
|
||||||
'timeout' not in self.ap.provider_cfg.data['dify-service-api']['chat']
|
|
||||||
or 'timeout' not in self.ap.provider_cfg.data['dify-service-api']['workflow']
|
|
||||||
or 'agent' not in self.ap.provider_cfg.data['dify-service-api']
|
|
||||||
)
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.provider_cfg.data['dify-service-api']['chat']['timeout'] = 120
|
|
||||||
self.ap.provider_cfg.data['dify-service-api']['workflow']['timeout'] = 120
|
|
||||||
self.ap.provider_cfg.data['dify-service-api']['agent'] = {
|
|
||||||
'api-key': 'app-1234567890',
|
|
||||||
'timeout': 120,
|
|
||||||
}
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('xai-config', 18)
|
|
||||||
class XaiConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return 'xai-chat-completions' not in self.ap.provider_cfg.data['requester']
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.provider_cfg.data['requester']['xai-chat-completions'] = {
|
|
||||||
'base-url': 'https://api.x.ai/v1',
|
|
||||||
'args': {},
|
|
||||||
'timeout': 120,
|
|
||||||
}
|
|
||||||
self.ap.provider_cfg.data['keys']['xai'] = ['xai-1234567890']
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('zhipuai-config', 19)
|
|
||||||
class ZhipuaiConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return 'zhipuai-chat-completions' not in self.ap.provider_cfg.data['requester']
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.provider_cfg.data['requester']['zhipuai-chat-completions'] = {
|
|
||||||
'base-url': 'https://open.bigmodel.cn/api/paas/v4',
|
|
||||||
'args': {},
|
|
||||||
'timeout': 120,
|
|
||||||
}
|
|
||||||
self.ap.provider_cfg.data['keys']['zhipuai'] = ['xxxxxxx']
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('wecom-config', 20)
|
|
||||||
class WecomConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
|
|
||||||
# for adapter in self.ap.platform_cfg.data['platform-adapters']:
|
|
||||||
# if adapter['adapter'] == 'wecom':
|
|
||||||
# return False
|
|
||||||
|
|
||||||
# return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.platform_cfg.data['platform-adapters'].append(
|
|
||||||
{
|
|
||||||
'adapter': 'wecom',
|
|
||||||
'enable': False,
|
|
||||||
'host': '0.0.0.0',
|
|
||||||
'port': 2290,
|
|
||||||
'corpid': '',
|
|
||||||
'secret': '',
|
|
||||||
'token': '',
|
|
||||||
'EncodingAESKey': '',
|
|
||||||
'contacts_secret': '',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
await self.ap.platform_cfg.dump_config()
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('lark-config', 21)
|
|
||||||
class LarkConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
|
|
||||||
# for adapter in self.ap.platform_cfg.data['platform-adapters']:
|
|
||||||
# if adapter['adapter'] == 'lark':
|
|
||||||
# return False
|
|
||||||
|
|
||||||
# return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.platform_cfg.data['platform-adapters'].append(
|
|
||||||
{
|
|
||||||
'adapter': 'lark',
|
|
||||||
'enable': False,
|
|
||||||
'app_id': 'cli_abcdefgh',
|
|
||||||
'app_secret': 'XXXXXXXXXX',
|
|
||||||
'bot_name': 'LangBot',
|
|
||||||
'enable-webhook': False,
|
|
||||||
'port': 2285,
|
|
||||||
'encrypt-key': 'xxxxxxxxx',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
await self.ap.platform_cfg.dump_config()
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('lmstudio-config', 22)
|
|
||||||
class LmStudioConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
|
|
||||||
return 'lmstudio-chat-completions' not in self.ap.provider_cfg.data['requester']
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.provider_cfg.data['requester']['lmstudio-chat-completions'] = {
|
|
||||||
'base-url': 'http://127.0.0.1:1234/v1',
|
|
||||||
'args': {},
|
|
||||||
'timeout': 120,
|
|
||||||
}
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('siliconflow-config', 23)
|
|
||||||
class SiliconFlowConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
|
|
||||||
return 'siliconflow-chat-completions' not in self.ap.provider_cfg.data['requester']
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.provider_cfg.data['keys']['siliconflow'] = ['xxxxxxx']
|
|
||||||
|
|
||||||
self.ap.provider_cfg.data['requester']['siliconflow-chat-completions'] = {
|
|
||||||
'base-url': 'https://api.siliconflow.cn/v1',
|
|
||||||
'args': {},
|
|
||||||
'timeout': 120,
|
|
||||||
}
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('discord-config', 24)
|
|
||||||
class DiscordConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
|
|
||||||
# for adapter in self.ap.platform_cfg.data['platform-adapters']:
|
|
||||||
# if adapter['adapter'] == 'discord':
|
|
||||||
# return False
|
|
||||||
|
|
||||||
# return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.platform_cfg.data['platform-adapters'].append(
|
|
||||||
{
|
|
||||||
'adapter': 'discord',
|
|
||||||
'enable': False,
|
|
||||||
'client_id': '1234567890',
|
|
||||||
'token': 'XXXXXXXXXX',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
await self.ap.platform_cfg.dump_config()
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('gewechat-config', 25)
|
|
||||||
class GewechatConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
|
|
||||||
# for adapter in self.ap.platform_cfg.data['platform-adapters']:
|
|
||||||
# if adapter['adapter'] == 'gewechat':
|
|
||||||
# return False
|
|
||||||
|
|
||||||
# return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.platform_cfg.data['platform-adapters'].append(
|
|
||||||
{
|
|
||||||
'adapter': 'gewechat',
|
|
||||||
'enable': False,
|
|
||||||
'gewechat_url': 'http://your-gewechat-server:2531',
|
|
||||||
'gewechat_file_url': 'http://your-gewechat-server:2532',
|
|
||||||
'port': 2286,
|
|
||||||
'callback_url': 'http://your-callback-url:2286/gewechat/callback',
|
|
||||||
'app_id': '',
|
|
||||||
'token': '',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
await self.ap.platform_cfg.dump_config()
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('qqofficial-config', 26)
|
|
||||||
class QQOfficialConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
|
|
||||||
# for adapter in self.ap.platform_cfg.data['platform-adapters']:
|
|
||||||
# if adapter['adapter'] == 'qqofficial':
|
|
||||||
# return False
|
|
||||||
|
|
||||||
# return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.platform_cfg.data['platform-adapters'].append(
|
|
||||||
{
|
|
||||||
'adapter': 'qqofficial',
|
|
||||||
'enable': False,
|
|
||||||
'appid': '',
|
|
||||||
'secret': '',
|
|
||||||
'port': 2284,
|
|
||||||
'token': '',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
await self.ap.platform_cfg.dump_config()
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('wx-official-account-config', 27)
|
|
||||||
class WXOfficialAccountConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
|
|
||||||
# for adapter in self.ap.platform_cfg.data['platform-adapters']:
|
|
||||||
# if adapter['adapter'] == 'officialaccount':
|
|
||||||
# return False
|
|
||||||
|
|
||||||
# return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.platform_cfg.data['platform-adapters'].append(
|
|
||||||
{
|
|
||||||
'adapter': 'officialaccount',
|
|
||||||
'enable': False,
|
|
||||||
'token': '',
|
|
||||||
'EncodingAESKey': '',
|
|
||||||
'AppID': '',
|
|
||||||
'AppSecret': '',
|
|
||||||
'host': '0.0.0.0',
|
|
||||||
'port': 2287,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
await self.ap.platform_cfg.dump_config()
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('bailian-requester-config', 28)
|
|
||||||
class BailianRequesterConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
|
|
||||||
return 'bailian-chat-completions' not in self.ap.provider_cfg.data['requester']
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.provider_cfg.data['keys']['bailian'] = ['sk-xxxxxxx']
|
|
||||||
|
|
||||||
self.ap.provider_cfg.data['requester']['bailian-chat-completions'] = {
|
|
||||||
'base-url': 'https://dashscope.aliyuncs.com/compatible-mode/v1',
|
|
||||||
'args': {},
|
|
||||||
'timeout': 120,
|
|
||||||
}
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('dashscope-app-api-config', 29)
|
|
||||||
class DashscopeAppAPICfgMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return 'dashscope-app-api' not in self.ap.provider_cfg.data
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.provider_cfg.data['dashscope-app-api'] = {
|
|
||||||
'app-type': 'agent',
|
|
||||||
'api-key': 'sk-1234567890',
|
|
||||||
'agent': {'app-id': 'Your_app_id', 'references_quote': '参考资料来自:'},
|
|
||||||
'workflow': {
|
|
||||||
'app-id': 'Your_app_id',
|
|
||||||
'references_quote': '参考资料来自:',
|
|
||||||
'biz_params': {'city': '北京', 'date': '2023-08-10'},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('lark-config-cmpl', 30)
|
|
||||||
class LarkConfigCmplMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
|
|
||||||
for adapter in self.ap.platform_cfg.data['platform-adapters']:
|
|
||||||
if adapter['adapter'] == 'lark':
|
|
||||||
if 'enable-webhook' not in adapter:
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
for adapter in self.ap.platform_cfg.data['platform-adapters']:
|
|
||||||
if adapter['adapter'] == 'lark':
|
|
||||||
if 'enable-webhook' not in adapter:
|
|
||||||
adapter['enable-webhook'] = False
|
|
||||||
if 'port' not in adapter:
|
|
||||||
adapter['port'] = 2285
|
|
||||||
if 'encrypt-key' not in adapter:
|
|
||||||
adapter['encrypt-key'] = 'xxxxxxxxx'
|
|
||||||
|
|
||||||
await self.ap.platform_cfg.dump_config()
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('dingtalk-config', 31)
|
|
||||||
class DingTalkConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
|
|
||||||
# for adapter in self.ap.platform_cfg.data['platform-adapters']:
|
|
||||||
# if adapter['adapter'] == 'dingtalk':
|
|
||||||
# return False
|
|
||||||
|
|
||||||
# return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.platform_cfg.data['platform-adapters'].append(
|
|
||||||
{
|
|
||||||
'adapter': 'dingtalk',
|
|
||||||
'enable': False,
|
|
||||||
'client_id': '',
|
|
||||||
'client_secret': '',
|
|
||||||
'robot_code': '',
|
|
||||||
'robot_name': '',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
await self.ap.platform_cfg.dump_config()
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('volcark-requester-config', 32)
|
|
||||||
class VolcArkRequesterConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
|
|
||||||
return 'volcark-chat-completions' not in self.ap.provider_cfg.data['requester']
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.provider_cfg.data['keys']['volcark'] = ['xxxxxxxx']
|
|
||||||
|
|
||||||
self.ap.provider_cfg.data['requester']['volcark-chat-completions'] = {
|
|
||||||
'base-url': 'https://ark.cn-beijing.volces.com/api/v3',
|
|
||||||
'args': {},
|
|
||||||
'timeout': 120,
|
|
||||||
}
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('dify-thinking-config', 33)
|
|
||||||
class DifyThinkingConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
|
|
||||||
if 'options' not in self.ap.provider_cfg.data['dify-service-api']:
|
|
||||||
return True
|
|
||||||
|
|
||||||
if 'convert-thinking-tips' not in self.ap.provider_cfg.data['dify-service-api']['options']:
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.provider_cfg.data['dify-service-api']['options'] = {'convert-thinking-tips': 'plain'}
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from urllib.parse import urlparse
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('gewechat-file-url-config', 34)
|
|
||||||
class GewechatFileUrlConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
|
|
||||||
for adapter in self.ap.platform_cfg.data['platform-adapters']:
|
|
||||||
if adapter['adapter'] == 'gewechat':
|
|
||||||
if 'gewechat_file_url' not in adapter:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
for adapter in self.ap.platform_cfg.data['platform-adapters']:
|
|
||||||
if adapter['adapter'] == 'gewechat':
|
|
||||||
if 'gewechat_file_url' not in adapter:
|
|
||||||
parsed_url = urlparse(adapter['gewechat_url'])
|
|
||||||
adapter['gewechat_file_url'] = f'{parsed_url.scheme}://{parsed_url.hostname}:2532'
|
|
||||||
|
|
||||||
await self.ap.platform_cfg.dump_config()
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('wxoa-mode', 35)
|
|
||||||
class WxoaModeMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
|
|
||||||
for adapter in self.ap.platform_cfg.data['platform-adapters']:
|
|
||||||
if adapter['adapter'] == 'officialaccount':
|
|
||||||
if 'Mode' not in adapter:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
for adapter in self.ap.platform_cfg.data['platform-adapters']:
|
|
||||||
if adapter['adapter'] == 'officialaccount':
|
|
||||||
if 'Mode' not in adapter:
|
|
||||||
adapter['Mode'] = 'drop'
|
|
||||||
|
|
||||||
await self.ap.platform_cfg.dump_config()
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('wxoa-loading-message', 36)
|
|
||||||
class WxoaLoadingMessageMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
|
|
||||||
for adapter in self.ap.platform_cfg.data['platform-adapters']:
|
|
||||||
if adapter['adapter'] == 'officialaccount':
|
|
||||||
if 'LoadingMessage' not in adapter:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
for adapter in self.ap.platform_cfg.data['platform-adapters']:
|
|
||||||
if adapter['adapter'] == 'officialaccount':
|
|
||||||
if 'LoadingMessage' not in adapter:
|
|
||||||
adapter['LoadingMessage'] = 'AI正在思考中,请发送任意内容获取回复。'
|
|
||||||
|
|
||||||
await self.ap.platform_cfg.dump_config()
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('mcp-config', 37)
|
|
||||||
class MCPConfigMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return 'mcp' not in self.ap.provider_cfg.data
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.provider_cfg.data['mcp'] = {'servers': []}
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('tg-dingtalk-markdown', 38)
|
|
||||||
class TgDingtalkMarkdownMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
|
|
||||||
for adapter in self.ap.platform_cfg.data['platform-adapters']:
|
|
||||||
if adapter['adapter'] in ['dingtalk', 'telegram']:
|
|
||||||
if 'markdown_card' not in adapter:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
for adapter in self.ap.platform_cfg.data['platform-adapters']:
|
|
||||||
if adapter['adapter'] in ['dingtalk', 'telegram']:
|
|
||||||
if 'markdown_card' not in adapter:
|
|
||||||
adapter['markdown_card'] = False
|
|
||||||
await self.ap.platform_cfg.dump_config()
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('modelscope-config-completion', 39)
|
|
||||||
class ModelScopeConfigCompletionMigration(migration.Migration):
|
|
||||||
"""ModelScope配置迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return (
|
|
||||||
'modelscope-chat-completions' not in self.ap.provider_cfg.data['requester']
|
|
||||||
or 'modelscope' not in self.ap.provider_cfg.data['keys']
|
|
||||||
)
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
if 'modelscope-chat-completions' not in self.ap.provider_cfg.data['requester']:
|
|
||||||
self.ap.provider_cfg.data['requester']['modelscope-chat-completions'] = {
|
|
||||||
'base-url': 'https://api-inference.modelscope.cn/v1',
|
|
||||||
'args': {},
|
|
||||||
'timeout': 120,
|
|
||||||
}
|
|
||||||
|
|
||||||
if 'modelscope' not in self.ap.provider_cfg.data['keys']:
|
|
||||||
self.ap.provider_cfg.data['keys']['modelscope'] = []
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('ppio-config', 40)
|
|
||||||
class PPIOConfigMigration(migration.Migration):
|
|
||||||
"""PPIO配置迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return (
|
|
||||||
'ppio-chat-completions' not in self.ap.provider_cfg.data['requester']
|
|
||||||
or 'ppio' not in self.ap.provider_cfg.data['keys']
|
|
||||||
)
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
if 'ppio-chat-completions' not in self.ap.provider_cfg.data['requester']:
|
|
||||||
self.ap.provider_cfg.data['requester']['ppio-chat-completions'] = {
|
|
||||||
'base-url': 'https://api.ppinfra.com/v3/openai',
|
|
||||||
'args': {},
|
|
||||||
'timeout': 120,
|
|
||||||
}
|
|
||||||
|
|
||||||
if 'ppio' not in self.ap.provider_cfg.data['keys']:
|
|
||||||
self.ap.provider_cfg.data['keys']['ppio'] = []
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('dingtalk_card_auto_layout', 41)
|
|
||||||
class DingTalkCardAutoLayoutMigration(migration.Migration):
|
|
||||||
"""迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return True
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.platform_cfg.data['platform-adapters']['app']['dingtalk']['card_auto_layout'] = False
|
|
||||||
await self.ap.platform_cfg.dump_config()
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('weknora-api-config', 42)
|
|
||||||
class WeKnoraAPICfgMigration(migration.Migration):
|
|
||||||
"""WeKnora API 配置迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return 'weknora-api' not in self.ap.provider_cfg.data
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.provider_cfg.data['weknora-api'] = {
|
|
||||||
'base-url': 'http://localhost:8080/api/v1',
|
|
||||||
'app-type': 'agent',
|
|
||||||
'api-key': '',
|
|
||||||
'agent-id': 'builtin-smart-reasoning',
|
|
||||||
'knowledge-base-ids': [],
|
|
||||||
'web-search-enabled': False,
|
|
||||||
'timeout': 120,
|
|
||||||
'base-prompt': '请回答用户的问题。',
|
|
||||||
}
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from .. import migration
|
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class('deerflow-api-config', 43)
|
|
||||||
class DeerFlowAPICfgMigration(migration.Migration):
|
|
||||||
"""DeerFlow API 配置迁移"""
|
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
"""判断当前环境是否需要运行此迁移"""
|
|
||||||
return 'deerflow-api' not in self.ap.provider_cfg.data
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
"""执行迁移"""
|
|
||||||
self.ap.provider_cfg.data['deerflow-api'] = {
|
|
||||||
'api-base': 'http://127.0.0.1:2026',
|
|
||||||
'api-key': '',
|
|
||||||
'auth-header': '',
|
|
||||||
'assistant-id': 'lead_agent',
|
|
||||||
'model-name': '',
|
|
||||||
'thinking-enabled': False,
|
|
||||||
'plan-mode': False,
|
|
||||||
'subagent-enabled': False,
|
|
||||||
'max-concurrent-subagents': 3,
|
|
||||||
'timeout': 300,
|
|
||||||
'recursion-limit': 1000,
|
|
||||||
}
|
|
||||||
|
|
||||||
await self.ap.provider_cfg.dump_config()
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
|
|
||||||
from .. import stage, app
|
|
||||||
from .. import migration
|
|
||||||
from ...utils import importutil
|
|
||||||
from .. import migrations
|
|
||||||
|
|
||||||
importutil.import_modules_in_pkg(migrations)
|
|
||||||
|
|
||||||
|
|
||||||
@stage.stage_class('MigrationStage')
|
|
||||||
class MigrationStage(stage.BootingStage):
|
|
||||||
"""Migration stage
|
|
||||||
|
|
||||||
These migrations are legacy, only performed in version 3.x
|
|
||||||
"""
|
|
||||||
|
|
||||||
async def run(self, ap: app.Application):
|
|
||||||
"""Run migration"""
|
|
||||||
|
|
||||||
if any(
|
|
||||||
[
|
|
||||||
ap.command_cfg is None,
|
|
||||||
ap.pipeline_cfg is None,
|
|
||||||
ap.platform_cfg is None,
|
|
||||||
ap.provider_cfg is None,
|
|
||||||
ap.system_cfg is None,
|
|
||||||
]
|
|
||||||
): # only run migration when version is 3.x
|
|
||||||
return
|
|
||||||
|
|
||||||
migrations = migration.preregistered_migrations
|
|
||||||
|
|
||||||
# Sort by migration number
|
|
||||||
migrations.sort(key=lambda x: x.number)
|
|
||||||
|
|
||||||
for migration_cls in migrations:
|
|
||||||
migration_instance = migration_cls(ap)
|
|
||||||
|
|
||||||
if await migration_instance.need_migrate():
|
|
||||||
await migration_instance.run()
|
|
||||||
print(f'Migration {migration_instance.name} executed')
|
|
||||||
@@ -1,238 +0,0 @@
|
|||||||
"""Tests for core migration registration and abstract classes."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from unittest.mock import MagicMock
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
from tests.utils.import_isolation import isolated_sys_modules
|
|
||||||
|
|
||||||
|
|
||||||
class TestMigrationClassDecorator:
|
|
||||||
"""Tests for @migration_class decorator."""
|
|
||||||
|
|
||||||
def _make_migration_import_mocks(self):
|
|
||||||
"""Create mocks for migration import."""
|
|
||||||
return {
|
|
||||||
'langbot.pkg.core.app': MagicMock(),
|
|
||||||
}
|
|
||||||
|
|
||||||
def test_migration_class_registers_migration(self):
|
|
||||||
"""@migration_class registers migration in preregistered_migrations."""
|
|
||||||
mocks = self._make_migration_import_mocks()
|
|
||||||
|
|
||||||
with isolated_sys_modules(mocks):
|
|
||||||
from langbot.pkg.core.migration import migration_class, preregistered_migrations
|
|
||||||
|
|
||||||
# Clear for clean test
|
|
||||||
preregistered_migrations.clear()
|
|
||||||
|
|
||||||
@migration_class('test-migration', 1)
|
|
||||||
class TestMigration:
|
|
||||||
pass
|
|
||||||
|
|
||||||
assert len(preregistered_migrations) == 1
|
|
||||||
assert preregistered_migrations[0] == TestMigration
|
|
||||||
|
|
||||||
def test_migration_class_sets_name_attribute(self):
|
|
||||||
"""@migration_class sets name attribute on class."""
|
|
||||||
mocks = self._make_migration_import_mocks()
|
|
||||||
|
|
||||||
with isolated_sys_modules(mocks):
|
|
||||||
from langbot.pkg.core.migration import migration_class
|
|
||||||
|
|
||||||
@migration_class('test-migration', 1)
|
|
||||||
class TestMigration:
|
|
||||||
pass
|
|
||||||
|
|
||||||
assert TestMigration.name == 'test-migration'
|
|
||||||
|
|
||||||
def test_migration_class_sets_number_attribute(self):
|
|
||||||
"""@migration_class sets number attribute on class."""
|
|
||||||
mocks = self._make_migration_import_mocks()
|
|
||||||
|
|
||||||
with isolated_sys_modules(mocks):
|
|
||||||
from langbot.pkg.core.migration import migration_class
|
|
||||||
|
|
||||||
@migration_class('test-migration', 42)
|
|
||||||
class TestMigration:
|
|
||||||
pass
|
|
||||||
|
|
||||||
assert TestMigration.number == 42
|
|
||||||
|
|
||||||
def test_migration_class_returns_original_class(self):
|
|
||||||
"""@migration_class returns the original class."""
|
|
||||||
mocks = self._make_migration_import_mocks()
|
|
||||||
|
|
||||||
with isolated_sys_modules(mocks):
|
|
||||||
from langbot.pkg.core.migration import migration_class
|
|
||||||
|
|
||||||
@migration_class('test', 1)
|
|
||||||
class TestMigration:
|
|
||||||
custom_attr = 'value'
|
|
||||||
|
|
||||||
assert TestMigration.custom_attr == 'value'
|
|
||||||
|
|
||||||
def test_migration_class_multiple_migrations(self):
|
|
||||||
"""Multiple migrations can be registered."""
|
|
||||||
mocks = self._make_migration_import_mocks()
|
|
||||||
|
|
||||||
with isolated_sys_modules(mocks):
|
|
||||||
from langbot.pkg.core.migration import migration_class, preregistered_migrations
|
|
||||||
|
|
||||||
preregistered_migrations.clear()
|
|
||||||
|
|
||||||
@migration_class('migration1', 1)
|
|
||||||
class Migration1:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@migration_class('migration2', 2)
|
|
||||||
class Migration2:
|
|
||||||
pass
|
|
||||||
|
|
||||||
assert len(preregistered_migrations) == 2
|
|
||||||
assert preregistered_migrations[0] == Migration1
|
|
||||||
assert preregistered_migrations[1] == Migration2
|
|
||||||
|
|
||||||
|
|
||||||
class TestMigrationAbstractClass:
|
|
||||||
"""Tests for Migration abstract class."""
|
|
||||||
|
|
||||||
def _make_migration_import_mocks(self):
|
|
||||||
return {'langbot.pkg.core.app': MagicMock()}
|
|
||||||
|
|
||||||
def test_migration_is_abstract(self):
|
|
||||||
"""Migration is abstract and cannot be instantiated directly."""
|
|
||||||
mocks = self._make_migration_import_mocks()
|
|
||||||
|
|
||||||
with isolated_sys_modules(mocks):
|
|
||||||
from langbot.pkg.core.migration import Migration
|
|
||||||
|
|
||||||
with pytest.raises(TypeError):
|
|
||||||
Migration(MagicMock())
|
|
||||||
|
|
||||||
def test_migration_requires_need_migrate_method(self):
|
|
||||||
"""Subclass must implement need_migrate method."""
|
|
||||||
mocks = self._make_migration_import_mocks()
|
|
||||||
|
|
||||||
with isolated_sys_modules(mocks):
|
|
||||||
from langbot.pkg.core.migration import Migration
|
|
||||||
|
|
||||||
class IncompleteMigration(Migration):
|
|
||||||
async def run(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
with pytest.raises(TypeError):
|
|
||||||
IncompleteMigration(MagicMock())
|
|
||||||
|
|
||||||
def test_migration_requires_run_method(self):
|
|
||||||
"""Subclass must implement run method."""
|
|
||||||
mocks = self._make_migration_import_mocks()
|
|
||||||
|
|
||||||
with isolated_sys_modules(mocks):
|
|
||||||
from langbot.pkg.core.migration import Migration
|
|
||||||
|
|
||||||
class IncompleteMigration(Migration):
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
return False
|
|
||||||
|
|
||||||
with pytest.raises(TypeError):
|
|
||||||
IncompleteMigration(MagicMock())
|
|
||||||
|
|
||||||
def test_migration_subclass_works(self):
|
|
||||||
"""Complete subclass can be instantiated."""
|
|
||||||
mocks = self._make_migration_import_mocks()
|
|
||||||
|
|
||||||
with isolated_sys_modules(mocks):
|
|
||||||
from langbot.pkg.core.migration import Migration
|
|
||||||
|
|
||||||
class CompleteMigration(Migration):
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
return True
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
mock_ap = MagicMock()
|
|
||||||
migration = CompleteMigration(mock_ap)
|
|
||||||
assert migration.ap == mock_ap
|
|
||||||
|
|
||||||
def test_migration_stores_app_reference(self):
|
|
||||||
"""Migration stores ap reference in __init__."""
|
|
||||||
mocks = self._make_migration_import_mocks()
|
|
||||||
|
|
||||||
with isolated_sys_modules(mocks):
|
|
||||||
from langbot.pkg.core.migration import Migration
|
|
||||||
|
|
||||||
class TestMigration(Migration):
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
mock_ap = MagicMock()
|
|
||||||
migration = TestMigration(mock_ap)
|
|
||||||
assert migration.ap is mock_ap
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_migration_need_migrate_returns_bool(self):
|
|
||||||
"""need_migrate must return bool."""
|
|
||||||
mocks = self._make_migration_import_mocks()
|
|
||||||
|
|
||||||
with isolated_sys_modules(mocks):
|
|
||||||
from langbot.pkg.core.migration import Migration
|
|
||||||
|
|
||||||
class TestMigration(Migration):
|
|
||||||
async def need_migrate(self) -> bool:
|
|
||||||
return True
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
migration = TestMigration(MagicMock())
|
|
||||||
result = await migration.need_migrate()
|
|
||||||
assert isinstance(result, bool)
|
|
||||||
assert result == True
|
|
||||||
|
|
||||||
|
|
||||||
class TestPreregisteredMigrations:
|
|
||||||
"""Tests for preregistered_migrations global registry."""
|
|
||||||
|
|
||||||
def _make_migration_import_mocks(self):
|
|
||||||
return {'langbot.pkg.core.app': MagicMock()}
|
|
||||||
|
|
||||||
def test_preregistered_migrations_is_list(self):
|
|
||||||
"""preregistered_migrations is a list."""
|
|
||||||
mocks = self._make_migration_import_mocks()
|
|
||||||
|
|
||||||
with isolated_sys_modules(mocks):
|
|
||||||
from langbot.pkg.core.migration import preregistered_migrations
|
|
||||||
|
|
||||||
assert isinstance(preregistered_migrations, list)
|
|
||||||
|
|
||||||
def test_preregistered_migrations_order(self):
|
|
||||||
"""Migrations are registered in order of decoration."""
|
|
||||||
mocks = self._make_migration_import_mocks()
|
|
||||||
|
|
||||||
with isolated_sys_modules(mocks):
|
|
||||||
from langbot.pkg.core.migration import migration_class, preregistered_migrations
|
|
||||||
|
|
||||||
preregistered_migrations.clear()
|
|
||||||
|
|
||||||
@migration_class('first', 1)
|
|
||||||
class First:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@migration_class('second', 2)
|
|
||||||
class Second:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@migration_class('third', 3)
|
|
||||||
class Third:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Order should match decoration order
|
|
||||||
assert preregistered_migrations[0].number == 1
|
|
||||||
assert preregistered_migrations[1].number == 2
|
|
||||||
assert preregistered_migrations[2].number == 3
|
|
||||||
Reference in New Issue
Block a user