Undefined 可作为 Python 库嵌入到其他应用、脚本或测试环境中,复用配置系统、AI 客户端、Skills 注册表、认知记忆、知识库等组件,而无需启动完整的 QQ Bot CLI。
CLI 入口(
Undefined/Undefined-webui)行为不变;库嵌入路径与 CLI 启动链隔离。详见 配置详解 — 库嵌入配置。
# 源码开发
uv sync
# 或 PyPI 包
pip install Undefined-botPython 版本要求:3.11 ~ 3.13。
包内附带 py.typed 标记,mypy / Pyright / IDE 可直接消费类型信息。
以下符号承诺通过 from Undefined import … 长期稳定(完整清单见下文 公共 API 符号表):
from Undefined import (
__version__,
Config,
get_config,
set_config,
AIClient,
ToolRegistry,
AgentRegistry,
PipelineRegistry,
BaseRegistry,
AnthropicSkillRegistry,
CognitiveService,
KnowledgeManager,
MemeService,
AttachmentRegistry,
RuntimeAPIServer,
RuntimeAPIContext,
)根包符号与 公共 API 符号表 一致;若需更细粒度导入,可使用下方子包路径,二者语义等价。
| 稳定性 | 模块 | 常用符号 |
|---|---|---|
| stable | Undefined.config |
Config, get_config, set_config, ConfigBuilder, ChatModelConfig, VisionModelConfig, … |
| stable | Undefined.ai |
AIClient |
| stable | Undefined.skills |
ToolRegistry, AgentRegistry, PipelineRegistry |
| stable | Undefined.cognitive |
CognitiveService, CognitiveVectorStore, ProfileStorage, … |
| stable | Undefined.knowledge |
KnowledgeManager, Embedder, Reranker, RetrievalRuntime |
| stable | Undefined.memes |
MemeService, MemeStore, MemeWorker, … |
| stable | Undefined.attachments |
AttachmentRegistry |
| stable | Undefined.api |
RuntimeAPIServer, RuntimeAPIContext |
| subpackage | Undefined.skills.registry |
BaseRegistry, SkillItem, SkillStats |
| subpackage | Undefined.skills.anthropic_skills |
AnthropicSkillRegistry |
| subpackage | Undefined.mcp |
MCPToolRegistry, MCPToolSetRegistry |
拆分后下列 import 路径仍可用(指向子包公开 API,而非并列的 .py 单文件):
from Undefined.config.loader import Config # → Undefined.config.Config
from Undefined.ai.client import AIClient
from Undefined.attachments import AttachmentRegistry
from Undefined.skills.tools import ToolRegistry
from Undefined.cognitive.service import CognitiveService
from Undefined.knowledge.manager import KnowledgeManager
from Undefined.memes.service import MemeService
from Undefined.api.app import RuntimeAPIServer注意:请勿在同名包目录旁保留完整
.py副本(如handlers.py+handlers/)。Python 只会加载包目录,并列单文件会成为不可达死代码;仓库通过tests/test_package_layout.py回归检测。
以下模块不会进入根包 re-export,也不保证跨版本兼容:
Undefined.main,Undefined.webui,Undefined.handlers,Undefined.onebotUndefined.services下的运行时编排模块;AICoordinator的唯一内部导入路径是Undefined.services.coordinator,旧路径Undefined.services.ai_coordinator已移除Undefined.config.coercers,Undefined.config.parsers(Undefined.config.model_parsers仅保留兼容 re-export)Undefined.utils.io,Undefined.utils.paths
OneBot 内部时间解析提供两种约定:parse_message_time(message) 在无效时间上保留当前时间回退,适用于既有展示调用;try_parse_message_time(message) 返回 datetime | None,用于历史统计等必须区分未知时间的场景。二者均支持秒级、毫秒级及数值字符串时间戳;统计调用必须先排除 None,不能将其补为当前时间后计数或排序。
库嵌入场景的核心入口是 Config.from_mapping() 与 opt-in 的 set_config()。
Python 显式 mapping / override > config.toml > 环境变量 > 代码默认值
Config.from_mapping()/Config.builder():不读取config.toml、config.local.json或.env,适合测试与无文件部署;[webui]与其余字段一样使用传入 mapping,显式超级管理员仍自动加入管理员列表。Config.load():从指定或 CWD 下的config.toml加载(CLI 路径)。- 环境变量仅在 TOML / mapping 未提供对应项时兜底;详见 配置详解 — 环境变量兜底。
Config.load(strict=False) 只放宽必填项校验,文件的 TOML 语法、编码或读取错误仍会抛出 ValueError。ConfigManager.reload() 加载失败时保留原配置;订阅者应用失败会记录日志并保留变更,下次重载相同内容也会再次通知。运行时热更新应用函数会在完成其余同步步骤后汇报失败,后台失败同样会进入重试。
WebUISettings.from_config(config, config_exists=...) 从已验证的 Config 构建设置,不读文件;运行中的 WebUI 使用该入口刷新同一次重载的快照。config_exists 表示这份快照是否来自现存配置;显式或隐式的 changeme 都会标记为默认密码模式,禁止登录。独立 load_webui_settings() 保留首次启动的宽松解析和初始化默认值,不应拿它替代已验证的运行时快照。
从内存 dict 构建配置,结构与 config.toml 一致:
from Undefined.config import Config
cfg = Config.from_mapping(
{
"core": {"bot_qq": 123456, "superadmin_qq": 654321},
"onebot": {"ws_url": "ws://127.0.0.1:3001"},
"models": {
"chat": {
"api_url": "https://api.example/v1",
"api_key": "sk-xxx",
"model_name": "gpt-4o-mini",
},
"vision": {
"api_url": "https://api.example/v1",
"api_key": "sk-xxx",
"model_name": "gpt-4o-mini",
},
"agent": {
"api_url": "https://api.example/v1",
"api_key": "sk-xxx",
"model_name": "gpt-4o-mini",
},
},
},
strict=False, # 库嵌入 / 测试可放宽;生产 Bot 建议 strict=True
)
print(cfg.chat_model.model_name) # gpt-4o-ministrict=True 时缺失必填项(如 onebot.ws_url、各模型 api_url 等)会抛出异常;行为与 CLI 严格模式一致。
OneBotClient(ws_url, token="", *, config_getter=None, file_transport=None) 保留原有位置参数和发送返回值。未注入配置时本地文件默认使用 local,保持旧的本地路径发送行为;库嵌入需要 Stream 上传时可通过 config_getter 显式返回 FileSendSettings("stream"),运行中需要热更新则注入返回当前 Config 的函数:
from Undefined.onebot import OneBotClient
client = OneBotClient(cfg.onebot_ws_url, cfg.onebot_token, config_getter=lambda: cfg)OneBotFileTransport 的 chunk_size、timeout 和 store 可用于测试注入,不是额外业务配置。URL 模式需要将同一客户端传入 RuntimeAPIContext.onebot,并显式启动 RuntimeAPIServer;服务会绑定客户端的临时文件存储与实际监听端口,OneBot 发送方法不会自动启动 Runtime。准备错误为 FileTransferError,含 mode、stage、user_message 与 file_transfer_error 标记;投递发出后结果未确认仍为 OneBotDeliveryUncertainError。详细模式与部署要求见 配置说明。
stop_accepting_messages() 关闭新消息与通知事件入口,但保留已有 API 响应的处理,供已接收任务收尾;随后可用 drain_message_tasks() 等待这些任务完成。disconnect() 会先关闭新事件入口,再关闭 WebSocket 并取消、回收剩余消息任务,直接调用它也不会在断开期间新建消息任务。
disconnect() 用于终止当前客户端,后续启动应创建新的 OneBotClient。网络断线时,run_with_reconnect() 的自动重连路径不会调用 disconnect(),也不会关闭新事件入口。
链式构建器,适合在 base mapping 上覆盖少量字段:
cfg = (
Config.builder()
.with_mapping({"onebot": {"ws_url": "ws://127.0.0.1:3001"}, "models": {...}})
.override(log_level="DEBUG")
.build(strict=False)
)将已构建的 Config 注入全局单例,供 get_config() 与 get_config_manager().load() 读取:
from Undefined.config import Config, get_config, get_config_manager, set_config
cfg = Config.from_mapping({...}, strict=False)
set_config(cfg)
assert get_config(strict=False) is cfg
assert get_config_manager().load(strict=False) is cfg约束:
set_config()仅供库嵌入 opt-in 使用;CLI / WebUI 启动链不得调用。- 未调用
set_config()时,get_config()仍走 CWD 下./config.toml(与 CLI 行为一致)。 - 注入后会同步
ConfigManager缓存,库嵌入代码不应再混用独立的Config.load()实例。
mapping 为空时,已注册的环境变量仍可兜底填充配置:
import os
os.environ["ONEBOT_WS_URL"] = "ws://127.0.0.1:3001"
os.environ["CHAT_MODEL_API_URL"] = "https://api.example/v1"
# ... 其他必填 env
cfg = Config.from_mapping({}, strict=False)完整 env 注册表见 配置详解 §8。
from Undefined.config import Config, set_config
@pytest.fixture
def app_config():
cfg = Config.from_mapping(MINIMAL_MAPPING, strict=False)
set_config(cfg)
yield cfgfrom Undefined.config import Config
from Undefined.ai.client import AIClient
cfg = Config.from_mapping({...}, strict=False)
client = AIClient(cfg)
# 使用 client 发起 LLM 请求 …from Undefined.config import Config, set_config
from Undefined.api import RuntimeAPIServer, RuntimeAPIContext
cfg = Config.from_mapping({...}, strict=True)
set_config(cfg)
server = RuntimeAPIServer(RuntimeAPIContext(...))根包与子包 __all__ 中列出的符号为稳定面;semver minor 内不 breaking。
| 符号 | 定义模块 | 说明 |
|---|---|---|
__version__ |
Undefined |
包版本 |
Config |
Undefined.config |
应用配置 dataclass |
get_config |
Undefined.config |
获取全局配置单例 |
set_config |
Undefined.config |
opt-in 注入 Config(CLI 不调用) |
Config.builder |
Undefined.config |
链式配置构建器 |
Config.from_mapping |
Undefined.config |
从 dict 构建配置 |
AIClient |
Undefined.ai |
LLM 请求客户端 |
ToolRegistry |
Undefined.skills |
工具注册表 |
AgentRegistry |
Undefined.skills |
Agent 注册表 |
PipelineRegistry |
Undefined.skills |
自动处理管线注册表 |
BaseRegistry |
Undefined.skills.registry |
注册表基类 |
AnthropicSkillRegistry |
Undefined.skills.anthropic_skills |
Anthropic Skills 注册表 |
CognitiveService |
Undefined.cognitive |
认知记忆服务 |
KnowledgeManager |
Undefined.knowledge |
本地知识库管理 |
MemeService |
Undefined.memes |
表情包库服务 |
AttachmentRegistry |
Undefined.attachments |
附件 UID 登记 |
RuntimeAPIServer |
Undefined.api |
主进程 Runtime API 服务 |
RuntimeAPIContext |
Undefined.api |
Runtime API 运行时上下文 |
| 包 | 稳定性 | 符号 |
|---|---|---|
Undefined.config |
stable | Config, get_config, get_config_manager, set_config, WebUISettings, load_webui_settings, ChatModelConfig, VisionModelConfig, SecurityModelConfig, APIConfig, AgentModelConfig, EmbeddingModelConfig, GrokModelConfig, RerankModelConfig, ModelPool, ModelPoolEntry, MemeConfig, MessageBatcherConfig, RenderCacheConfig |
Undefined.ai |
stable | AIClient |
Undefined.skills |
stable | ToolRegistry, AgentRegistry, PipelineRegistry |
Undefined.skills.registry |
subpackage | BaseRegistry, SkillItem, SkillStats, RegistryExecutionTimeoutError |
Undefined.skills.anthropic_skills |
subpackage | AnthropicSkillRegistry |
Undefined.skills.pipelines |
subpackage | PipelineRegistry, PipelineDetection |
Undefined.cognitive |
stable | CognitiveService, CognitiveVectorStore, ProfileStorage, HistorianWorker, JobQueue |
Undefined.knowledge |
stable | KnowledgeManager, Embedder, Reranker, RetrievalRuntime |
Undefined.memes |
stable | MemeService, MemeStore, MemeWorker, MemeVectorStore, MemeRecord, MemeSearchItem, MemeSourceRecord |
Undefined.attachments |
stable | AttachmentRegistry |
Undefined.api |
stable | RuntimeAPIServer, RuntimeAPIContext |
Undefined.mcp |
subpackage | MCPToolRegistry, MCPToolSetRegistry |
ProfileStorage 的所有读写、历史版本和合并锁操作只接受 user / group 实体类型,以及非空的单层实体 ID(不接受路径分隔符、. / .. 或 Windows 盘符)。侧写文件与历史版本解析符号链接后必须仍位于 base_path 内,否则抛出 ValueError;路径解析与文件访问一起在线程中执行,避免阻塞事件循环。Runtime 的侧写查询接口将这类错误转换为 HTTP 400。
- 配置详解 — TOML 字段、热更新、库嵌入(§2)、环境变量全表(§8)
- 安装与部署 — CLI 部署与库嵌入交叉引用
- Runtime API / OpenAPI — HTTP 集成
- 开发者与拓展中心 — 源码结构与自检命令