Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 4 additions & 4 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ graph TB
T_Time["get_current_time<br/>获取当前时间"]
T_GetPicture["get_picture<br/>获取图片"]
T_GetUserInfo["get_user_info<br/>获取用户信息"]
T_ArxivPaper["arxiv_paper<br/>arXiv 论文发送"]
T_BilibiliVideo["bilibili_video<br/>B站视频下载发送"]
T_ArxivPaper["arxiv_paper<br/>arXiv 论文发送 / UID 获取"]
T_BilibiliVideo["bilibili_video<br/>B站视频下载发送 / UID 获取"]
end

subgraph Toolsets["工具集 (skills/toolsets/, 11大类)"]
Expand All @@ -115,7 +115,7 @@ graph TB
subgraph IntelligentAgents["智能体 Agents (skills/agents/, 7个)"]
A_Info["info_agent<br/>信息查询助手<br/>(18个工具)<br/>• weather_query<br/>• *hot 热搜<br/>• bilibili_*<br/>• arxiv_search<br/>• whois"]
A_Web["web_agent<br/>网络搜索助手<br/>(3个工具 + MCP)<br/>• web_search<br/>• crawl_webpage<br/>• Playwright MCP"]
A_File["file_analysis_agent<br/>文件分析助手<br/>(14个工具)<br/>• extract_* (PDF/Word/Excel/PPT)<br/>• analyze_code<br/>• analyze_multimodal"]
A_File["file_analysis_agent<br/>文件分析助手<br/>• extract_* (PDF/Word/Excel/PPT)<br/>• describe_pdf_page<br/>• analyze_code<br/>• analyze_multimodal"]
A_Naga["naga_code_analysis_agent<br/>NagaAgent 代码分析<br/>(7个工具)<br/>• read_file / glob<br/>• search_file_content"]
A_Self["undefined_self_code_agent<br/>Undefined 自身代码查阅<br/>(4个工具)<br/>• read_file / list_directory<br/>• glob / search_file_content"]
A_Entertainment["entertainment_agent<br/>娱乐助手<br/>(9个工具)<br/>• ai_draw_one<br/>• horoscope<br/>• video_random_recommend"]
Expand Down Expand Up @@ -877,7 +877,7 @@ description: 从 PDF 文件中提取文本和表格,填写表单。当用户
|-------|---------|---------|---------|
| **info_agent** | 信息查询助手 | 18个 | 天气查询、热搜榜单、网络检测、B站信息查询、arXiv 搜索等 |
| **web_agent** | 网络搜索助手 | 3个 + MCP | 网页搜索、爬虫、Playwright MCP |
| **file_analysis_agent** | 文件分析助手 | 14个 | PDF/Word/Excel/PPT解析、代码分析、多模态分析 |
| **file_analysis_agent** | 文件分析助手 | 多个 | PDF/Word/Excel/PPT解析、指定 PDF 页视觉分析、代码分析、多模态分析、arXiv/Bilibili UID 获取分析 |
| **naga_code_analysis_agent** | NagaAgent 代码分析 | 7个 | 代码库浏览、文件搜索、目录遍历 |
| **undefined_self_code_agent** | Undefined 自身代码查阅 | 4个 | 受限读取源码、测试、文档、资源、脚本与 App |
| **entertainment_agent** | 娱乐助手 | 9个 | AI 绘图、星座运势、小说搜索、随机视频推荐等 |
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
## v3.6.1 Agent 路由收敛、文件分析增强与发版脚本修复

本版本围绕 Agent 职责边界和文件分析链路做小版本收敛:把 arXiv 论文分析从独立 Agent 合并到通用文件分析 Agent,让论文、PDF 页面视觉分析和视频附件获取都走统一的附件 UID 语义;同时修复版本迭代脚本重写 Tauri 配置格式导致 pre-commit 失败的问题,保证后续版本号同步、lock 文件刷新和自动提交流程更稳定。

- 合并 arXiv 论文分析职责到文件分析链路。移除独立 `arxiv_analysis_agent`,`file_analysis_agent` 现在可通过 `arxiv_paper(output_mode=uid)` 获取论文 PDF 附件 UID,并结合 `extract_pdf` 与 `describe_pdf_page` 完成文本和指定页视觉分析。
- 扩展媒体工具的附件输出能力。`arxiv_paper` 与 `bilibili_video` 新增 `output_mode=uid` 调用方式,可把下载或提取结果登记为当前会话附件,供后续 Agent 直接引用和复用。
- 明确 Agent 职责边界。更新代码交付、文件分析、信息查询、娱乐、总结、Naga 代码分析、Undefined 自查与 Web Agent 的 intro / prompt,减少项目问题、通用搜索、文件理解和代码修改任务之间的误路由。
- 补齐文件分析视觉工具与测试。新增 `describe_pdf_page` 工具及回归测试,覆盖 PDF 指定页截图/视觉描述链路;同步更新 arXiv、B 站发送器和工具注册测试。
- 修复版本迭代脚本的 JSON 格式漂移。`scripts/bump_version.py` 更新 JSON manifest 时只替换顶层 `version` 字段,保留 Tauri 配置原有格式,避免 `--commit` 触发的 Biome 检查因 `targets` 数组被重排而失败;脚本文档与单元测试同步覆盖该行为。

---

## v3.6.0 原生 Chat、WebChat 多会话与运行时管理增强

本版本把 Undefined 的“管理控制台内聊天”扩展为一套更完整的跨端聊天与运行时管理体系:一边新增面向桌面端和 Android 的原生 Chat 客户端,一边把 WebUI WebChat 升级为可长期使用的多会话工作台;底层则补齐 Runtime / Management API、任务续接、附件、命令、定时任务和发布构建能力。围绕这些入口,v3.6.0 也整理了 Agent 路由、认知记忆、附件标签和工程验证,让 WebUI、原生客户端和 QQ 侧共享更一致的运行时语义。
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@
- **MCP 协议支持**:支持通过 MCP (Model Context Protocol) 连接外部工具和数据源,扩展 AI 能力。
- **Agent 私有 MCP**:可为单个 agent 提供独立 MCP 配置,按调用即时加载并释放,工具仅对该 agent 可见。
- **Anthropic Skills**:支持 Anthropic Agent Skills(SKILL.md 格式),遵循 agentskills.io 开放标准,提供领域知识注入能力。
- **Bilibili 视频提取**:自动检测消息中的 B 站视频链接/BV 号/小程序分享,下载 1080p 视频并通过 QQ 发送;同时提供 AI 工具调用入口
- **arXiv 论文提取与搜索**:自动检测消息中的 arXiv 链接/标识并发送论文信息与 PDF;同时提供 `arxiv_paper` 发送工具和 `arxiv_search` 检索工具
- **Bilibili 视频提取与分析**:自动检测消息中的 B 站视频链接/BV 号/小程序分享,下载视频并通过 QQ 合并转发;`bilibili_video` 也可只返回附件 UID,供 `file_analysis_agent` 做视频内容分析
- **arXiv 论文提取、搜索与分析**:自动检测消息中的 arXiv 链接/标识并发送论文信息与 PDF;`arxiv_paper` 也可只返回 PDF 附件 UID,供 `file_analysis_agent` 做文本提取或指定页视觉分析;`arxiv_search` 负责论文检索
- **GitHub 仓库卡片**:自动检测 GitHub 仓库链接或 `owner/repo` 仓库 ID,获取 public 仓库信息并发送简洁图片卡片,展示头像、简介、stars、forks、issues、contributors 等概览。
- **自动处理管线**:Bilibili、arXiv、GitHub 等自动提取统一运行在 `skills/pipelines` 中,斜杠命令优先级更高;命令输入/输出会写入历史,非命令消息会并行检测和处理命中管线,结果通过统一发送层写入历史并登记附件 UID 后再进入 AI 回复。远程大附件超过 `[attachments].remote_download_max_size_mb` 时只登记 URL 引用,避免无界下载和缓存膨胀。
- **同 sender 短时消息合并**:默认开启。连续发的多条消息会合并到同一轮 AI 调用,AI 一次看到全部意图自行识别"独立请求/修正/打断";告别"画猫→改成狗"的重复触发与回复打架。主提示词按 batcher 的"当前输入批次"语义适配,关闭该功能可能导致连续补充/修正消息与提示词不匹配,需要单独适配。可选投机预发送让用户停顿时 LLM 提前开跑、新消息可在未发出回复前取消,进一步压低响应延迟。详见 [docs/message-batching.md](docs/message-batching.md)。
Expand Down
4 changes: 2 additions & 2 deletions apps/undefined-chat/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/undefined-chat/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "undefined-chat",
"private": true,
"version": "3.6.0",
"version": "3.6.1",
"type": "module",
"scripts": {
"tauri": "tauri",
Expand Down
2 changes: 1 addition & 1 deletion apps/undefined-chat/src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/undefined-chat/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "undefined_chat"
version = "3.6.0"
version = "3.6.1"
description = "Undefined native chat client"
authors = ["Undefined contributors"]
license = "MIT"
Expand Down
2 changes: 1 addition & 1 deletion apps/undefined-chat/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "Undefined Chat",
"version": "3.6.0",
"version": "3.6.1",
"identifier": "com.undefined.chat",
"build": {
"beforeDevCommand": "npm run dev",
Expand Down
4 changes: 2 additions & 2 deletions apps/undefined-console/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/undefined-console/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "undefined-console",
"private": true,
"version": "3.6.0",
"version": "3.6.1",
"type": "module",
"scripts": {
"tauri": "tauri",
Expand Down
2 changes: 1 addition & 1 deletion apps/undefined-console/src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/undefined-console/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "undefined_console"
version = "3.6.0"
version = "3.6.1"
description = "Undefined cross-platform management console"
authors = ["Undefined contributors"]
license = "MIT"
Expand Down
2 changes: 1 addition & 1 deletion apps/undefined-console/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "Undefined Console",
"version": "3.6.0",
"version": "3.6.1",
"identifier": "com.undefined.console",
"build": {
"beforeDevCommand": "npm run dev",
Expand Down
1 change: 1 addition & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,7 @@ Prompt caching 补充:
- 命中 `arxiv.org/abs/...`、`arxiv.org/pdf/...` 或 `arXiv:<id>` 时直接触发。
- 裸新式编号仅在消息中同时出现 `arxiv` 关键词时触发,避免误判普通数字串。
- PDF 下载或上传失败时不会额外发送失败提示,只保留论文信息消息。
- 自动提取仍默认发送论文信息与 PDF;若用户要求分析 arXiv 论文内容,`file_analysis_agent` 会通过 `arxiv_paper(output_mode=uid)` 获取 PDF 附件 UID 后再分析。

---

Expand Down
2 changes: 1 addition & 1 deletion docs/pipelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
3. 若消息命中斜杠命令,立即分发命令并结束本轮后续流程;命令输入和命令输出会写入历史,供后续 AI 轮次读取。
4. 未命中命令时,`PipelineRegistry` 并行调用所有已注册管线的 `detect(context)`。
5. 对所有命中的管线,并行调用对应的 `process(detection, context)`。
6. 管线发送出的信息、图片、文件或视频摘要通过统一发送器写入历史;本地图片、文件和视频会自动登记为当前会话可见的统一附件 UID,历史正文同样使用 `<attachment uid="..."/>` 作为可复用引用。
6. 管线发送出的信息、图片、文件或视频摘要通过统一发送器写入历史;本地图片、文件和视频会自动登记为当前会话可见的统一附件 UID,历史正文同样使用 `<attachment uid="..."/>` 作为可复用引用。需要“只获取 UID 不发送”的 arXiv/Bilibili 分析场景由 `file_analysis_agent` 调用共享主工具处理,不改变自动管线的发送行为。
7. 自动处理完成后,当前消息和管线输出一起进入 AI 自动回复/Agent 循环。

命中自动处理管线的消息会继续进入 AI 自动回复,让 AI 基于用户消息和刚写入的自动处理结果判断后续行为。
Expand Down
10 changes: 6 additions & 4 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,14 @@ Undefined 搭载了基于 ChromaDB 向量数据库的后台认知系统,无需

### `file_analysis_agent` — 文件分析助手

支持对代码、PDF、Word、Excel 等多种格式文件进行解析与分析。用户只需将文件发送至对话中即可
支持对代码、PDF、Word、Excel 等多种格式文件进行解析与分析。用户可以直接发送文件,也可以提供附件 UID、URL、arXiv ID/URL 或 Bilibili BV/AV/URL

**子工具**:`analyze_pdf`、`analyze_docx`、`analyze_xlsx`、`analyze_code`、`read_file`
**子工具**:`download_file`、`extract_pdf`、`describe_pdf_page`、`extract_docx`、`extract_xlsx`、`analyze_code`、`analyze_multimodal`

**示例:**
> *"请分析这份 PDF 文档,提取其中第三章的核心数据。"*
> *"请看 arXiv:2501.01234 的第 3-5 页图表,解释实验结论。"*
> *"分析这个 BV1xx411c7mD 视频里主要讲了什么。"*
> *"请检查这份 Python 代码,找出其中潜在的性能瓶颈。"*

---
Expand Down Expand Up @@ -283,8 +285,8 @@ Undefined 搭载了基于 ChromaDB 向量数据库的后台认知系统,无需
| `get_picture` | 获取指定类型的图片(二次元、壁纸、白丝、黑丝、JK、历史上的今天等 10 余种类别) |
| `qq_like` | 给指定 QQ 号的资料卡点赞(默认 10 次) |
| `python_interpreter` | 在隔离的 **Docker 容器**中执行 Python 代码,支持按需安装第三方库,可在执行后自动发送生成的文件(图片、CSV 等) |
| `bilibili_video` | 下载并发送哔哩哔哩视频(支持 BV 号、链接) |
| `arxiv_paper` | 下载并发送 arXiv 论文 PDF(支持 arXiv ID、链接) |
| `bilibili_video` | 下载并发送哔哩哔哩视频;也支持返回视频附件 UID 供文件分析(支持 BV 号、链接) |
| `arxiv_paper` | 下载并发送 arXiv 论文 PDF;也支持返回 PDF 附件 UID 供文件分析(支持 arXiv ID、链接) |
| `fetch_image_uid` | 将指定 URL 的图片下载并转换为系统内部 uid |
| `task_progress` | 向用户发送长任务的阶段性进度通知 |
| `changelog_query` | 查询系统内置版本更新日志 |
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "Undefined-bot"
version = "3.6.0"
version = "3.6.1"
description = "QQ bot platform with cognitive memory architecture and multi-agent Skills, via OneBot V11."
readme = "README.md"
authors = [
Expand Down
1 change: 1 addition & 0 deletions scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ uv run python scripts/bump_version.py 3.6.0 --commit
- `apps/undefined-chat/src-tauri/Cargo.lock`

非 dry-run 时脚本还会执行 `uv sync`,并分别在 Console / Chat 下执行 `npm install --package-lock-only` 与 `cargo update --workspace`,保证 lock 文件和 manifest 不漂移。
脚本更新 JSON manifest 时只替换顶层 `version` 字段,保留现有格式,避免 Tauri 配置与 Biome 格式化规则漂移。

### prepare_tauri_android.py — 生成后 Android 修补

Expand Down
28 changes: 26 additions & 2 deletions scripts/bump_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,30 @@ def _update_text_file(
return _write_if_changed(path, new_text, dry_run)


def _update_json_string_field(
path: Path,
field: str,
value: str,
dry_run: bool,
) -> bool:
text = path.read_text(encoding="utf-8")
data = cast(dict[str, Any], json.loads(text))
old_value = data.get(field)
if not isinstance(old_value, str):
raise ValueError(f"{path} 缺少字符串字段 {field}")
if old_value == value:
return False

field_pattern = re.compile(
rf'^(\s*"{re.escape(field)}"\s*:\s*)"[^"]*"',
re.MULTILINE,
)
new_text, count = field_pattern.subn(rf'\g<1>"{value}"', text, count=1)
if count == 0:
raise ValueError(f"{path} 未匹配到 {field} 字段")
return _write_if_changed(path, new_text, dry_run)


def _update_json_version(path: Path, version: str, dry_run: bool) -> bool:
data = cast(dict[str, Any], json.loads(path.read_text(encoding="utf-8")))
old_version = data.get("version")
Expand Down Expand Up @@ -159,7 +183,7 @@ def _update_native_app_versions(
updates: tuple[tuple[Path, bool], ...] = (
(
package_json,
_update_json_version(package_json, version, dry_run),
_update_json_string_field(package_json, "version", version, dry_run),
),
(
package_lock,
Expand All @@ -171,7 +195,7 @@ def _update_native_app_versions(
),
(
tauri_conf,
_update_json_version(tauri_conf, version, dry_run),
_update_json_string_field(tauri_conf, "version", version, dry_run),
),
(
cargo_lock,
Expand Down
2 changes: 1 addition & 1 deletion src/Undefined/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from .skills.registry import BaseRegistry as BaseRegistry
from .skills.tools import ToolRegistry as ToolRegistry

__version__ = "3.6.0"
__version__ = "3.6.1"

# symbol -> (module_path, attribute_name);首次访问时才 importlib 加载
_LAZY_IMPORTS: dict[str, tuple[str, str]] = {
Expand Down
Loading
Loading