oh-my-openagent 续跑注入 Fail-Safe:非可重试请求错误分类与停止再注入机制全解析
oh-my-openagent 续跑注入 Fail-Safe非可重试请求错误分类与停止再注入机制全解析【免费下载链接】oh-my-openagentOmO: Just type mass ulw keyword with your prompt. Now you are the master of graph engineering.项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-openagent本篇技术指南聚焦 oh-my-openagent 中todo-continuation-enforcerBoulder 续跑机制的一次关键加固当会话收到提供商明确标记为不可重试的请求类错误典型如 compaction 后tool_use缺少tool_result的 400时插件必须停止再次注入续跑指令否则每次session.idle都会重建完全相同的失败请求把会话永久卡死。读完本文你将掌握该 Fail-Safe 的分类器实现、三处注入闸门的协作方式、状态机语义以及 Red-Green 测试与 hermetic 沙箱验证的完整方法。该机制位于 packages/omo-opencode/src/hooks/todo-continuation-enforcer/对应的变更证据文档为 .omo/evidence/20260805-continuation-stop-unrecoverable/README.md关联 issue #6605同时缓解 #6303、#6528。一、背景Boulder 续跑机制与注入-重试死循环风险1.1 todo-continuation-enforcer 是什么todo-continuation-enforcer是 oh-my-openagent 在 opencode 插件侧实现的Boulder 续跑钩子当会话中仍有未完成的 todo 时它会在session.idle事件上触发向会话注入一段CONTINUATION_PROMPT驱动 Agent 继续处理剩余任务。其工作流依据 AGENTS.mdsession.idle → 会话不是 prometheus/compaction/planDEFAULT_SKIP_AGENTS → 近期无 abort 信号ABORT_WINDOW_MS 3s → todos 仍有未完成项todo.ts → 无后台任务运行 → 冷却期已过CONTINUATION_COOLDOWN_MS 5s按失败次数指数退避 → 失败次数 上限MAX_CONSECUTIVE_FAILURES 5 → 未在轮次边界暂停continuationBlockReason → 启动 2 秒倒计时 toast → 注入 CONTINUATION_PROMPT注入动作本身由 continuation-injection.ts 的injectContinuation()完成先通过ctx.client.session.todo()拉取最新 todo 列表再调用dispatchInternalPromptmode: async、queueBehavior: defer把一段系统指令 剩余任务清单作为内部消息送入会话。1.2 死循环风险从何而来问题出在注入 → 失败 → 再注入的闭环上。默认状态下一次session.idle注入失败后consecutiveFailures计数递增但冷却退避只会在时间轴上拉长重试间隔见 constants.ts 中CONTINUATION_COOLDOWN_MS 5_000、MAX_CONSECUTIVE_FAILURES 5、FAILURE_RESET_WINDOW_MS 5 * 60 * 1000。如果错误根源是请求本身形状非法那么无论重试多少次、间隔多久重建出的请求都会以同样的方式被提供商拒绝——会话被永久卡在一个必败的循环里这正是本次变更要消灭的 wedge 场景。二、事故模型compaction 后的 tool_use/tool_result 400真实事故的失败请求形状被完整捕获并固化在测试中handler.test.ts 与 unrecoverable-request-error.test.ts 使用同一 payload{ name: APIError, data: { message: messages.2: tool_use ids were found without tool_result blocks immediately after: toolu_01PCXjcagoMAca32awicQHce. Each tool_use block must have a corresponding tool_result block in the next message., statusCode: 400, isRetryable: false } }这是 Anthropic 对compaction 请求携带了没有配套tool_result的tool_use块的拒绝。关键点在于该错误由消息序列的历史状态决定不随重试而改变。只要会话消息中仍存在孤立的tool_use续跑注入就必然再次触发同一个 400。因此降低重试频率毫无意义唯一的正确动作是识别并停止。三、Fail-Safe 设计一个分类器 三处注入闸门本次变更新增 unrecoverable-request-error.ts并让handler.ts、idle-event.ts、continuation-injection.ts、non-idle-events.ts、types.ts协同工作形成识别 → 落状态 → 三处拦截的完整闭环。3.1 分类器isUnrecoverableRequestErrorconst UNRECOVERABLE_REQUEST_STATUS_CODES new Set([400, 422]) export function isUnrecoverableRequestError(error: unknown): boolean { if (!error) { return false } const statusCode getRuntimeFallbackStatusCode(error) if (statusCode undefined || !UNRECOVERABLE_REQUEST_STATUS_CODES.has(statusCode)) { return false } return getRuntimeFallbackRetryableSignal(error) false }见 unrecoverable-request-error.ts判定逻辑是双重条件与状态码必须是请求形状类错误——400 Bad Request或422 Unprocessable ContentUNRECOVERABLE_REQUEST_STATUS_CODES集合提供商必须显式给出isRetryable: false信号。getRuntimeFallbackStatusCode与getRuntimeFallbackRetryableSignal来自oh-my-opencode/model-core的 runtime-fallback-error-shape.ts负责从各种错误形态Error实例、{ data: { statusCode } }、{ error: { code } }等中稳健地抽取状态码与可重试信号因此分类器能直接作用于 opencode 事件系统抛出的任意形态错误对象。3.2 闸门一handler.ts的session.error分支事件路由器 handler.ts 的createTodoContinuationHandler()对session.error事件按错误类型分流三路判定互斥错误类型状态落点行为MessageAbortedError/AbortErrorwasCancelled true、abortDetectedAt now重置失败/停滞计数取消倒计时token limit 错误isTokenLimitErrortokenLimitDetected true取消倒计时后续 idle 跳过避免上下文溢出恶化非可重试请求错误isUnrecoverableRequestErrorunrecoverableErrorDetected true取消倒计时后续 idle 跳过extractSessionErrorInfohandler.ts负责把事件里的error归一化成{ name, message }兼容字符串、Error实例和嵌套data.error/data.error等深层结构而真正传给分类器的是原始props?.error确保分类基于未失真的完整 payload。3.3 闸门二idle-event.ts的 idle 决策门在 idle-event.ts 的handleSessionIdle()中unrecoverableErrorDetected被放在决策链的最前列紧随 todo 完成/恢复/取消等基础门之后if (state.unrecoverableErrorDetected) { log([${HOOK_NAME}] Skipped: non-retryable request error detected, re-injecting would rebuild the same request, { sessionID }) return }这确保了后续的 todo 拉取、agent 解析、倒计时启动等昂贵步骤根本不会执行——错误一旦落旗续跑循环即刻冻结。3.4 闸门三continuation-injection.ts的注入失败捕获注入路径本身也必须兜底即使session.error事件丢失或延迟dispatchInternalPrompt抛出的异常也要被同一分类器识别。在 continuation-injection.ts 的 catch 分支中} catch (error) { if (isTokenLimitError(errorObj)) { injectionState.tokenLimitDetected true } else if (isUnrecoverableRequestError(error)) { injectionState.unrecoverableErrorDetected true log([${HOOK_NAME}] Non-retryable request error detected during injection, stopping continuation, { sessionID }) } }这是评审期间补充的两条路径之一失败注入被重抛进自身的 catch从而在错误发生的第一现场落旗而不是依赖后续事件。失败计数与lastInjectedAt照常更新但状态标志让下一轮 idle 直接短路。3.5 事件时序兜底non-idle-events.ts的延迟分类另一条评审补充路径处理了一个精妙的时序问题当unrecoverableErrorDetected已置位后如果到达一个不带 parts 的message.updatedroleuser事件立刻把它当作用户打断分类会误清旗标。现在的做法是延迟分类non-idle-events.tsconst shouldDeferClassification state ! undefined (hasAcceptedContinuationLifecycle(state) || state.unrecoverableErrorDetected true) if (parts undefined state shouldDeferClassification messageID) { state.pendingUserMessageID messageID // 分类推迟到 message.part.updated 时依据 split part 的真实内容判定 return }等到message.part.updated携带具体 part 到达时non-idle-events.ts才根据 part 是否属于合成/内部文本isSyntheticOrInternalOnlyTextParts决定是忽略、暂停还是清除错误旗标。同时注意语义细节真实用户打断会重置unrecoverableErrorDetected false见 non-idle-events.ts 的pauseForGenuineUserInterruption——即用户亲自介入后会话可以重新进入正常续跑生命周期错误旗标不是永久封禁。3.6 状态模型SessionState.unrecoverableErrorDetected新旗标被加入 types.ts 的SessionState与既有标志并列export interface SessionState { // ... tokenLimitDetected?: boolean unrecoverableErrorDetected?: boolean // ... }它本质上是一个每会话级别的熔断位置位后handleSessionIdle、injectContinuation、countdown 启动三处全部跳过只有真实用户打断或会话被删除session.deleted触发cleanup才会清除。四、分类器边界刻意窄化与负面用例设计文档明确指出分类器刻意保持窄化——只有请求形状状态码 AND 提供商显式isRetryable: false才计为不可恢复避免误伤可重试的瞬时错误。unrecoverable-request-error.test.ts 用 6 组用例把边界钉死输入状态码retryable 信号判定理由compactiontool_use/tool_result400真实 payload400false不可恢复目标场景{ statusCode: 422, isRetryable: false }422false不可恢复同属请求形状错误overloadedstatusCode 529529true可恢复状态码不在集合内bare400无 retryable 信号400无可恢复未获提供商确认的死路不封禁rate limitedstatusCode 429429false可恢复429 是限流重试在时间上有效undefined/null/ 字符串 /MessageAbortedError——可恢复空值或非请求类错误一律放行值得强调的是两个反直觉的负面用例bare 400 不封禁仅凭状态码无法区分请求形状永远非法与瞬时参数错误必须等提供商给出isRetryable: false才下结论429 isRetryable: false不封禁429 属于速率语义即使本次标记不可重试退避后仍可能成功不应被熔断。五、验证策略Red-Green 测试与 hermetic 沙箱证据文档 .omo/evidence/20260805-continuation-stop-unrecoverable/README.md 记录了完整的三段式验证。5.1 Failing-first证明旧代码确实有缺陷将旧版源码origin/dev检出与新增测试配对运行确保测试不是空转$ git checkout origin/dev -- .../todo-continuation-enforcer/{handler,idle-event,types,non-idle-events}.ts $ bun test packages/omo-opencode/src/hooks/todo-continuation-enforcer/handler.test.ts expect(state.unrecoverableErrorDetected).toBe(true) Expected: true Received: undefined 3 pass 1 fail失败语义旧代码中非可重试 400 到达后SessionState原封不动下一次session.idle仍会重新注入续跑指令并重建相同失败请求——正是要修复的 wedge。unrecoverable-request-error.test.ts未纳入该次运行因为其被测模块在origin/dev上尚不存在。产物为unit-red-before-fix.txt。5.2 Green新实现全绿bun test packages/omo-opencode/src/hooks/todo-continuation-enforcer 142 pass 0 fail 244 expect() calls (17 files) bun run typecheck - exit 0 bun build packages/omo-opencode/src/index.ts --outdir dist --target bun --format esm --external zod - exit 0评审期间补齐两条路径后完整套件为145 pass / 0 fail。全部用例含handler.test.ts中非可重试 400 标记会话不可恢复并取消倒计时可重试 529 不标记等均使用真实捕获的生产 payload 驱动真实的createTodoContinuationHandler事件路由器而非手造的替身对象。5.3 Hermetic 沙箱真实 opencode 端到端验证构建后的插件被加载进真实opencode1.18.13 运行沙箱%TEMP%\omo-qa-sandbox3隔离了全部用户态环境XDG_DATA_HOME/XDG_CONFIG_HOME/XDG_STATE_HOME/XDG_CACHE_HOMETMP/TEMP用户主目录USERPROFILE/HOME/HOMEDRIVE/HOMEPATH仅拷贝auth.json作为最小凭据观测结果REAL_DB_SESSIONS_BEFORE2864 SANDBOX_DB_PATH...\omo-qa-sandbox3\data\opencode\opencode.db OPENCODE_EXIT0 REAL_DB_SESSIONS_AFTER2864 ISOLATIONOK HOST_CONFIG_REFERENCES0插件端到端驱动了一个真实会话写入todowrite工具调用、WAITING文本留下两个 pending todos会话正常退出OPENCODE_EXIT0转录中没有任何[todo-continuation-enforcer]skip 行说明健康会话完全不受新分支影响host-config 泄漏扫描为 0真实~/.local/share/opencode/opencode.db的会话数前后不变2864 → 2864DB 隔离成立。产物为opencode-qa-plugin.log。5.4 为什么这套证据是充分的failing-first 证明新闸门在origin/dev上确实缺失回归被钉死测试不空洞判定逻辑由真实事件路由器 真实生产 payload 驱动hermetic 运行证明变更模块随构建插件发布、可在真实 opencode 中加载且不扰动健康会话——这正是本变更携带的回归风险点。六、已知局限与边界声明证据文档如实记录了三条未覆盖项理解它们有助于评估该 Fail-Safe 的适用前提沙箱内未复现一次真实的非可重试 400。触发它需要一个会拒绝请求形状的提供商免费沙箱模型返回的是 503 queue-full而产出原始 400 的生产卡死会话无法在全新 opencode 实例中重放。因此该分支的证明方式是用真实捕获的 payload 重放经过真实 handler而非在沙箱里让提供商真实拒绝一次。[todo-continuation-enforcer]idle 行不会出现在 CLIopencode run转录中——进程在 idle 驱动的续跑周期开始前就已退出所以健康会话无 skip 行的证据证明的是无回归而非 skip 分支实际触发。auth.json被复制进沙箱但未在任何产物中复现所有 artifact 均不含 token、API key 或 auth header凭证隔离与脱敏是验证流程的一部分。七、在本仓库中复现与延伸阅读复现本次变更的测试与构建# 运行 todo-continuation-enforcer 全量套件含 unrecoverable-request-error 与 handler 用例 bun test packages/omo-opencode/src/hooks/todo-continuation-enforcer # 单测分类器边界 bun test packages/omo-opencode/src/hooks/todo-continuation-enforcer/unrecoverable-request-error.test.ts # 类型检查与构建与证据文档中的 green 步骤一致 bun run typecheck bun build packages/omo-opencode/src/index.ts --outdir dist --target bun --format esm --external zod深入阅读建议按此顺序分类器本体unrecoverable-request-error.ts事件路由与错误分流handler.tsidle 决策门与注入兜底idle-event.ts、continuation-injection.ts时序兜底与用户打断语义non-idle-events.ts错误形态抽取工具runtime-fallback-error-shape.ts钩子整体定位与常量设计AGENTS.md、constants.ts变更证据全文.omo/evidence/20260805-continuation-stop-unrecoverable/README.md。总结本次 Fail-Safe 的核心工程结论是——对于提供商确认永远无法重试成功的请求形状错误正确的续跑策略不是再试一次而是识别并停下。通过400/422 显式isRetryable: false的窄化分类器、session.error/idle 决策门/注入 catch 三处协同落旗、partless 事件延迟分类的时序兜底以及 Red-Green 与 hermetic 沙箱的双重验证oh-my-openagent 让 todo 续跑机制在必败循环面前具备了可证明的熔断能力同时把误伤可重试瞬时错误的概率压到了最低。【免费下载链接】oh-my-openagentOmO: Just type mass ulw keyword with your prompt. Now you are the master of graph engineering.项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-openagent创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

七夕表白代码实战指南:微信/邮件/桌面/链接四类可落地方案

七夕表白代码实战指南:微信/邮件/桌面/链接四类可落地方案

1. 这不是“代码合集”,而是一套可落地的七夕情感表达系统你搜“七夕表白代码”时,刷到的往往是几十个零散HTML文件、几行Python打印语句、或者带音乐的网页弹窗——点开一看,要么报错,要么样式崩坏,要么根本没法发给对…

2026/9/20 15:21:05 阅读更多 →
@typespec/http-client-java 版本演进全解读:0.7.0 → 0.8.1 的关键能力、修复与 Java 客户端生成实践

@typespec/http-client-java 版本演进全解读:0.7.0 → 0.8.1 的关键能力、修复与 Java 客户端生成实践

typespec/http-client-java 版本演进全解读:0.7.0 → 0.8.1 的关键能力、修复与 Java 客户端生成实践 【免费下载链接】typespec 项目地址: https://gitcode.com/GitHub_Trending/ty/typespec typespec/http-client-java 是 TypeSpec 生态中负责从 TypeSpec…

2026/9/21 13:45:55 阅读更多 →
iPhone Duo双屏适配挑战:如何用Kuikly跨端框架从容应对

iPhone Duo双屏适配挑战:如何用Kuikly跨端框架从容应对

1. iPhone Duo的形态变化,先看它改变了什么今年行业内最热的话题之一,就是苹果双屏折叠设备的传闻——大家习惯叫它iPhone Duo。虽然苹果官方还没正式发布,但各路供应链消息、系统代码解析、设计专利都已经指向一个结论:新形态设备…

2026/9/20 16:01:16 阅读更多 →

最新新闻

CANN ops-transformer FlashAttn 性能建模:D=256 下基本块 (M, N) 的选择与 Cube Bound 达成分析

CANN ops-transformer FlashAttn 性能建模:D=256 下基本块 (M, N) 的选择与 Cube Bound 达成分析

CANN ops-transformer FlashAttn 性能建模:D256 下基本块 (M, N) 的选择与 Cube Bound 达成分析 【免费下载链接】ops-transformer 本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。 项目地址: https://gitcode.com/cann/ops-t…

2026/9/21 12:04:03 阅读更多 →
VSS横向扩展指南:如何把视频AI处理规模从单机扩展到生产级

VSS横向扩展指南:如何把视频AI处理规模从单机扩展到生产级

VSS横向扩展指南:如何把视频AI处理规模从单机扩展到生产级 【免费下载链接】video-search-and-summarization NVIDIA AI Blueprint for video search and summarization (VSS) is a GPU-accelerated reference architecture for building video analytics agents wi…

2026/9/21 12:02:56 阅读更多 →
MCP Python SDK 依赖注入实战:用 `Resolve` 让工具参数脱离模型幻觉

MCP Python SDK 依赖注入实战:用 `Resolve` 让工具参数脱离模型幻觉

MCP Python SDK 依赖注入实战:用 Resolve 让工具参数脱离模型幻觉 【免费下载链接】python-sdk The official Python SDK for Model Context Protocol servers and clients 项目地址: https://gitcode.com/gh_mirrors/pythonsd/python-sdk 在 MCP&#xff08…

2026/9/21 12:02:56 阅读更多 →
Foam for VS Code 深度指南:用 Markdown + Wikilinks 构建本地优先的个人知识库

Foam for VS Code 深度指南:用 Markdown + Wikilinks 构建本地优先的个人知识库

Foam for VS Code 深度指南:用 Markdown Wikilinks 构建本地优先的个人知识库 【免费下载链接】foam A personal knowledge management and sharing system for VSCode 项目地址: https://gitcode.com/gh_mirrors/fo/foam Foam 是一款运行在 VS Code 之内的…

2026/9/21 12:02:56 阅读更多 →
Nix 1.11 发布说明深度解读:确定性构建验证、Nix 表达式预取与沙箱命名统一

Nix 1.11 发布说明深度解读:确定性构建验证、Nix 表达式预取与沙箱命名统一

Nix 1.11 发布说明深度解读:确定性构建验证、Nix 表达式预取与沙箱命名统一 【免费下载链接】nix Nix, the purely functional package manager 项目地址: https://gitcode.com/gh_mirrors/ni/nix 导读 本文基于 Nix 官方发布说明 rl-1.11.md,系…

2026/9/21 12:01:54 阅读更多 →
Torchvision 内部代码同步脚本 fbcode_to_main_sync.sh 使用指南:将 fbsync 分支变更批量落地为开源 PR

Torchvision 内部代码同步脚本 fbcode_to_main_sync.sh 使用指南:将 fbsync 分支变更批量落地为开源 PR

计算机视觉深度学习图像处理数据集 【免费下载链接】vision Datasets, Transforms and Models specific to Computer Vision 项目地址: https://gitcode.com/gh_mirrors/vi/vision 点击查看 免费下载 本篇文章围绕 scripts/README.rst 所记载的唯一实用脚本 fbcode…

2026/9/21 12:01:54 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址: https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件(Full-featured Plugin)是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/21 4:51:05 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/19 23:01:36 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →