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
5 changes: 5 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ uv run playwright install # 页面截图等能力依赖的浏览器运行
uv run Undefined-webui # 启动 Management-first WebUI(推荐入口)
uv run Undefined # 直接启动 Bot

# WebUI 自动启动 Bot
# 配置 [webui].autostart_bot = true 后,运行 uv run Undefined-webui 会自动拉起 bot 进程
# 默认为 false,保持传统手动启动行为
# 注意:该配置仅在 WebUI 启动时生效,运行时修改需重启 WebUI

# 代码质量(提交前必须全部通过)
uv run ruff format .
uv run ruff check .
Expand Down
3 changes: 3 additions & 0 deletions config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -1234,6 +1234,9 @@ port = 8787
# zh: WebUI 密码(首次启动必须修改默认值;默认密码无法登录)。
# en: WebUI password (must be changed on first run; default password cannot be used to log in).
password = "changeme"
# zh: WebUI 启动时是否自动启动机器人进程。
# en: Auto-start bot when WebUI starts.
autostart_bot = false

# zh: 主进程 Runtime API(供 WebUI/外部系统读取探针、记忆检索、AI Chat 使用)。
# en: Runtime API in the main process (for WebUI/external integrations: probes, memory queries, AI chat).
Expand Down
7 changes: 5 additions & 2 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -840,11 +840,13 @@ Prompt caching 补充:
| `url` | `127.0.0.1` | WebUI 监听地址 |
| `port` | `8787` | WebUI 端口(1..65535) |
| `password` | `changeme` | WebUI 登录密码 |
| `autostart_bot` | `false` | WebUI 启动时是否自动启动机器人进程 |

关键行为:
- 默认密码 `changeme` 禁止登录,必须先修改。
- 未配置或为空时,会回退默认密码并标记为“默认密码模式”。
- `webui.url/port/password` 修改需重启 WebUI 进程(机器人主进程中也属于重启生效类)。
- 未配置或为空时,会回退默认密码并标记为”默认密码模式”。
- `webui.url/port/password/autostart_bot` 修改需重启 WebUI 进程(机器人主进程中也属于重启生效类)。
- `autostart_bot=true` 时,运行 `uv run Undefined-webui` 会自动拉起 bot 进程,无需手动点击启动按钮;与 WebUI 更新重启后的自动恢复机制(`pending_bot_autostart` marker)互不冲突。

---

Expand Down Expand Up @@ -1029,6 +1031,7 @@ Prompt caching 补充:
- `webui.url`
- `webui.port`
- `webui.password`
- `webui.autostart_bot`
- `api.*`(`enabled/host/port/auth_key/openapi_enabled`)
- `memes.blob_dir`
- `memes.preview_dir`
Expand Down
12 changes: 12 additions & 0 deletions docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@ uv run Undefined-webui
>
> WebUI 功能详见 [WebUI 使用指南](webui-guide.md)。

#### 自动启动选项

若希望 WebUI 启动后自动拉起机器人进程,可在 `config.toml` 中设置:

```toml
[webui]
autostart_bot = true
```

这样运行 `uv run Undefined-webui` 时会自动启动 bot,无需手动操作。默认为 `false`。

### 6. 跨平台与资源路径(重要)

- **资源读取**:运行时会优先从运行目录加载同名 `res/...` / `img/...`(便于覆盖),若不存在再使用安装包自带资源;并提供仓库结构兜底查找,因此从任意目录启动也能正常加载提示词与资源文案。
Expand Down Expand Up @@ -149,6 +160,7 @@ Undefined-webui
>
> - 选择 `Undefined`:直接在终端运行机器人,修改 `config.toml` 后重启生效(或依赖热重载能力)。
> - 选择 `Undefined-webui`:启动后访问 WebUI(默认 `http://127.0.0.1:8787`,密码默认 `changeme`;**首次启动必须修改默认密码,默认密码不可登录**;可在 `config.toml` 的 `[webui]` 中修改),在 WebUI 中在线编辑/校验配置,并通过 WebUI 启动/停止机器人进程。
> - 若希望 `Undefined-webui` 启动后自动拉起机器人进程,可在 `config.toml` 的 `[webui]` 中设置 `autostart_bot = true`(默认 `false`)。

> `Undefined-webui` 会在检测到当前目录缺少 `config.toml` 时,自动从 `config.toml.example` 生成一份,便于直接在 WebUI 中修改。
> 提示:资源文件已随包发布,支持在非项目根目录启动;如需自定义内容,请参考上方源码部署的自定义指南。
Expand Down
1 change: 1 addition & 0 deletions docs/management-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ GET /api/v1/management/runtime/commands?scope=webui&q=help
- `GET runtime/chat/jobs/active`:`conversation_id` 可选。
- 校验:
- Runtime 会检查 `conversation_id` 是否存在。
- `POST runtime/chat` 在 `stream=false` 时也会创建并等待 Runtime WebChat job,运行期间受同一套全局 job 互斥保护。
- 删除历史时,如果仍有运行中或收尾落盘中的 job,会透传 `409`。
- 响应:
- `200` / `202`:聊天结果、历史页、job 快照或 active job。
Expand Down
5 changes: 3 additions & 2 deletions docs/openapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,8 @@ curl http://127.0.0.1:8788/openapi.json
}
```

- `stream = false` 保持同步响应
- 当 `stream = true` 时,Runtime 会创建 WebChat job。旧接口仍可返回 SSE,但 WebUI 默认使用 job 查询接口续接事件。
- `stream = false` 返回同步 JSON,但后端同样会创建 WebChat job 并等待其完成;运行期间会占用 WebChat 全局 job 互斥,删除会话、清空历史和启动其他 WebChat job 会返回 `409`
- 当 `stream = true` 时,Runtime 会创建 WebChat job 并通过旧接口返回 SSE;WebUI 默认使用 job 查询接口续接事件。
- `conversation_id` 可选;不传时使用兼容默认会话 `legacy-system-42`,传入不存在的会话 ID 时返回 `404`。
#### Event types

Expand Down Expand Up @@ -424,6 +424,7 @@ curl http://127.0.0.1:8788/openapi.json
### WebUI AI Chat Jobs

- `POST /api/v1/chat/jobs`:创建后台 job,Body 为 `{"message":"...","conversation_id":"..."}`,`conversation_id` 可选。
- WebChat job 在当前 Runtime 进程内全局单飞;如果已有任意 WebChat job 正在运行或收尾落盘,创建新 job 返回 `409`。兼容的非流式 `POST /api/v1/chat` 也走同一套 job 互斥,只是等待完成后返回同步结果。
- WebChat 前端粘贴或选择的附件会先被合并进 `message`:小图片使用 `CQ:image,file=base64://...`,普通文件使用 WebUI 管理代理的 `/api/runtime/chat/files` 缓存后生成 `CQ:file,id=...`;Runtime 侧沿用 `register_message_attachments()` 注册到 `webui` 附件作用域。
- WebChat 前端引用 AI 消息、选中文本或 HTML 预览中点选的元素时,不新增后端端点,也不写入单独附件;发送前会把待引用内容转换成 Markdown blockquote 并拼接到 `message` 前面,例如 `> 引用 AI:` / `> 引用 HTML 片段:`。后端只接收最终 `message` 字符串。
- `GET /api/v1/chat/jobs/active?conversation_id=<id>`:返回当前运行中的 WebChat job(没有则为 `null`)。不传时返回任意当前 WebChat job;传入时只在该 job 属于对应会话时返回。
Expand Down
2 changes: 2 additions & 0 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,8 @@ Undefined 提供了一套完整的可视化管理控制台,无需修改配置

WebUI 通过浏览器访问(默认地址 `http://127.0.0.1:8787`,默认密码 `changeme`,**首次启动必须在 `config.toml` 的 `[webui]` 中修改默认密码**)。如需通过手机或其他设备进行远程管理,可使用配套的多端控制台 App,详见 [《跨平台控制台 App》](app.md)。

> **自动启动 Bot**:WebUI 支持配置 `[webui].autostart_bot = true` 实现启动时自动拉起机器人进程,详见 [WebUI 使用指南](webui-guide.md)。

---

*如需查阅各模块的底层设计原理与 API 集成说明,请参阅本目录下的其余技术文档。*
18 changes: 17 additions & 1 deletion docs/webui-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ uv run Undefined-webui
url = "127.0.0.1" # 监听地址
port = 8787 # 端口
password = "changeme" # 密码(必须在首次登录时修改)
autostart_bot = false # 启动 WebUI 时是否自动启动 Bot(默认 false)
```

> 如需远程访问,将 `url` 改为 `0.0.0.0` 或实际 IP。
Expand Down Expand Up @@ -121,7 +122,7 @@ WebUI 内置的对话界面,直接与 Bot 的 AI 进行交互:

- 右侧会话抽屉支持多对话管理:新建对话、切换对话、重命名对话和删除对话。桌面端默认折叠,鼠标移到右侧触发区会自动展开;移动端默认只显示“对话”按钮,点击后展开会话列表,切换会话后自动收起。新建成功后会显示提示,并短暂高亮新会话。多对话只作用于 WebChat,不影响 QQ 私聊 / 群聊历史。每个会话在后端保存为 `data/webchat/conversations/<conversation_id>.json`,删除对话会删除对应 JSON 文件;如果仍有 WebChat job 运行或正在收尾落盘,删除和清空会被拒绝。
- WebChat 的 AI 视角始终是同一个虚拟私聊用户 `system#42`,权限仍为 `superadmin`。切换 WebUI 会话只切换后端提供给 AI 的当前 WebChat 历史,不改变 `user_id`、`sender_id` 或身份提示,因此 AI 不会把多个 WebUI 会话看成不同真实用户。
- 输入框开头输入 `/` 时会从后端 `/api/v1/commands?scope=webui` 获取当前可用斜杠命令并在输入框上方展开补全面板。面板按命令名、别名、说明和用法即时筛选,支持点击选择,也支持方向键选择、`Enter` / `Tab` 填入;直接手打 `/faq `、`/changelog ` 或 alias `/cl ` 这类复合命令后,会切换为子命令补全并显示具体用法。命令数据尚未返回时面板显示正在加载可用命令”,不会提前显示未找到匹配命令”;输入 `/h ` 这类已命中 alias 但命令本身没有声明子命令的内容时,会显示命令帮助块,包含说明、用法、示例和别名,例如 `/h [命令名] [-t]`,便于继续补参数;只有命令或子命令确实没有匹配项时才显示无匹配提示。命令清单按 WebChat 的虚拟私聊执行身份过滤,因此不会提示当前 WebUI 会话实际不可用的命令。
- 输入框开头输入 `/` 时会从后端 `/api/v1/commands?scope=webui` 获取当前可用斜杠命令并在输入框上方展开补全面板。面板按命令名、别名、说明和用法即时筛选,支持点击选择,也支持方向键选择、`Enter` / `Tab` 填入;直接手打 `/faq`、`/changelog` 或 alias `/cl` 这类复合命令后(命令末尾需带空格),会切换为子命令补全并显示具体用法。命令数据尚未返回时面板显示正在加载可用命令”,不会提前显示未找到匹配命令”;输入 `/h` 这类已命中 alias 但命令本身没有声明子命令的内容时(末尾带空格),会显示命令帮助块,包含说明、用法、示例和别名,例如 `/h [命令名] [-t]`,便于继续补参数;只有命令或子命令确实没有匹配项时才显示无匹配提示。命令清单按 WebChat 的虚拟私聊执行身份过滤,因此不会提示当前 WebUI 会话实际不可用的命令。
- 旧版 WebChat 历史会在首次打开时自动迁移到默认会话。迁移完成后会写入标记文件,之后不会重复迁移;即使删除该默认会话,也不会再从旧历史文件恢复。未选择会话的旧接口调用会按需创建一个空的默认会话以保持向后兼容。
- 会话标题先使用第一条用户消息的前若干字符作为临时标题;当会话已有首问和首答后,后端会使用 chat model 根据首问 + 首答生成正式标题。手动重命名的标题不会被自动生成覆盖;临时或生成失败的标题会在后续能处理时继续尝试。
- 支持文本、图片和文件消息。图片或文件可通过 `+` 选择,也可直接粘贴到输入框;粘贴只会加入待发送附件条,不会立即发送,点击发送或按 Enter 时才随同当前文本进入同一条 WebChat 消息。无待发送附件时输入框会占满可用宽度;添加附件后右侧预览轨道随数量平滑展开,图片显示缩略图,附件较多时输入框保持最小可用宽度并压缩预览卡片,避免输入区跳动。移动端会把引用和附件预览轨道放到输入框上方,保证正文输入和发送按钮不被挤压。
Expand Down Expand Up @@ -154,6 +155,21 @@ WebUI 首页(Landing Page)提供 Bot 的启停控制:

首页还会检测是否有可用更新(基于 Git),并提供更新 + 重启功能。

### 自动启动 Bot

若希望 WebUI 启动后自动拉起 bot 进程,可在 `config.toml` 中配置:

```toml
[webui]
autostart_bot = true
```

启用后,`uv run Undefined-webui` 会自动启动机器人,无需手动点击"启动 Bot"按钮。默认为 `false`。

**注意**:
- 该配置仅在 WebUI 启动时生效,运行时修改需重启 WebUI 才能应用。
- 与 WebUI 更新重启后的自动恢复机制(`pending_bot_autostart` marker)互不冲突,自动恢复优先级更高。

---

## 键盘快捷键
Expand Down
6 changes: 4 additions & 2 deletions src/Undefined/api/_openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,10 @@ def _build_openapi_spec(ctx: RuntimeAPIContext, request: web.Request) -> dict[st
"summary": "WebUI special private chat",
"description": (
"POST JSON {message, stream?, conversation_id?}. "
"stream=false runs synchronously; stream=true creates a "
"WebChat job and streams lifecycle events as SSE."
"stream=false waits for an internal WebChat job and "
"returns JSON; stream=true uses the same WebChat job "
"lifecycle and streams events as SSE. WebChat jobs are "
"process-local single-flight while running or finalizing."
),
}
},
Expand Down
2 changes: 2 additions & 0 deletions src/Undefined/api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ async def start(self) -> None:
logger.info("[RuntimeAPI] 已启动: %s", cfg.api.display_url)

async def stop(self) -> None:
await self._chat_job_manager.stop()

for task in self._background_tasks:
task.cancel()
if self._background_tasks:
Expand Down
Loading
Loading