agent-Specialization/cache_research/gateway/gateway_work_plan.md

15 KiB
Raw Blame History

Astrion 运行时边界整理与定时任务工作清单

更新日期2026-09-07 状态:修订后的设计与实施建议,尚未实施。 原题为「Astrion Gateway 化工作清单」,保留文件名便于既有引用。 依据:用户对目标的澄清、三份研究报告,以及本轮三个 Luna 子智能体的只读核查。 本轮核查为静态代码分析,没有运行并发、断线或进程重启复现;下文区分已有机制、待核验风险与拟新增能力。

0. 改造目标与范围

本次目标是让 Astrion 的内部职责、状态修改规则和任务入口更清晰,使后续功能沿稳定边界扩展。当前明确的新功能场景是定时任务

Gateway 是长期架构方向;近期交付是在现有进程中整理运行时服务边界,让 Web、CLI 和定时触发器复用任务受理、执行与控制逻辑。验收依据是新增入口所需理解和修改的范围,以及现有行为是否得到保留。

近期主线:

  1. 固定已有状态边界和正确性保障。
  2. 抽出接收显式运行上下文的公共任务入口。
  3. 通过定时任务验证该入口,并补齐调度所需的持久记录和生命周期。

事件持久化、传输替换、公开 SDK、设备配对和远程执行分别评估不构成本次完成的前置条件。

参考资料的使用边界

  • 原始愿景:.astrion/user_upload/Astrion_Architecture_Product_Roadmap_Review_1.md,重点 §1014、§35、§3738。
  • 原始盘点:astrion_audit/astrion_gateway_gap.md。其中“无唯一 owner”“补丁不是投影”“恢复机制脆弱”等结论须结合下表理解不能直接当作未修复故障。
  • 外部研究:opencode_study/opencode_architecture.mdopenclaw_study/openclaw_gateway.md。参考其职责分离、契约、幂等和恢复设计,不要求复制其部署、存储或认证方案;外部实现未在本轮重新核验。

1. 现状:已有保障、剩余耦合与待核验事项

以下路径相对仓库根目录;行号是本轮读取时的定位锚点,后续以符号为准。

类别 当前证据 对改造的含义
已有:对话级资源隔离 server/context.py:58 按 username/workspace/conversation 生成终端 key 保留每对话资源边界;多端共享同一对话资源本身合理
已有:主任务门闸 server/chat_flow.py:139 获取门闸,:258 在 finally 释放;实现位于 server/main_task_gate.py 公共入口复用同一执行裁决,不新增平行门闸
已有:对话保存保护 utils/conversation_manager/crud_mixin.py:335 按 message_id 合并、防止意外缩减;:194 使用 I/O 锁;index_mixin.py:104 原子替换文件 将保存语义纳入契约;不能因存在内存和文件副本就断言写入竞争未解决
已有:客户端恢复 static/src/stores/task.ts:156 偏移轮询;static/src/app/methods/taskPolling/probe.ts:73 对账恢复;同目录 lifecycle.ts:137 按 task_id/idx 去重 保留恢复闭环和过期响应过滤;当前轮询是增量事件读取,不是每轮全量读取
已有:审批单次决定 modules/tool_approval_manager.py:65 在锁内裁决 pending已决定时返回现状 复用决定规则;记录谁决定与提前认领审批是不同需求
耦合:执行依赖 Web 环境 server/tasks/models.py:785 后台任务建立 test_request_context、回填 session 后获取资源和执行 优先抽出显式上下文,减少隐式请求状态依赖
耦合:写入口分散 任务 manager、terminal、conversation manager 各有职责和直接调用方 按状态明确权威、写入口和缓存更新;新增门面不是完成所有权收敛的证明
边界:过程记录为内存态 server/tasks/models.py:75 有界事件 deque:108 清理旧任务,:762 分配任务级 idx审批 manager 为进程内实例 不能承诺服务重启续跑或无限期回放;也不能说任务一结束事件就立即丢失
优化候选:用户级广播 server/context.py:75 给事件补 conversation_id由客户端筛选 当前也是投影方案;对话级订阅用于减少无关流量和明确受众,不是 Owner 正确性的必选前提
新能力:用户定时任务 本轮搜索只发现任务清理、idle reaper 等维护定时器,未发现用户 Schedule 实体与到期派发链路 单独设计调度状态与记录,复用现有任务执行

保留两个有界核验项,避免将静态推断直接升级为故障结论:

  • server/tasks/models.py:157 的“检查运行中任务→创建记录”与最终执行门闸分属两处。核验并发请求是否产生重复任务记录;不能据此断言会并发修改同一对话。
  • 原报告提到 server/chat/terminal.py::issue_socket_token 发放竞争。本轮未重新复现;若仍存在,作为独立的小范围缺陷处理,不捆绑整个运行时改造。

2. 阶段一:固定契约与已有不变量

目标:明确状态属于谁、新入口应该调用哪里。

  • 产出 docs/runtime_contract.md,先描述内部服务契约;暂不强制公开网络协议、握手或实体全面改名。
  • 建立状态责任表:每项列明权威来源、允许的修改方、持久化入口、缓存刷新、并发裁决和失效条件。内存/文件/客户端缓存可以共存,权威关系必须明确。
  • 对齐概念Session 对应现有 conversationRun 对应一轮主任务Schedule 表示计划Occurrence 表示某次到期触发Event 表示变化通知。子 agent、后台命令与主任务的关系单独说明不直接把所有现有 task 等同主 Run。
  • 审批与用户提问保留不同语义。可共享 ID、关联、等待和回答的基础设施但提问答案不能被当作工具执行授权。
  • 明确公共入口所需的 principal、workspace、conversation、模型/运行配置与事件输出接口;默认值由明确的解析步骤产生。
  • 建立调用方迁移表Web/CLI 对应 API、Workflow 激活、通知派发、定时触发。每项标注上下文来源、门闸获取/释放和取消传播。
  • 围绕修改范围保留或补充回归用例:同对话并发、不同对话隔离、保存不丢消息、取消、审批重复回答、偏移恢复和过期响应过滤。

**完成标准:**目标入口的状态修改路径和执行裁决可定位;已有保障成为明确约束,未验证风险有独立记录。

3. 阶段二:抽出显式上下文与公共任务入口

目标:无浏览器也能通过受控入口启动、观察和停止一轮任务。

Web / CLI 适配层       定时触发器       Workflow / 通知派发
        \                 |                 /
             公共任务受理与控制入口
                       |
             现有执行门闸与 Agent 执行
                       |
          现有保存、审批、事件和取消链路
  • TaskManager.create_chat_task 及执行链路为基础抽出服务接口。RuntimeService 可作为名称候选;文件位置按真实职责确定,避免把所有 manager 和状态塞入一个新类。
  • 服务接口至少覆盖提交、查询和取消;审批回答复用现有 manager通过明确关联接入服务层。会话创建按需要复用现有服务第一条验证链路可使用已有会话。
  • HTTP 参数解析、Cookie/CSRF/Bearer 验证放在适配层,向服务层传入可信 principal 和经校验的资源范围。不能接受客户端或 Schedule payload 自报的 role 作为授权依据。
  • 消除目标执行链路对隐式 Flask session 的读取。迁移期可在明确的兼容适配层保留旧上下文,但须列出剩余依赖;只把 test_request_context 包进新方法不算完成解耦。
  • 复用门闸、取消、审批和保存规则;分别定义任务受理去重与实际执行互斥,防止重复启动或门闸泄漏。
  • Web 任务入口先接入服务,再逐条迁移 Workflow/通知等调用方;每次明确哪些旧写路径已封闭。不能把“门面转发成功”写成“全部状态唯一 Owner 已完成”。
  • 内部错误采用稳定状态/错误码HTTP 状态码由适配层映射;事件先适配现有 idx/offset 和 sender不同时重写客户端。

**完成标准:**不创建浏览器会话、不伪造 HTTP 请求,测试能通过显式身份和资源上下文启动一次受控任务、读取结果并取消;同对话重入仍受门闸保护;现有 Web/CLI 行为兼容。执行可使用可控模型/工具替身验证,无需真实外部副作用。

4. 阶段三:定时任务纵向落地

目标:时钟成为公共任务入口的另一个调用方。

本节是待实施设计,不代表当前已有调度器。具体 UI 和默认行为在实现前确认,下列保守默认作为讨论起点。

4.1 计划与触发记录

  • Schedule 至少保存ID、所属 principal、目标 workspace、会话策略、提示词/任务配置、时间规则、时区、启用状态和配置版本。明确夏令时重复/不存在时刻的处理。
  • 支持创建、暂停、恢复和删除计划。建议暂停/删除只影响未来触发,已受理的 Run 另行取消;最终行为须明确。
  • 明确使用已有会话还是每次新建会话;首版可只实现一种,须说明上下文累积、目标删除和工作区失效时的行为。
  • 模型配置确定“创建时固定”还是“触发时解析”;权限在触发时按当前有效授权重新校验,不保存可绕过权限变更的长期授权快照。
  • 每个 Occurrence 有稳定触发标识,例如 schedule_id + 计划时间点保存所用配置版本、受理状态、run_id 和终态。计划编辑后的未来触发身份规则须明确。

4.2 重复、重叠与停机

  • 为 Occurrence 登记和 Run 受理定义持久幂等规则:同一触发重试返回同一受理结果,相同键不同参数拒绝;记录保留期覆盖允许的重试窗口。
  • 明确“登记后未启动”“已启动但关联未写完”等崩溃窗口。登记/受理应原子提交或具备可验证的恢复对账;不能只用内存 TTL 承诺跨重启不重复执行。
  • 选定单个活动调度器的启动与所有权规则,防止重载器或多个服务进程重复派发;不要求因此引入分布式基础设施。
  • 同会话已有任务或上一轮仍在运行时,定义 skip/queue/parallel 策略。建议首版跳过并记录原因,沿用会话门闸,不默默增加无限队列。
  • 定义服务关闭期间错过触发的策略。建议首版记录错过并等待下个未来时点,不集中补发;服务需运行才会触发,本阶段不包含操作系统唤醒/开机自启。
  • 重启后恢复 Schedule 和触发记录;上一进程未确认完成的 Run 标为中断或结果待核验,不显示仍在正常运行,不自动重做可能已产生副作用的动作。
  • 触发去重仅保证任务受理规则,不承诺任意外部工具副作用 exactly-once。无法确认的执行结果进入显式待核验状态。

4.3 审批、存储与验收

  • 无人在线时仍保持原有权限限制:遇到审批/提问按明确超时等待,超时结束或中断本轮并记录原因,不自动扩大权限。等待中的任务也遵守重叠策略。
  • 审批关联当前 Run/会话,复用现有 pending/answer 链路。重启后旧请求不能被当作仍有执行现场的有效审批;持久审批记录与继续执行分别设计。
  • 为 Schedule/Occurrence/必要的运行摘要选择持久化方案,先列出原子更新、唯一性、查询和恢复要求,再决定文件或 SQLite。数据走运行态路径解析不写源码树不强制迁移全部对话历史。
  • 沿用当前任务事件读取;补充触发记录查询,使旧内存任务被清理或重启后仍能解释触发结果。日志记录 schedule_id/occurrence_id/run_id复用既有设施。

**完成标准:**可控时钟与执行替身验证一次触发、重复触发、任务重叠、计划暂停/恢复、目标失效、无人审批超时、停机错过触发及重启对账;真实入口验证不依赖浏览器。明确只恢复计划与记录,不承诺从任意执行位置续跑。

5. 后续独立决策:有明确需求再启动

决策 启动条件 决策前必须补充的内容
SSE / WebSocket / 保持轮询 现有延迟、连接数或带宽不能满足目标,或新增双向交互需求 部署 worker 模型、代理缓冲、重连、慢消费者处理;传输更换不等于状态正确性提升
对话级订阅 需要减少无关广播、精确控制受众 订阅与资源授权分别校验,区分任务/会话事件与用户级通知
durable 事件与快照恢复 需要超出内存保留窗口的过程追溯、跨重启生命周期查询 提交时机、序号作用域、快照边界、日志裁剪、缺口处理与 schema 版本
审批持久化与可恢复执行 需要重启后继续等待并执行原动作 重建上下文和待执行动作、权限重校验、过期请求处理及结果不确定性;恢复 pending 记录不能实现续跑
TS 类型 / SDK 生成 对外契约或多客户端类型维护成为实际成本 选一个 schema 权威源、兼容策略与生成检查;不强制新网络握手
身份体系整理 跨凭证访问同一资源或统一授权成为需求 统一 principal/resource/authorization各适配层可保留不同凭证机制不能直接合并 Web/API 用户数据空间
设备配对 / Remote Worker 明确需要多设备接入或远程执行 执行契约、连接身份、所有权转移及故障语义,独立设计验收

若进入事件恢复改造,必须遵守以下边界:

  1. 快照注明覆盖的事件水位 N并与同一状态版本一致续传从 N 之后开始。快照生成、订阅和历史读取之间不得有漏事件窗口,重复投递仍需幂等应用。
  2. durable 事件只承诺已提交记录可恢复live delta 是否恢复单独定义。运行中未完成的 Item 需要当前内容快照、覆盖式更新或不完整标记,不能只依赖最终 completed 事件。
  3. 状态和事件写入需要一致的提交/恢复规则。对话 JSON、事件 JSONL、审批 JSONL 不天然构成一致快照与日志。
  4. 连接序号、任务偏移和持久会话序号不能混用;连接重建、历史裁剪或会话重置时给出明确的重新同步规则。
  5. JSONL 与 SQLite 都需定义恢复、保留和迁移方案。选择依据是事务与查询边界,不承诺以后可低成本平移。

6. 改造完成的判断

  • 新增任务来源只需构造显式上下文、校验目标并调用公共入口,无需复制 Web 聊天启动流程。
  • 已迁移路径有明确状态权威与写入规则,现有门闸、保存和客户端恢复保护得到保留。
  • 定时任务有可查询的计划、触发记录和终态;重复、重叠、权限变化与停机行为可解释。
  • 各阶段可独立验证;只为当前边界迁移做必要的接口调整,不同时重写 Agent loop、前端状态管理或部署拓扑。
  • 每阶段说明实际迁移的入口、剩余兼容依赖和验证结果。完成门面、生成架构图或更换传输本身不算完成改造。