Skip to main content

create-rabiroute-agent-adapter

新增、改造或排障 RabiRoute Agent 端适配器时使用。覆盖 Runtime 所有权和启动独立性、会话找不到或串线、工具能力缺失、后端 agent adapter、独立 Agent Manager API、扫描/安装/登录/健康检查、RibiWebGUI 自动化配置、消息投递、诊断和验证;适用于 Codex runtime、Copilot CLI、Marvis、AstrBot、DSH、脚本、Webhook 或其他 Agent 处理端。

الانتقال إلى التثبيت

معلومات المصدر

المستودع
vb2250158/RabiRoute
آخر نشاط في المصدر
١٤ سبتمبر ٢٠٢٦ في ١٤:٠٦
لغة SKILL.md المكتشفة
الصينية
النجوم
٤٣٥
التفرعات
٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
3 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
create-rabiroute-agent-adapter
description
新增、改造或排障 RabiRoute Agent 端适配器时使用。覆盖 Runtime 所有权和启动独立性、会话找不到或串线、工具能力缺失、后端 agent adapter、独立 Agent Manager API、扫描/安装/登录/健康检查、RibiWebGUI 自动化配置、消息投递、诊断和验证;适用于 Codex runtime、Copilot CLI、Marvis、AstrBot、DSH、脚本、Webhook 或其他 Agent 处理端。
# 创建 RabiRoute Agent 端适配器 ## 目标 新增 Agent 端时,不只接上一条 `deliver(message)`。必须让用户能在 WebGUI 里尽量自动完成配置: 1. 自动发现安装位置、运行状态、登录状态、插件状态、项目目录和会话。 2. 如果有项目概念,先选 Agent 路径或服务地址,再选项目目录,最后选会话。 3. 如果设置了项目目录,会话列表必须能显示项目归属并用于消歧。Codex Desktop 下拉显示全部任务,选择任务后自动采用其 cwd;其他 Agent 可按项目过滤。没有项目概念就隐藏项目目录。 4. 能扫描的不要让用户手填;必须提供刷新、安装、打开下载页、登录、部署/更新插件、健康检查等动作入口。 5. 添加 Agent 端后必须在 WebGUI 展示“环境和依赖”清单:安装状态、登录状态、插件/扩展、Endpoint、项目/会话发现、下载或文档入口、缺失项和下一步动作。 6. 运行态要能解释“为什么不可用”,不能只给一个空输入框或沉默失败。 所有带会话概念的 Agent 端还必须满足以下 P0 合同,缺一项都不能标记为 `verified`: 1. 已保存的完整任务 ID 存在且 owner 记录未归档时,直接投递到该任务,不创建新任务。owner 保存的默认 cwd、标题或 SQLite `title` 都不能否定有效 ID;本次执行目录由当前 Route 或计划绑定单独提供。保存 ID 指向已归档任务时,真实投递或保存提交点幂等创建新任务并持久化新 ID;不查找或复用其它同名任务。扫描、刷新和失焦仍只报告归档状态。 2. 目标不存在时,先按 RabiPC Manager 保存的明确名称 + workspace 查找;存在一个或多个匹配时按 `updatedAt` 降序绑定唯一最新任务,只有最新时间并列时才要求用户选择;零匹配才幂等创建一个会话,再把真实消息投给新会话,并发、重试和索引延迟期间仍只能创建一次。允许提供用户显式点击的“自动初始化会话”:它必须先完成同一保存/解析事务,再通过唯一 owner 投递一条携带角色文件、记忆、计划和必读项的人格初始化消息。 3. 真实消息必须通过 Agent 桌面应用实际使用的 owner 接口执行,保证桌面端统一可见并沿用同一任务的模型、工具、权限和状态;不得用第二 Runtime 冒充。 4. 用户在 Rabi 设置中选择已有会话或输入新名称后,点击保存必须完成解析/创建并持久化新的名称、完整 ID 和 workspace。 5. 完整任务 ID 是任务身份;workspace 是每次投递的执行目录,名称用于显示和无 ID 查找。Agent/Desktop 改名、默认 cwd 不同或首投后 `title` 自动变化时继续同一 ID;用户在 Rabi 端明确输入新名称时,UI 先清空旧 ID,再按新名称和 workspace 查找/创建并保存新 ID。 6. 项目和会话扫描只允许在进入设置界面时自动执行一次,或由用户点击扫描/刷新按钮显式触发;禁止定时轮询、展开面板、输入、`blur`、保存或普通状态刷新持续扫描。 Codex 目前的产品基线是 Desktop owner:RabiRoute 从 Codex Desktop 左侧栏共用的 `session_index.jsonl.thread_name` 读取用户可见 `Name`,再按完整 ID 合并本地状态提供的 cwd、归档、时间和 owner/rollout 状态,以“完整 ID + 工作目录”稳定绑定,并通过 Desktop IPC 把真实消息交给 Codex/ChatGPT Desktop 当前任务。SQLite `threads.title` 可能是首条 prompt,不得用于下拉名称或同名查找。Desktop 必须在线;任务无法加载就失败,禁止启动备用执行 Runtime。 AstrBot 这类服务型 Agent 必须显示服务健康、认证状态和可选会话。当前 AstrBot 合同只允许绑定明确的 ChatUI 会话并调用 `/api/chat/send`;没有 `ASTRBOT_SESSION_ID` 时失败,不再部署或回退到 `rabiroute_agent` 插件。 先读 `../../docs/agent-adapter-standard-requirements.md` 和 `../../docs/agent-adapter-integration-lessons.md`。前者定义标准 Agent 端应达到的能力与验收合同;后者记录 Desktop IPC 未唤醒 owner、隔离 app-server 不实时/缺桌面工具,以及共享 4510 导致 Desktop `ECONNREFUSED` 的历史。涉及 Codex/Desktop、会话绑定或工具注册时,还必须读 `../../docs/codex-desktop-agent-acceptance.md`,不能跳过。 新增任何带 Runtime、会话、桌面可见性或工具注入的 Agent 端时,还必须读 [owner-first-design-gate.md](references/owner-first-design-gate.md),并在实现前完成其中的设计门。不要等实现失败后才补所有权说明。 ## 负一号关卡:冻结用户可观察合同 写探测、后端或 UI 前,先把需求改写成可验收事实: - 消息必须出现在哪里,多久可见,谁能看到运行状态和结果。 - 哪个 task/session owner 必须执行真实消息。 - 模型、工具、权限和审批由谁注入。 - Agent、宿主和 RabiRoute 缺席时各自应如何启动、失败和退出。 - 新建、续投、重名、失效 ID、active turn 分别是什么行为。 - 哪些行为明确禁止,例如第二执行 Runtime、模糊换会话、持久化修改宿主启动配置。 把它写成“要求 / 真源 / 验收证据 / 禁止替代”表。用户未确认前,不得为了让错误消失而改变可观察合同。协议无法满足时保持 `experimental` 并报告缺口,不得私自增加 fallback。 历史反复修改暴露了六类设计异味,看到任一项就停止实现并回到设计门: 1. 用连接成功、记录可读或构建通过代替用户界面中的真实结果。 2. 把同一个 session ID 误当成同一个 live owner、实时事件流和工具集合。 3. 用 fallback 掩盖 owner 未加载、身份错误或协议不完整。 4. 为追求“一个 Runtime”而让宿主依赖 RabiRoute 的端口、环境变量或进程。 5. 把本机交互式 Desktop 与远端无人值守 Agent 当成同一生命周期。 6. 在一个大改动里同时迁移 Runtime、UI、配置、打包和文档,导致测试只验证实现自洽。 一个 adapter 只能有一条真实消息执行路径。发现必须靠第二条路径才能“可用”时,先判断产品要求是否其实包含两种不同 adapter;拆分产品边界,不做模式切换。 ## 零号审查:所有权和启动独立性 写探测脚本或 UI 前,先列出:Agent、宿主、Runtime、Transport、Session、Tool 分别由谁拥有,谁启动、谁停止、故障会影响谁。没有这张清单就不实施。 硬性边界: - 外部 Agent/服务拥有自己的生命周期;RabiRoute 只能探测或通过已验证接口连接。 - 如果要求消息实时出现在某个 UI 并使用该 UI 注入的工具,这个 UI 的任务 owner 必须执行真实轮次;恢复相同 session ID 的第二个 Runtime 不等价。 - Codex Desktop 是 transport 的 owner 和健康条件;RabiRoute 只连接 IPC,不启动/停止 Desktop,也不提供 fallback。 - Adapter 只有在“创建空任务、恢复用户名称”等不执行真实 prompt 的元数据操作中,才可短暂拥有隔离子进程;完成后立即回收,不能成为 fallback。 - 不得从普通 adapter 配置写用户级环境变量、注册表、桌面启动参数或固定 WebSocket 地址。 - 不得让 Agent/Desktop 的冷启动依赖 Manager、Gateway、托盘或某个固定 RabiRoute 端口。 - “一个 Runtime”指一个实际消息 owner,不是把 Desktop 强制连接到 RabiRoute 拥有的共享端口。 - 对 Codex/ChatGPT Desktop,`127.0.0.1:4510` 属于 Desktop 自己的生命周期。禁止写入进程、用户或机器级 `CODEX_APP_SERVER_WS_URL`,禁止让 RabiRoute 监听/接管 4510,禁止为了投递关闭或重启 Desktop。必须实测 RabiRoute 停止时 Desktop 仍可启动,避免再次出现 `connect ECONNREFUSED 127.0.0.1:4510`。 开始改代码前必须完成两个基线检查: 1. RabiRoute 全部停止时,目标 Agent/Desktop 能单独冷启动。 2. 目标 Agent/Desktop 全部停止时,RabiRoute Manager 能启动,并对该 adapter 给出可行动状态。 任一项失败,先修所有权,不继续增加回退模式。 ## 统一能力模型 每个 Agent adapter 都要先声明自己支持哪些能力,再决定 UI 显示什么字段: ```ts type AgentAdapterCapability = { type: AgentAdapterType; label: string; maturity: "verified" | "experimental" | "stub"; requiresInstall: boolean; requiresAuth: boolean; hasAgentPath: boolean; hasServiceEndpoint: boolean; hasProject: boolean; hasSession: boolean; canListProjects: boolean; canListSessions: boolean; canFilterSessionsByProject: boolean; canDeployPlugin: boolean; canHealthCheck: boolean; }; ``` 能力模型是产品合同,不只是类型定义: - `verified`:本机或 CI 已验证扫描、配置、投递、失败诊断四条路径。 - `experimental`:代码存在,但没有完成端到端验证;WebGUI 必须显示“实验/未验证”提示。 - `stub`:只是占位或打开外部页面;不能默认启用,必须说明缺哪段能力。 - `hasProject=false` 时不要显示项目目录。 - `hasSession=false` 时不要显示会话输入框,要显示“该 Agent 无可选会话”。 - `canListSessions=false` 时不要伪装成下拉框;用说明和后续任务替代。 - `canFilterSessionsByProject=false` 且 `hasProject=true` 时,要显示项目/会话可能不一致的风险。 当前已有 Agent 的默认基线: | Agent | 默认等级 | 说明 | | --- | --- | --- | | Codex Desktop | `verified` | 只读发现 Desktop 任务;完整任务 ID 是任务身份,每次投递单独指定执行目录;通过 Desktop IPC 唤醒并向任务 owner start/steer,无 fallback。 | | Copilot CLI | `experimental` | 需要验证安装检测、登录、`-C` 项目目录、`--resume` 会话和 Windows 长 prompt 路径。 | | Marvis | `stub`/`experimental` | 目前更像打开 App/复制 prompt,不应宣称有可靠会话绑定或回传。 | | AstrBot | `experimental` | 只使用 ChatUI `/api/chat/send`;必须配置明确的 `ASTRBOT_SESSION_ID`,缺失时失败关闭。 | 新增或改造时,不要靠口头记忆这些等级;让 Manager scan/status API 返回 `maturity` 和 `warnings`,让 WebGUI 显示出来。 ## 先判断 Agent 类型 实现前先确认目标 Agent 属于哪类: - **Desktop owner 型**:用户可见任务、实时状态和工具由桌面任务 owner 持有,例如当前 Codex/ChatGPT Desktop。投递必须进入 owner,不能另起后台 Runtime。 - **Agent runtime 型**:有正式进程协议、会话列表和项目目录,但没有“必须实时进入现有桌面任务”的要求。 - **CLI 项目型**:有可执行文件、登录状态、`cwd` 或 workspace、session/resume 名称,例如 Copilot CLI。 - **服务/机器人框架型**:有 dashboard URL、插件、token/password、bot 实例、会话或通道,例如 AstrBot。 - **网页/桌面跳转型**:只能打开页面或 app、复制 prompt,通常没有可靠回传,例如 Marvis。 - **Webhook/script 型**:有 endpoint、命令、脚本路径、输出协议,可能没有会话。 不要为了统一 UI 强行显示不存在的字段。字段由能力决定。 ## 先摸清真实 API 做任何 Agent 端适配前,先用最小脚本或临时命令验证目标 Agent 的真实能力。不要先写 WebGUI,不要先设计配置表单。 必须按这个顺序探测: 1. **健康检查**:确认 Agent app / CLI / service 是否存在、能启动、能连接。 2. **认证检查**:确认是否需要 token、password、cookie、device code 或本机登录态。 3. **列出会话线程**:优先找 owner 的 API、CLI、IPC 或插件协议。Codex Desktop 允许只读状态数据库作为任务候选来源,但实际绑定成功必须由 Desktop owner 接受 IPC 投递来证明。 4. **列出项目或 workspace**:如果会话带 cwd/project/workspace,记录字段名和路径格式。 5. **创建会话线程**:如果 API 支持,创建一个测试会话,名称用公开占位,例如 `RabiRoute Smoke Test`。若需 bootstrap 子进程,只能创建空任务,不能携带真实测试 prompt。 6. **消息注入测试**:向新建会话发送一条测试消息。 7. **同会话重复注入测试**:向同一个会话再发送第二条测试消息,确认不会新建另一个会话线程。 8. **如果不能创建会话**:选择第一个可用会话线程,连续注入两条明确的测试消息。 9. **读取结果或状态**:能读回复就读回复;不能读回复也要确认消息已被目标 Agent 接收。 测试消息必须无害、可识别、可公开: ```text RabiRoute adapter smoke test. If you see this, reply with: RabiRoute injection OK. ``` 第二条消息必须带序号,用来确认同一会话是否支持重复发送: ```text RabiRoute adapter smoke test #2 in the same thread. Reply with: RabiRoute repeat injection OK. ``` 如果目标 Agent 是中文场景,也可以使用: ```text RabiRoute Agent 端适配烟测消息。如果你收到这条消息,请回复:RabiRoute 注入成功。 ``` 第二条中文测试消息: ```text RabiRoute Agent 端适配烟测消息 #2。请在同一个会话里回复:RabiRoute 重复注入成功。 ``` 探测结果要沉淀成一小段事实记录,至少包括: - 使用了哪个 API / CLI / 文件路径。 - 能否列会话。 - 会话字段有哪些:id、name、updatedAt、projectPath/cwd。 - 能否按项目目录筛选。 - 能否创建会话。 - 能否向指定会话注入消息。 - 能否向同一会话重复注入消息。 - 第二次注入后是否错误地创建了新会话。 - 注入后能否读取回复或确认接收。 - 失败点、错误原文摘要和下一步。 如果列会话、建会话或注入消息任何一步没有跑通,该 Agent 的 `maturity` 只能是 `experimental` 或 `stub`。在成功前,只允许提交探测代码、mock、诊断 UI 或明确标注未验证的入口;不要把它做成默认推荐 Agent。 不要用“看起来应该可以”代替真实探测。接口不清楚时,先写临时探测脚本,成功后再把逻辑迁入 Manager scan/status API 和正式 adapter。 ## 代码入口 新增一个 Agent 类型通常要改这些位置: - `src/agentAdapters/types.ts`:扩展 `AgentAdapterType`、`parseAgentAdapterType`。 - `src/agentAdapters/agentAdapter.ts`:把 type 映射到 `deliver(message)`。 - `src/agentAdapters/<name>Adapter.ts`:优先新增接口化 adapter;旧式模块只作为兼容。 - `src/agentAdapters/managerApi.ts` 或同目录按端拆分的 manager-facing 模块:实现扫描、状态、安装、登录、部署、打开外部应用等 Agent 专属逻辑。 - `src/manager.ts`:只扩展通用 `GatewayDefinition` 字段、env 注入、运行态 state 读取和 HTTP 路由接线;不要把 Agent 专属扫描/安装/登录/部署实现写进 manager。 - `ribiwebgui/src/types.ts`:同步 gateway 字段和扫描结果类型。 - `ribiwebgui/src/pages/RouteConfigPage.vue`:添加 Agent 卡片、参数面板、自动扫描、状态和动作按钮。 - `ribiwebgui/src/components/QuickSetupDialog.vue`:如果该 Agent 适合首次配置,也同步快速配置。 - `README.md`、`docs/configuration.md` 或示例:只补公开、安全、可复制的说明。 如果新增的是消息入口,不要用本 skill;消息入口走 `src/adapters/`。 ## Manager 模块化边界 `src/manager.ts` 是 Agent 端编排层,不是某个 Agent 的实现层。新增或改造 Agent 端时,遵守这个边界: - Agent 专属逻辑放在 `src/agentAdapters/`:安装/登录检测、Dashboard/API 探测、项目/会话扫描、受支持的外部安装动作、打开外部 app、scan payload 组装。不要保留已经删除的部署协议或兼容回退。 - `manager.ts` 只构造上下文 `ctx` 并接 HTTP API:`rootDir`、runtime 读取器、通用 HTTP 检查、通用安装路径 helper。会话发现优先使用 owner 的稳定协议;Codex Desktop 的状态数据库只允许只读,不能直接写或代替 owner 接受投递。 - 通用 runtime 管理、配置 normalize、env 注入和状态文件读取可以暂留 `manager.ts`;不要为了新增一个 Agent 把专属逻辑塞进 manager。 - 新模块不能 import `src/manager.ts`,也不能依赖 `ribiwebgui`、浏览器 `window/document` 或前端状态。 - `/api/scan/agents` 应调用 `scanAgentAdapters(ctx)` 或各 Agent scan 函数组合;旧平铺字段只作为兼容输出。 当前参考模块: - `src/agentAdapters/managerApi.ts`:Codex/Copilot/Marvis/AstrBot 的 manager-facing scan、status、login、open 等受支持动作。AstrBot 不再提供 adapter deploy 动作。 如果某个 Agent 后续变复杂,优先新增 `src/agentAdapters/<type>ManagerApi.ts` 并由 `managerApi.ts` 聚合,不要继续扩大 `src/manager.ts`。 ## UX 合同 Agent 参数面板的顺序固定按依赖关系走: 1. **Agent 路径 / 服务地址 / App ID / CLI 路径** 2. **项目目录 / workspace / bot 实例 / channel**(仅当该 Agent 有项目或工作区概念) 3. **会话 / thread / session / resume name**(必须受上一步筛选) 4. **认证、安装、部署、健康检查动作** 5. **运行时诊断** 不要让“会话”排在最前面。用户要先知道自己连的是哪个 Agent、哪个项目,然后才知道该选哪个会话。 Agent 卡片本身必须显示统一状态: - 名称和简短说明。 - 等级 chip:已验证 / 实验 / 占位。 - 连接 chip:未安装 / 未登录 / 未启动 / 已连接 / 插件缺失。 - 如果不是 `verified`,展开面板顶部显示一条短 warning,说明还没验证哪几段。 能自动化的字段使用控件,不用裸输入框: - 路径:`v-combobox` + 扫描按钮 + 最近配置 + 文件存在状态。 - URL:默认值 + 健康检查 + 打开 dashboard + 最近成功地址;可手填但不是唯一入口。 - 会话:`v-combobox` / `v-select`,来源于扫描 API;按 Agent 合同进行项目分组、过滤或全量展示。Codex Desktop 必须可访问全部任务。 - 安装:状态 chip + 安装按钮或下载链接;安装失败显示 stderr 摘要。 - 登录:状态 chip + 登录按钮;device code 或浏览器链接要清楚展示下一步。 - 插件:状态 chip + 部署/更新按钮 + 打开插件目录/插件页。 - 无会话概念:显示“该 Agent 无会话概念”,不要留一个空白会话输入框。 ## 扫描 API 要求 每个新 Agent 都要在 Manager 侧提供扫描/状态能力。可以先扩展 `/api/scan/agents`,复杂时新增: ```text GET /api/agents/<type>/scan GET /api/agents/<type>/status POST /api/agents/<type>/install POST /api/agents/<type>/login POST /api/agents/<type>/deploy-plugin ``` 实现时优先让 `src/agentAdapters/managerApi.ts` 或 `src/agentAdapters/<type>ManagerApi.ts` 暴露这些函数,再由 `manager.ts` 接线: ```ts scanAgentAdapters(ctx) scan<Type>Agent(ctx) test<Type>Login(ctx, request) get<Type>Status(ctx, request) deploy<Type>Plugin(ctx, request) open<Type>(ctx, request) ``` 返回 JSON shape 必须和 WebGUI 已消费的结构兼容。迁移旧逻辑时先接新模块再删除 manager 内旧实现,并运行 `npm run build`。 扫描结果至少表达这些信息: ```ts type AgentScanResult = { type: AgentAdapterType; label: string; maturity: "verified" | "experimental" | "stub"; installed: boolean; installCandidates?: Array<{ label: string; path?: string; url?: string }>; auth?: { required: boolean; loggedIn?: boolean; loginUrl?: string; message?: string }; endpoints?: Array<{ label: string; url: string; healthy?: boolean }>; projects?: Array<{ label: string; path: string; exists: boolean }>; sessions?: Array<{ id?: string; name: string; projectPath?: string; updatedAt?: string; userNamed?: boolean; }>; plugins?: Array<{ id: string; name: string; installed: boolean; version?: string; healthy?: boolean }>; warnings?: string[]; }; ``` 当前代码还是平铺的 `threadNames/cwdOptions/copilotSessions/copilotBins/marvisAppIds`;新增适配时可以兼容旧字段,但新能力优先按 Agent 分组,避免不同 Agent 的会话混在一起。 推荐返回结构: ```ts type AgentScanResponse = { agents: Record<AgentAdapterType, AgentScanResult>; legacy?: { threadNames?: string[]; cwdOptions?: string[]; copilotSessions?: Array<{ name: string; cwd?: string; userNamed?: boolean }>; copilotBins?: string[]; marvisAppIds?: string[]; }; }; ``` WebGUI 读取 `agents[type]` 优先;旧字段只作为迁移兼容。 ## 项目目录与会话筛选 如果 Agent 有项目目录或 workspace: 1. 扫描项目目录:从 Agent 会话记录、已有 gateway 配置、最近 workspace、仓库兄弟目录中收集。 2. 路径必须规范化后比较:处理大小写、斜杠、尾部分隔符、符号链接失败时保持原始值。 3. 默认按项目过滤或分组;Codex Desktop 是明确例外:显示全部任务的名称 + 最后时间,选择后自动采用该任务 `projectPath`,避免固定前 100 条或路径别名把任务藏掉。 4. 如果未选择目录,会话按项目分组或显示项目标签,不要让用户猜。 5. 选择会话时,如果该会话带 `projectPath`,回填项目目录;Codex 以任务自己的 cwd 为准。 6. 如果项目目录与会话项目不一致,显示 warning,不要静默投递。 会话身份必须遵守: - 下拉显示 `name + updatedAt`,内部 value 和持久化绑定使用 Agent 返回的完整 opaque ID。 - Codex 的 `name` 必须来自 Desktop 左侧栏共用的 `session_index.jsonl.thread_name`;SQLite 只按完整 ID 补充 cwd、归档、时间和 owner/rollout 定位。禁止使用 app-server `thread.name` 或 SQLite `threads.title` 覆盖侧栏 `Name`。 - 会话绑定同时持久化可见名称、完整 ID 和 workspace;完整 ID 决定任务身份,workspace 决定下一轮执行目录。名称、时间和任务保存的默认 cwd 是展示或运行元数据,不能让有效 ID 失效。 - 投递前必须通过实际 owner 的合同验证精确 ID,并校验规范化 cwd。Codex 还必须验证 Desktop IPC 及目标任务 owner。 - 统一 resolver 先读取有效 ID;ID 存在、cwd 匹配且未归档就精确绑定,不比较 owner 的可变标题。ID 已归档时,真实投递或保存提交点按旧 ID 隔离的幂等键创建新任务并更新绑定,不复用其它同名任务。ID 为空、非法或确实失效时走名称查找,零匹配才按用户输入的新名称创建;最新时间并列才要求选择。 - 扫描、刷新、输入和 `blur` 只能 lookup,禁止创建;保存/应用、第一条真实投递或用户显式点击“自动初始化会话”才是 create 提交点。 - 保存提交必须调用和真实投递相同的 resolver,成功前写回完整 ID、名称和 workspace;连续保存不得再次创建。 - create 必须按 `agentProfile + normalizedWorkspace + requestedName` single-flight;create 已返回但索引尚未刷新时,立即重试仍返回同一个 ID。 - 精确 ID 存在但 cwd 冲突时必须停止,禁止悄悄切到同名或最新会话。 - 用户不填写、不查看、不手改 UUID;ID 只能由扫描、创建或受控迁移产生。 - 列表超过默认页大小时必须提供分页/搜索或完整加载,不能固定截断后宣称“所有会话”。 - 名称和 workspace 匹配多个会话时必须按可解析的 `updatedAt` 降序选择唯一最新者,禁止依赖数据库返回顺序;只有最大时间并列或都无有效时间时才让用户选择。 没有项目概念的 Agent 不显示项目目录。只有服务地址/插件/频道概念的 Agent,用对应字段替代。 ## 安装、登录和插件检查 每个 Agent 都要有“可行动”的状态: - 未安装:显示检测来源,提供安装按钮或官方下载/文档链接。 - 未登录:显示登录方式;能自动启动登录就提供按钮,不能就打开登录页。 - 服务未启动:提供打开 dashboard、复制启动命令或打开安装目录。 - 插件缺失:提供部署/更新按钮,并显示部署目标路径。 - 权限不足:显示需要的权限名和配置位置。 不要只写“请设置环境变量”。如果确实需要 env,要在 UI 里显示变量名、当前是否缺失、哪里保存、是否需要重启 Manager。 ## 消息投递协议 `deliver(message: string)` 可以继续兼容纯文本,但新 Agent 应优先能接收结构化上下文。最少要保留这些信息: - 渲染后的正文 prompt。 - route kind、input adapter、output adapter/pipeline。 - 来源信息:群聊/私聊/Webhook/手动触发/语音转写。 - 角色信息:`agentRoleId`、`agentRolePath`、`agentRoleDir`。 - 上下文路径:日志、消息记录、附件或 transcript 路径。 - 期望输出:纯文本、QQ 草稿、JSON、语音短回复、Webhook payload 等。 如果目标 Agent 只能收纯文本,就把结构化字段渲染进 prompt;如果它有 HTTP/plugin API,就发送 JSON,并在 adapter 内做版本兼容。 工具能力与会话文本分开处理: - 当前轮次有哪些工具,以该 Runtime 实际注册的能力为准。 - 恢复同一个 session/thread 不代表另一个客户端注入的工具也会恢复。 - 提示词不能让未注册工具出现;缺工具时要返回明确能力错误和替代入口。 - 对 Codex,真实 prompt 必须由 Desktop 任务 owner 执行,才能沿用 Desktop 注入的工具和实时状态。 - 需要跨任务操作时,使用正式桥接 API(例如 `/api/agent/threads`);它的实际 `send` 仍须进入目标 owner。 - scan/status 应分别表达 transport、task owner 和 turn tools,不能只返回含糊的 `connected`。 正式 adapter 的第一条集成测试必须来自“先摸清真实 API”的探测结果: - 支持创建会话:测试创建会话,向同一个会话连续注入两条测试消息,并确认没有创建新会话。 - 不支持创建会话但能列会话:测试向第一个可用会话连续注入两条测试消息。 - 能列会话但不能稳定复用同一会话:不能标 `verified`,UI 要提示该 Agent 可能每次投递新开线程。 - 不能列会话但能投递到默认管线:测试默认管线注入,并在 UI 标明“无可选会话”。 - 只能打开外部页面或复制剪贴板:不能称为“线程消息注入”,只能标为 `stub` 或人工接力型 adapter。 ## 状态文件和诊断 每个 Agent 需要写自己的 state 文件到当前 route 的 `dataDir`,例如: ```json { "agentAdapterType": "astrbot", "monitorThreadId": "optional-session-id", "monitorThreadName": "optional-session-name", "monitorThreadSource": "http://127.0.0.1:6185", "bound": true, "notificationCount": 3, "lastNotificationAt": "2026-06-07T00:00:00.000Z", "lastNotificationError": null, "lastPromptPath": "...", "lastResponsePreview": "..." } ``` WebGUI 诊断区至少显示:连接/绑定状态、目标来源、最后成功、最后错误、状态文件路径。错误要转成用户能行动的中文提示。 ## WebGUI 实现要求 - 进入 Agent 设置页或打开快速配置对话框时自动扫描一次项目与会话;同一页面生命周期内不重复自动扫描。 - 只有用户点击扫描/刷新按钮可以再次请求项目与会话扫描。展开/折叠 Agent 参数、添加卡片、输入、`blur`、保存、健康轮询或计时器都不能触发扫描。 - 扫描按钮总是可见;列表为空时显示“扫描”而不是空下拉。 - 带人格和会话的 Agent 可提供“自动初始化会话”按钮:先保存名称 + ID 绑定;按 Manager 配置名称查找,零匹配只创建一次;再走正式 AgentPacket/角色消息链投递人格资料。初始化首投失败时复用已创建 ID,只重试投递,不再次创建。 - 关键动作按钮使用图标:刷新、下载/安装、登录、打开、部署、复制。 - 保存前校验必要字段:路径存在、URL 可达、插件安装、会话与项目匹配。 - 不要把多个 Agent 的会话混在一个未标注的列表里。 - 添加 Agent 后可以自动展开参数面板,但复用页面进入时的扫描结果;需要刷新时由用户点击扫描。 快速配置只放最常用链路,但顺序也必须是:Agent 类型 -> 路径/地址 -> 项目目录 -> 会话 -> 人格。 ## AstrBot 改造特别要求 AstrBot 当前只支持 ChatUI 会话合同: - 扫描默认 dashboard:`http://127.0.0.1:6185`,并允许发现最近配置的 URL。 - 检查 dashboard 是否在线、登录是否可用,并发现可绑定的 ChatUI 会话。 - 配置必须保存明确的 `ASTRBOT_SESSION_ID`;没有会话 ID 时禁止保存为可投递状态,并显示缺失字段。 - 投递只调用 `/api/chat/send`。不得调用 `/api/plug/rabiroute_agent/chat`,不得部署 `rabiroute_agent`,不得在会话缺失时切换到默认管线。 - 如果 AstrBot API 能列 bot、平台账号、群/私聊 channel,可继续提供辅助筛选,但最终投递身份仍是已保存的 ChatUI 会话 ID。 - 密码/token 缺失时显示缺失字段和重启/保存要求,不要等投递时才失败。 ## 验证清单 按以下顺序交付,前一步没有证据不得进入下一步: 1. 冻结用户可观察合同和禁止替代。 2. 完成 owner/lifecycle 表与真实协议探测。 3. 只实现一条最小纵向链路:发现一个目标、投递一条真实消息、读取或观察结果。 4. 先验证 owner 缺席、旧配置残留、失效 ID 和重复投递,再实现完整 WebGUI。 5. 完成 UI、诊断和文档后才构建安装包;打包不能充当架构验收。 完成后至少执行: ```text npm run webgui:build npm run build ``` 如果改了 WebGUI,启动本地页面并用浏览器检查: - Agent 面板可以渲染,无前端运行时错误。 - 字段顺序符合“路径/地址 -> 项目目录 -> 会话”。 - 扫描按钮、安装/登录/部署按钮不会让配置变脏,除非真的改了配置。 - 项目目录筛选会话有效。 - 缺安装、缺登录、缺插件、服务断开时都有可行动提示。 如果改了投递逻辑,至少用一个 mock 或本地假 endpoint 验证成功和失败两条路径都会写 state。 所有 Runtime 或会话接入还必须覆盖: - RabiRoute 缺席时 Agent/Desktop 独立冷启动。 - Agent/Desktop 缺席时 Manager 独立启动;Codex 显示 Desktop 未就绪且不启动 fallback。 - 分别关闭、重启两端,不互相拖死。 - 用户环境残留旧 endpoint 时不产生隐藏依赖。 - 重名会话按名称 + cwd 限定候选;精确 Codex ID 不因任务保存的默认 cwd 与本轮 workspace 不同而失效。非法/失效 ID 按名称 + cwd 自动解析,一个或多个匹配选择唯一最新者,零匹配创建,最新时间并列要求选择;已归档 ID 必须创建新任务、更新绑定且不复用同名任务。 - Desktop/Agent 端改名或 SQLite 标题在首投后变化时,连续两次真实投递仍使用同一 ID;Rabi 端明确输入新名称时先清空旧 ID,再按新名称查找/创建并保存新 ID。 - Codex 下拉和无 ID lookup 能按左侧栏 `Name` 找到 UI 可见任务,即使同一 ID 的 app-server `thread.name` 与 SQLite `threads.title` 都不同;该场景不得创建新任务。侧栏索引缺少 `Name` 时,名称查找失败关闭,不得退回其它标题源。 - 自动初始化按钮先持久化名称 + ID,再投递包含角色文件、记忆/计划索引和必读项的初始化消息;Desktop 中真实可见,初始化失败不产生第二会话。 - 超过 100 个会话时仍能访问全部结果;UNC、映射盘和 extended path 规范化后属于同一 cwd。 - 记录进入设置页、展开面板、输入、`blur`、保存和空闲等待期间的扫描请求次数:只有页面进入一次和每次显式点击扫描各增加一次,禁止后台持续增长。 - 同一会话连续真实投递两次,不意外新建线程。 - active turn 使用 steer 或明确排队,不并发 start。 - Codex 实际消息能在 Desktop 目标任务立即显示,并由同一个任务 owner 执行。 - Desktop 任务工具可用;若缺失,确认不是另一个 Runtime 执行后再报告能力缺失。 - 登录过期、服务离线、权限请求都有可行动错误;审批默认拒绝。 - 多个 gateway/bridge 不会重复消费同一事件。 测试不能只证明“服务已经运行时能连接”。必须验证冷启动、依赖缺席、残留配置和独立退出,并用 `git diff` 确认没有修改用户级环境、注册表或外部应用启动配置。 验证结果要回写到能力等级: - 只验证了 UI 构建,不算 `verified`。 - 只验证了扫描,不算 `verified`。 - 没有真实投递目标时,保留 `experimental`,并记录 mock 验证范围。 - 真实跑通过扫描、配置保存、消息投递、失败诊断后,才升为 `verified`。
عرض على GitHub