Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
12224fe
fix(prompt): 避免心理委员关键词彩蛋导致AI误判
69gg Feb 16, 2026
39b3386
fix(api): 弃用JKYAI api
69gg Feb 16, 2026
1012d17
fix(agent): 按 allowed_callers 裁剪互调可见性
69gg Feb 16, 2026
23cf40f
fix: 让web_agent可以调用info_agent
69gg Feb 16, 2026
a885dc1
feat(bilibili): 切换官方接口并加入 WBI 重试
69gg Feb 16, 2026
6f18fb1
fix(logging): make TTY output opt-in by default
69gg Feb 16, 2026
fe9823e
fix: 修改默认绘图模型
69gg Feb 16, 2026
ef2a0e7
fix: 绘图工具url解析修复
69gg Feb 16, 2026
147bab7
feat(skills): 支持主工具按白名单暴露给 Agent
69gg Feb 16, 2026
650a788
feature(get_current_time): 升级换新get_current_time工具
69gg Feb 16, 2026
675f748
fix: 删除多余get_current_time
69gg Feb 16, 2026
0625e66
feature(get_current_time): 预取时带上农历
69gg Feb 16, 2026
2bdf6f4
feature(prompt): 分条发送消息以模拟真人
69gg Feb 16, 2026
155570a
feat(messages): add send_text_file for lightweight single-file delivery
69gg Feb 16, 2026
fdabd0d
feature: 添加更多文件扩展名支持
69gg Feb 16, 2026
44a4c2a
feat(anti-repeat): add inflight task summary guardrails
69gg Feb 17, 2026
47d7ff7
feat(prompts): externalize summary prompt templates
69gg Feb 17, 2026
ca23dad
chore(inflight): validate prompt placeholders and add diagnostics
69gg Feb 17, 2026
8df14d4
feat(prompt): harden anti-repeat task guardrails
69gg Feb 17, 2026
c4cdef5
fix(inflight): pre-register pending task before first model call
69gg Feb 17, 2026
db9727d
feat(config): add inflight summary enable switch
69gg Feb 17, 2026
72d6688
feat(stats): harden analysis pipeline and data summary
69gg Feb 17, 2026
67f947c
docs: document inflight anti-duplicate and /stats behavior
69gg Feb 17, 2026
fbc940c
refactor(inflight): migrate to asyncio.Lock and optimize GC
69gg Feb 17, 2026
5f7da76
fix: add safety guards for WBI key length and async task exceptions
69gg Feb 17, 2026
ffd1f9e
refactor(inflight): split pre-register and summary into independent s…
69gg Feb 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ Skills 是核心扩展机制,分四类,全部通过 `config.json`(OpenAI f
- 主配置:`config.toml`(TOML 格式,支持热更新)
- 配置模型:`config/models.py`,四类模型配置(chat/vision/agent/security)
- 运行时动态数据:`config.local.json`(自动生成,勿提交)
- 需重启的配置项:`log_level`, `logging.file_path/max_size_mb/backup_count`, `onebot.ws_url/token`, `webui.*`
- 需重启的配置项:`log_level`, `logging.file_path/max_size_mb/backup_count/tty_enabled`, `onebot.ws_url/token`, `webui.*`

## 开发注意事项

Expand Down
41 changes: 38 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
- **Skills 热重载**:自动扫描 `skills/` 目录,检测到变更后即时重载工具与 Agent,无需重启服务。
- **配置热更新 + WebUI**:使用 `config.toml` 配置,支持热更新;提供 WebUI 在线编辑与校验。
- **会话白名单(群/私聊)**:只需配置 `access.allowed_group_ids` / `access.allowed_private_ids` 两个列表,即可把机器人“锁”在指定群与指定私聊里;避免被拉进陌生群误触发、也避免工具/定时任务把消息误发到不该去的地方(默认留空不限制)。
- **并发防重复执行(进行中摘要)**:对私聊与 `@机器人` 场景在首轮前预占位,并在后续请求注入 `【进行中的任务】` 上下文,减少"催促/追问"导致的重复任务执行;支持通过 `features.inflight_pre_register_enabled`(预注册占位,默认启用)和 `features.inflight_summary_enabled`(摘要生成,默认禁用)独立控制。
- **并行工具执行**:无论是主 AI 还是子 Agent,均支持 `asyncio` 并发工具调用,大幅提升多任务处理速度(如同时读取多个文件或搜索多个关键词)。
- **智能 Agent 矩阵**:内置多个专业 Agent,分工协作处理复杂任务。
- **Agent 互调用**:Agent 之间可以相互调用,通过简单的配置文件(`callable.json`)即可让某个 Agent 成为其他 Agent 的工具,支持细粒度的访问控制,实现复杂的多 Agent 协作场景。
Expand Down Expand Up @@ -480,14 +481,18 @@ uv run Undefined-webui
- `allowed_private_ids`:允许处理/发送消息的私聊 QQ 列表
- `superadmin_bypass_allowlist`:超级管理员是否可在私聊中绕过 `allowed_private_ids`(仅影响私聊收发;群聊仍严格按 `allowed_group_ids`)
- 规则:只要 `allowed_group_ids` 或 `allowed_private_ids` 任一非空,就会启用限制模式;未在白名单内的群/私聊消息将被直接忽略,且所有消息发送也会被拦截(包括工具调用与定时任务)。
- **模型配置**:`[models.chat]` / `[models.vision]` / `[models.agent]` / `[models.security]`
- **模型配置**:`[models.chat]` / `[models.vision]` / `[models.agent]` / `[models.security]` / `[models.inflight_summary]`
- `api_url`:OpenAI 兼容 **base URL**(如 `https://api.openai.com/v1` / `http://127.0.0.1:8000/v1`)
- `models.security.enabled`:是否启用安全模型检测(默认开启)
- `queue_interval_seconds`:队列发车间隔(秒),每个模型独立生效
- `models.inflight_summary`:并发防重的“进行中摘要”模型(可选);当 `api_url/api_key/model_name` 任一缺失时,会自动回退到 `models.chat`
- DeepSeek Thinking + Tool Calls:若使用 `deepseek-reasoner` 或 `deepseek-chat` + `thinking={"type":"enabled"}` 且启用了工具调用,建议启用 `deepseek_new_cot_support`
- **日志配置**:`[logging]`
- `tty_enabled`:是否输出到终端 TTY(默认 `false`);关闭后仅写入日志文件
- **功能开关(可选)**:`[features]`
- `nagaagent_mode_enabled`:是否启用 NagaAgent 模式(开启后使用 `res/prompts/undefined_nagaagent.xml` 并暴露相关 Agent;关闭时使用 `res/prompts/undefined.xml` 并隐藏/禁用相关 Agent)
- `inflight_pre_register_enabled`:是否预注册进行中占位(默认 `true`)。启用后在首轮前预占位,防止重复执行
- `inflight_summary_enabled`:是否生成进行中任务摘要(默认 `false`)。启用后会调用模型生成动作摘要,需要额外 API 调用
- **彩蛋(可选)**:`[easter_egg]`
- `keyword_reply_enabled`:是否启用群聊关键词自动回复(如“心理委员”,默认关闭)
- **Token 统计归档**:`[token_usage]`(默认 5MB,<=0 禁用)
Expand All @@ -501,6 +506,9 @@ uv run Undefined-webui
- `oversize_strategy`:超限策略(`downgrade`=降低清晰度重试, `info`=发送封面+标题+简介)
- `auto_extract_group_ids` / `auto_extract_private_ids`:自动提取功能白名单(空=跟随全局 access)
- 系统依赖:需安装 `ffmpeg`
- **消息工具(单文件发送)**:`[messages]`
- `send_text_file_max_size_kb`:`messages.send_text_file` 单文件文本发送大小上限(KB),默认 `512`(`0.5MB`)
- 建议:单文件、轻量任务优先用 `messages.send_text_file`;多文件工程或需要执行验证/打包交付优先用 `code_delivery_agent`
- **代理设置(可选)**:`[proxy]`
- **WebUI**:`[webui]`(默认 `127.0.0.1:8787`,密码默认 `changeme`,启动 `uv run Undefined-webui`)

Expand All @@ -515,9 +523,30 @@ WebUI 支持:配置分组表单快速编辑、Diff 预览、日志尾部查看
#### 配置热更新说明

- 默认自动热更新:修改 `config.toml` 后,配置会自动生效
- 需重启生效的项(黑名单):`log_level`、`logging.file_path`、`logging.max_size_mb`、`logging.backup_count`、`onebot.ws_url`、`onebot.token`、`webui.url`、`webui.port`、`webui.password`
- 需重启生效的项(黑名单):`log_level`、`logging.file_path`、`logging.max_size_mb`、`logging.backup_count`、`logging.tty_enabled`、`onebot.ws_url`、`onebot.token`、`webui.url`、`webui.port`、`webui.password`
- 模型发车节奏:`models.*.queue_interval_seconds` 支持热更新并立即生效

#### 防重复执行机制(进行中摘要)

- 目标:降低并发场景下同一任务被重复执行(例如"写个 X"后立刻"写快点/它可以吗")
- 机制:
- **预注册占位**:对私聊和 `@机器人/拍一拍` 触发的会话,首轮模型调用前预注册"进行中任务"占位
- **摘要生成**(可选):异步调用模型生成动作摘要(如"正在搜索信息"),丰富进行中提示
- 后续请求会在系统上下文注入 `【进行中的任务】`,引导模型走"轻量回复 + end"而非重跑业务 Agent
- 首轮若仅调用 `end`,占位会立即清除
- 配置:
- 预注册开关:`[features].inflight_pre_register_enabled`(默认 `true`,防止重复执行)
- 摘要开关:`[features].inflight_summary_enabled`(默认 `false`,需要额外 API 调用)
- 摘要模型:`[models.inflight_summary]`(可选,缺省自动回退 `models.chat`)
- 格式示例:
- 预注册(pending):`[2024-01-01T12:00:00+08:00] [group:测试群(123456)] 正在处理消息:"帮我搜索天气"`
- 摘要就绪(ready):`[2024-01-01T12:00:00+08:00] [group:测试群(123456)] 正在处理消息:"帮我搜索天气"(正在调用天气查询工具)`
- 观测日志关键字:
- `首轮前预占位`
- `注入进行中任务`
- `首轮仅end,已清理占位`
- `已投递摘要生成`

#### 会话白名单示例

把机器人限定在 2 个群 + 1 个私聊(最常见的“安全上车”配置):
Expand Down Expand Up @@ -611,8 +640,14 @@ Undefined 支持 **MCP (Model Context Protocol)** 协议,可以连接外部 MC
/addadmin <QQ> # 添加管理员(仅超级管理员)
/rmadmin <QQ> # 移除管理员
/bugfix <QQ> # 生成指定用户的 Bug 修复报告
/stats [时间范围] # Token 使用统计 + AI 分析(如 7d/30d/1w/1m)
```

`/stats` 说明:

- 默认统计最近 7 天,参数范围会自动钳制在 1-365 天
- 会生成图表并附带 AI 分析;若分析超时,会先发送图表和汇总,再给出超时提示

## 扩展与开发

Undefined 欢迎开发者参与共建!
Expand All @@ -638,7 +673,7 @@ src/Undefined/

请参考 [src/Undefined/skills/README.md](src/Undefined/skills/README.md) 了解如何编写新的工具和 Agent。

**Agent 互调用功能**:查看 [docs/agent-calling.md](docs/agent-calling.md) 了解如何让 Agent 之间相互调用,实现复杂的多 Agent 协作场景
**Agent 互调用与主工具共享**:查看 [docs/agent-calling.md](docs/agent-calling.md) 了解如何让 Agent 之间相互调用,以及如何将 `skills/tools` 下的主工具按白名单暴露给 Agent

### 开发自检

Expand Down
71 changes: 65 additions & 6 deletions config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,39 @@ thinking_include_budget = true
# en: Thinking tool-call compatibility: pass back reasoning_content in multi-turn tool calls to avoid 400 errors from some models.
thinking_tool_call_compat = false

# zh: 进行中任务摘要模型配置(可选,用于并发真空期的“处理中摘要”)。
# en: Inflight summary model config (optional, used to generate in-progress task summaries).
# zh: 当 api_url/api_key/model_name 任一为空时,自动回退到 [models.chat]。
# en: Falls back to [models.chat] when api_url/api_key/model_name is missing.
[models.inflight_summary]
# zh: OpenAI-compatible 基址 URL(可选,留空则回退 chat)。
# en: OpenAI-compatible base URL (optional; empty means fallback to chat).
api_url = ""
# zh: 模型 API Key(可选,留空则回退 chat)。
# en: API key (optional; empty means fallback to chat).
api_key = ""
# zh: 模型名称(可选,留空则回退 chat)。
# en: Model name (optional; empty means fallback to chat).
model_name = ""
# zh: 最大生成 tokens(可选,默认 128)。
# en: Max generation tokens (optional, default 128).
max_tokens = 128
# zh: 队列发车间隔(秒,可选,默认 1.5)。
# en: Queue interval in seconds (optional, default 1.5).
queue_interval_seconds = 1.5
# zh: 是否启用 thinking(可选,默认 false)。
# en: Enable thinking (optional, default false).
thinking_enabled = false
# zh: thinking 预算 tokens(可选,默认 0)。
# en: Thinking budget tokens (optional, default 0).
thinking_budget_tokens = 0
# zh: 是否在请求中发送 budget_tokens(可选,默认 false)。
# en: Include budget_tokens in request (optional, default false).
thinking_include_budget = false
# zh: 思维链工具调用兼容(可选,默认 false)。
# en: Thinking tool-call compatibility (optional, default false).
thinking_tool_call_compat = false

# zh: 日志配置。
# en: Logging settings.
[logging]
Expand All @@ -195,6 +228,9 @@ max_size_mb = 10
# zh: 保留日志文件数量。
# en: Log backup count.
backup_count = 5
# zh: 是否输出到终端 TTY(默认关闭,避免后台运行时终端阻塞)。
# en: Enable logging to terminal TTY (default: off, prevents blocking in background runs).
tty_enabled = false
# zh: 是否在日志中输出思维链(默认开启)。
# en: Log thinking output (default: on).
log_thinking = true
Expand All @@ -220,8 +256,8 @@ sanitize_verbose = false
# en: Description preview length in logs.
description_preview_len = 160

# zh: 功能开关(默认建议保持关闭)
# en: Feature flags (recommended to keep disabled by default).
# zh: 功能开关。
# en: Feature flags.
[features]
# zh: 是否启用 NagaAgent 模式:
# zh: - true: 使用 `res/prompts/undefined_nagaagent.xml`,并向模型暴露/允许调用相关 Agent
Expand All @@ -230,6 +266,22 @@ description_preview_len = 160
# en: - true: use `res/prompts/undefined_nagaagent.xml` and expose related agents
# en: - false: use `res/prompts/undefined.xml` and hide/disable related agents
nagaagent_mode_enabled = false
# zh: 是否启用“进行中任务摘要”防重机制。
# zh: 是否预注册进行中占位(防止重复执行)
# zh: - true: 启用(默认),在首轮前预占位
# zh: - false: 关闭,不预注册占位
# en: Enable inflight task pre-registration (prevent duplicate execution)
# en: - true: enable (default), pre-register before first round
# en: - false: disable, no pre-registration
inflight_pre_register_enabled = true

# zh: 是否生成进行中任务摘要(需要额外 API 调用)
# zh: - true: 启用,异步生成动作摘要
# zh: - false: 关闭(默认),不生成摘要
# en: Enable inflight task summary generation (requires additional API calls)
# en: - true: enable, generate action summary asynchronously
# en: - false: disable (default), no summary generation
inflight_summary_enabled = false

# zh: 彩蛋功能(可选)。
# en: Easter egg features (optional)
Expand Down Expand Up @@ -311,8 +363,8 @@ xxapi_base_url = "https://v2.xxapi.cn"
# zh: 星之阁 API 基础地址。
# en: Xingzhige API base URL.
xingzhige_base_url = "https://api.xingzhige.com"
# zh: JKYAI API 基础地址。
# en: JKYAI API base URL.
# zh: JKYAI API 基础地址。(已弃用,不必填写)
# en: JKYAI API base URL.(this field is no longer in use and does not need to be filled in)
jkyai_base_url = "https://api.jkyai.top"
# zh: 心知天气 API 基础地址。
# en: Seniverse API base URL.
Expand Down Expand Up @@ -355,14 +407,21 @@ archive_prune_mode = "delete"
# en: MCP config file path (relative to the working directory).
config_path = "config/mcp.json"

# zh: 消息工具配置。
# en: Message tool settings.
[messages]
# zh: messages.send_text_file 单文件文本发送大小上限(KB)。默认 512KB(0.5MB)。
# en: Size limit for messages.send_text_file single-text-file uploads (KB). Default 512KB (0.5MB).
send_text_file_max_size_kb = 512

# zh: Bilibili 视频自动提取配置。
# en: Bilibili video auto-extraction settings.
[bilibili]
# zh: 是否启用自动提取(检测到B站视频链接/BV号时自动下载并发送)。
# en: Enable auto-extraction (auto-download and send when Bilibili video links/BV IDs are detected).
auto_extract_enabled = false
# zh: B站账号完整 Cookie 字符串(推荐,至少包含 SESSDATA;用于更稳定地通过风控)。
# en: Full Bilibili Cookie string (recommended, should include SESSDATA for better anti-bot pass rate).
# zh: B站账号完整 Cookie 字符串(必须粘贴浏览器中的完整内容,不要只填 SESSDATA;建议至少包含 SESSDATA + buvid3 + buvid4,用于通过风控与 WBI 搜索)。
# en: Full Bilibili Cookie string (paste the complete browser cookie; do not provide SESSDATA only. Recommended to include at least SESSDATA + buvid3 + buvid4 for anti-bot checks and WBI search).
cookie = ""
# zh: 首选清晰度: 80=1080P, 64=720P, 32=480P。
# en: Preferred quality: 80=1080P, 64=720P, 32=480P.
Expand Down
4 changes: 4 additions & 0 deletions config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
1. 复制 `config.toml.example` 为 `config.toml` 并填入实际参数
2. 如需 MCP,复制 `config/mcp.json.example` 为 `config/mcp.json`,并在 `config.toml` 中配置 `[mcp].config_path`

推荐关注的新增配置:
- `[features].inflight_summary_enabled`:并发防重摘要总开关(默认 `true`)
- `[models.inflight_summary]`:进行中摘要模型(可选);未完整配置时自动回退 `models.chat`

注意事项:
- `config.local.json` 为运行时自动生成文件,请勿提交
- 请妥善保护日志路径、Token 等敏感信息
24 changes: 24 additions & 0 deletions docs/agent-calling.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,30 @@ EOF
}
```

### 4. 让 `skills/tools` 下的主工具对 Agent 可见

除了 Agent 互调用外,也可以把主工具按白名单暴露给 Agent,避免在每个 Agent 下重复复制工具目录。

在主工具目录下添加 `callable.json`:

```json
{
"enabled": true,
"allowed_callers": ["*"]
}
```

文件位置:

```
src/Undefined/skills/tools/{tool_name}/callable.json
```

规则:
- 不存在 `callable.json`:仅主 AI 可调用该工具(默认行为)
- `enabled: true` + `allowed_callers`:对应 Agent 可调用
- 若 Agent 本地 `tools/` 下存在同名工具:本地优先,共享主工具会被跳过

## 配置文件详解

### 文件位置
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ dependencies = [
"mdit-py-plugins>=0.5.0",
"python-markdown-math>=0.9",
"linkify-it-py>=2.0.3",
"lunar-python>=1.4.8",
"pymdown-extensions>=10.20",
"playwright>=1.57.0",
"aiohttp>=3.13.2",
Expand Down
5 changes: 5 additions & 0 deletions res/prompts/generate_title.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
请根据以下 Bug 修复分析报告,生成一个简短、准确的标题(不超过 20 字),用于 FAQ 索引。
只返回标题文本,不要包含任何前缀或引号。

分析报告:
{summary}
3 changes: 3 additions & 0 deletions res/prompts/inflight_summary_system.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
你是任务状态摘要器。
请输出一句极简中文短语(不超过20字),用于描述该任务当前处理动作。
禁止解释、禁止换行、禁止时间承诺。
5 changes: 5 additions & 0 deletions res/prompts/inflight_summary_user.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
会话类型: {location_type}
会话名称: {location_name}
会话ID: {location_id}
正在处理消息: {source_message}
仅返回一个动作短语,例如:已开始生成首版
Loading