oh-my-opencode-slim 后台任务会话管理(Task Session Manager)深度解析:多 Agent 协作下的作业看板、别名复用与生命周期编排
发布时间:2026/9/25 11:18:28 锦皓数字建站
深度解析:多 Agent 协作下的作业看板、别名复用与生命周期编排`)
人工智能AI AgentAgent 编排AI 技能【免费下载链接】oh-my-opencode-slimLean, fine tuned Opencode multi agent suite · Mix any models · Auto delegate tasks项目地址https://gitcode.com/gh_mirrors/oh/oh-my-opencode-slim点击查看免费下载导读src/hooks/task-session-manager/是 oh-my-opencode-slim 中负责V2 后台任务background job状态管理的核心模块它以一张集中的BackgroundJobBoard作业看板为唯一事实来源通过钩子接入 OpenCode 生命周期让 orchestrator 能够跟踪活跃任务、按短别名如exp-1、ora-2复用已完成且已对账reconciled的子会话并实现安全的任务分发、恢复与人工介入等待。读完本文你将掌握该模块的 Facade Strategy 架构、任务执行全生命周期、作业看板注入机制、配置项与容量上限以及它背后的源码级设计权衡。模块职责从分发完就忘到可跟踪、可复用、可对账在标准的 orchestrator/子 Agent 架构中orchestrator 会通过task工具把工作委派给 explorer、librarian、oracle、designer、fixer、observer、council 等子 Agentsrc/config/constants.ts 中定义了完整的SUBAGENT_NAMES列表。任务一旦派发出去父会话就需要持续跟踪其状态、在完成后拿回结果、并在下一次请求中决定是复用已有会话还是新建会话。task-session-manager正是承载这一职责的模块它的核心能力可以概括为四点跟踪活跃任务维护一张内存中的作业看板记录每个后台任务的 ID、父会话、Agent 类型、目标objective、状态与读取上下文。按别名复用已完成会话每个任务在注册时被分配短别名exp-1、ora-2等orchestrator 可以在下一次task调用中直接用别名或 task ID 复用已完成的子会话避免重复劳动。安全的生命周期对账区分已完成待确认terminal unreconciled、已确认reconciled、运行中running、停止stopped等状态防止父会话丢失任务结果或误复用不安全的会话。人工介入等待通过wait_for_user工具向用户显式等待并抑制空闲续推。架构设计Facade Strategy单一职责的模块分解index.ts是整个模块的门面Facade它把行为编排到一组职责单一的策略子模块上。目录下每个文件都有明确的关注点详见 src/hooks/task-session-manager/codemap.mdindex.ts主门面实现插件钩子接口tool.execute.before、tool.execute.after、experimental.chat.messages.transform、event并向wait_for_user工具暴露beginUserWait()。input-wait-tracker.ts提供唯一的hasInputWait()判定入口供空闲对账与续推评估使用它合并了本地 question/permission 等待与进程级显式用户等待闩锁。continuation-model-selection.ts归一化当前会话与聊天钩子的模型形状再把运行时模型与变体选择转发给空闲续推提示。pending-call-tracker.ts用有上限的有序 MapMAX_PENDING_TASK_CALLS跟踪飞行中的任务调用提供调用 ID 的生成、存储、检索与清理。admission-runtime.ts转导出插件代次generation使用的每目录准入运行时租约调度器与 pending 调用跟踪器只有在最后一个未认领的所有者释放后才被拆除。fallback-observation-transfer.ts为被前台回退foreground fallback重新提示的后台子任务提供终端观测交接createBackgroundFallbackHandoffprepare/admit/reject/settleUnresolved包裹了重新提示的准入使停止证据门stop-evidence gate推迟终端发布直到存在交付所有者。same-provider-policy.ts可选的按 Provider 重写backgroundJobs.sameProviderPolicy: { provider: foreground }把同 Provider 的background: true任务请求转换到前台路径未知模型/Provider 时失败开放fail-open。task-context-tracker.ts管理来自子会话的读取上下文带有行数与文件数上限按任务 ID 存储并提供修剪以防止无界增长。关键抽象抽象含义源码位置BackgroundJobBoard任务会话的中央状态存储活跃、可复用、终端未对账src/utils/background-job-board.tsPendingTaskCall飞行中的任务调用记录call ID、父会话 ID、Agent 类型、标签、可选的重启任务 IDsrc/hooks/task-session-manager/pending-call-tracker.tsContextFile子会话读取上下文路径、行数、最后读取时间戳src/utils/background-job-board.tsUser wait显式纯文本 HITL 闩锁由wait_for_user武装由一条明确的真实外部用户消息释放src/hooks/task-session-manager/user-wait-gate.ts别名生成的实现细节别名不是随机的BackgroundJobBoard内部维护一个AGENT_PREFIX映射把 Agent 名映射为 3 字母前缀council→cou、designer→des、explorer→exp、fixer→fix、librarian→lib、observer→obs、oracle→ora未知 Agent 取名字前 3 个字符最终格式为prefix-n如ora-2。计数器以parentSessionID:prefix为键并且会从持久化的高位水印high-water mark播种——这意味着插件重启后不会复用历史上的旧别名旧别名解析为未找到是预期行为src/utils/background-job-board.ts。任务执行生命周期一次后台任务调用的完整旅程1. 执行前tool.execute.before当 orchestrator 发起task工具调用时实现在 src/hooks/task-session-manager/tool-execute-hooks.ts 的handleToolExecuteBefore钩子会拦截被管理会话上的task工具调用通过deriveTaskSessionLabel从description/prompt生成任务标签description 优先取前 48 字符否则取 prompt 第一个非空行都为空则回退为recent agentType task创建PendingTaskCall记录含 call ID、父会话 ID、Agent 类型、标签、background标志与生命周期纪元从作业看板解析可复用的 task ID已完成/已对账的作业可按别名复用超时后仍在运行running的作业只有在收到实时忙信号live busy signal确认可安全恢复后才可恢复resolveRecoverable要求recoverableAfterLiveBusy为真且未超出墙钟截止时间若不存在可复用任务则允许新建任务分发循环守卫dispatch loop guardissue #1070若一个全新 spawn 的目标与同一父会话、同一 Agent 的未对账终端作业目标完全一致比较的是未截断的完整 objective 文本而不是 48 字符标签见deriveFullObjective则拒绝派发在该作业完成后的task_result检索lastUsedAt completedAt会授权重试escape hatch。此外还有几层防呆保护值得一提拒绝恢复非法的显式 task_idrefuseExplicitTaskId/refuseKnownTaskResume会抛出明确错误——例如stopped状态的会话不能用task()恢复必须用task_revive未对账的终端会话必须等对账后才能task()。幻觉 UUID 丢弃当请求的 task_id 形如随机 UUIDUUID_SHAPE正则且不在看板中时直接丢弃该 ID 并按新 spawn 处理——这是 2026-09-19 发现的下游 Provider 故障签名429 窗口期模型编造 task_id注释中记录了该模式。未知别名防重复如果别名无法解析如插件重启导致看板丢失映射且hasUntrackedRunningChild探测发现可能仍有运行中的子会话则拒绝静默 spawn 重复任务探测失败时按 fail-closed 处理。2. 任务启动tool.execute.afterhandleToolExecuteAfter负责把启动结果写回看板先处理read工具的调用若当前会话是被管理的任务则从输出中提取读取的文件extractReadFiles解析path.../path与^N:行号存入任务上下文跟踪器对task调用先通过调用 ID 精确匹配 pendingtake无调用 ID 时通过takeByTaskID用输出中解析出的 task ID 匹配早注册的 pending仍失败时走受保护的takeUnresolvedFirstMatch排水回退drain fallback解析任务输出parseTaskLaunchOutput识别启动信息并调用registerLaunch注册parseTaskStatusOutput识别状态输出并触发终端门terminal gate的对账把读取上下文加到看板addContext处理迟取消任务normalizeLateCancelledTaskOutput。值得强调的是身份解析纪律在宿主不提供工具调用 ID 的情况下模块绝不按插入顺序猜测并行调用的归属take()无调用 ID 时仅在父会话恰好只有一个 pending 时才推进独存者属于此调用的顺序论证否则拒绝并走任务 ID 匹配或排水回退。排水回退消费的 pending 会被标记identityUnresolved其 label/objective 永不猜测不涂抹到看板记录上resultSummary/taskID始终来自调用自身的输出。3. 上下文跟踪从read工具输出中提取读取文件extractReadFiles见 src/hooks/task-session-manager/task-context-tracker.ts按任务 ID 在 task context tracker 中存储上下文路径 行号集合 最后读取时间在生命周期事件与状态转换期间修剪过期上下文prune既不在pendingManagedTaskIds也不在看板中的任务上下文被删除。4. 消息注入experimental.chat.messages.transform这是 orchestrator看到后台任务状态的通道实现在 src/hooks/task-session-manager/board-injection.tsstabilizeRunningTaskParts先把所有仍处于running状态的 task 工具结果输出字节稳定化为确定性占位符仅按 task ID 生成防止运行时把实时子进程进度流式写入历史消息、破坏 Provider 提示缓存write-never-read 循环终端结果completed/error/cancelled保持原样、恰好物化一次rehydrateHistoricalRunningTasks从历史消息中恢复仍在运行的background: true任务如插件重启后并重新认领准入槽位把包含### Background Job Board段的system-reminderpart 注入用户消息#### Active / Unreconciled列出运行中、超时、状态不确定、未对账终端任务#### Reusable Sessions列出可按别名复用的已完成/已对账会话含Objective与Context read by alias#### Retained / Recovery列出无终端结果、须用task_revive而非task()恢复的 stopped 会话记住已注入的终端任务在完成结果呈现给模型后于下一次请求对账reconcileConsumedTerminalJobs/reconcileInjectedTerminalJobs空闲定时器兜底当模型结束回合且没有后续请求时空闲对账负责兜底对账注入终端结果后可选的续推评估器opt-in continuation evaluator在同一个空闲周期内、在其既有守卫下运行。注入还有两处值得一提的机制一是board 文本只允许挂在 user 角色消息上canCarryBoardPart——因为宿主消息转换器会把 assistant 消息的metadata作为providerOptions校验boolean 元数据会触发AI_InvalidPromptError二是retainedTailBoards保证latest策略已放置在中间历史锚点上的看板会按字节原样重放避免看板从已缓存前缀中消失导致的缓存失效。5. 生命周期事件event事件路由器src/hooks/task-session-manager/event-router.ts处理会话生命周期session.created把新任务 ID 加入待管理集合。早期看板注册只在能唯一识别时认领 pending唯一子会话title匹配v2 宿主会以title description参数盖章并额外约束子会话的 Agent或唯一 Agent 类型匹配且该 Agent 无已消费调用。歧义、过期或无法归属的子会话登记为unattributed agent task占位保证task_status总能解析所有权的tool.execute.after会纠正描述。session.idle/session.statusidle先对账父会话的注入终端任务兜底路径再在同一空闲周期内运行续推评估器子会话空闲是停止候选第一次观测保持临时provisional只有 5 秒宽限期后再次确认空闲/缺席才标记stopped。session.statusbusy根据实时会话状态把任务标记为运行中并重置停止确认。session.deleted清除会话的任务状态、子任务与 pending 调用记录clearParent、drop、clearSession。server.instance.disposed清除代次本地状态但保留共享的 pending calls 与准入队列供下一代使用。6. 人工介入等待Human-in-the-loop Waitswait_for_user仅在工具校验通过后调用门面的beginUserWait()共享闩锁会取消挂起的续推定时器/预订前台回退的重放来源replay provenance与共享回退拆除状态保证闩锁在插件管理器重建plugin-manager recreation后仍然存活在一条明确的外部真实用户消息到达之前空闲续推保持抑制isGenuineOperatorMessage是与 orchestrator-wake 共享的真实操作者消息判定单一来源。数据与控制流总览User task call → tool.execute.before → PendingTaskCall created → task ID resolved/reused → tool.execute.after → BackgroundJobBoard.registerLaunch() → context extracted/added → Message transform → BackgroundJobBoard.formatForPrompt() injected as a system-reminder message part → session.idle → reconcileInjectedTerminalJobs() → BackgroundJobBoard.markReconciled() → opt-in continuation evaluator (same idle cycle, existing guards)作业看板状态机与容量守卫BackgroundJobBoardsrc/utils/background-job-board.ts是唯一事实来源其记录类型BackgroundJobRecord包含丰富的状态字段状态running/completed/error/cancelled/stopped/reconciledBackgroundJobState运行身份generation单调运行身份显式重启/复用会递增、terminalRevision发布身份含被撤回的发布、taskGeneration任务本地运行身份不相关的任务不会影响它时间戳launchedAt、lastLaunchedAt、runStartedAt、lastLiveBusyAt、stopConfirmationStartedAt、completedAt、deadlineExceededAt持久硬墙钟标记区别于外部任务等待超时可靠性timedOut、recoverableAfterLiveBusy、statusUncertain、terminalUnreconciled归属与内容alias、description、objective、resultSummary、contextFiles、totalErrors、timeoutCount。关键的状态守卫逻辑从源码可以确认applyStatus拒绝把过期的状态更新重开已终端任务reconciled 不可重开stopped 不可回 runningcanonical 终端状态不可回 running墙钟截止claimWallClockDeadline/finalizeWallClockTimeout是硬性不可恢复主张截止后的完成属于迟到证据不能取代权威超时markStopped要求观测时间晚于lastLiveBusyAt并且不做空泛猜测——宿主报告子会话不再执行但没有原生结果时保留歧义并禁止普通task()复用恢复走task_revivemarkReconciled把状态推进到reconciled并解除terminalUnreconciled使会话进入可复用集合租约lease机制每个原生会话 ID 同一时刻只有一个运行操作/重启所有者liveLeasesrelaunch/cancellation/message/terminal-notification四类租约都有独立的校验路径防止同一代次被多个操作并发拥有。可复用性与容量上限看板以LRU 风格修剪trimReusable先按上下文行数预算maxContextLines驱逐超限会话再按maxReusablePerAgent数量上限驱逐最久未用的可复用会话trimRetained对 retained-stopped 会话做同样的修剪受租约屏蔽保护的除外。isReusable的判定组合了存在终端状态、未对账标记为假、状态不确定为假、上下文行数不超预算四个条件。配置项与容量上限模块的配置通过createTaskSessionManagerHook()的 options 注入默认值定义在 src/config/constants.ts配置项默认值含义maxSessionsPerAgentDEFAULT_MAX_SESSIONS_PER_AGENT 2每个 Agent 类型最多保留的可复用会话数readContextMinLinesDEFAULT_READ_CONTEXT_MIN_LINES 10读取上下文包含的最少行数低于此值的文件不入上下文readContextMaxFilesDEFAULT_READ_CONTEXT_MAX_FILES 8读取上下文包含的最大文件数maxContextLines看板内部DEFAULT_MAX_CONTEXT_LINES 50_000单个可复用会话上下文行数预算超限即驱逐maxRetainedSnapshotsDEFAULT_MAX_RETAINED_SNAPSHOTS 20看板注入保留快照数量上限strategylatest看板注入策略latest/checkpoint-compatibleshouldManageSession必填谓词判定哪些会话由该钩子管理sameProviderPolicy未设置关闭{ provider: foreground }映射把同 Provider 后台任务转前台pendingCallTracker共享进程级新建跨插件代次共享的 pending 调用跟踪器保证准入运行时唯一其他相关的进程级上限源码常量MAX_PENDING_TASK_CALLS 100pending 调用有序 Map 上限、MAX_CONSUMED_CALLS 200已消费调用保留数、空闲对账延迟IDLE_RECONCILE_DELAY_MS 2000父会话确认已发布结果的确认延迟子证据重试专属于终端门。与周边模块的集成主插件src/index.ts通过createTaskSessionManagerHook()把本钩子接入 OpenCode 生命周期这是唯一的消费入口。BackgroundJobBoardsrc/utils/background-job-board.ts任务会话与上下文的中央状态存储BackgroundJobStore是其只读/写接口契约。任务输出解析工具src/utils/index.tsparseTaskIdFromTaskOutput、parseTaskLaunchOutput、parseTaskStatusOutput、deriveTaskSessionLabel。终端门src/utils/background-job-terminal-gate.ts所有终端发布的共享执行/观测门运行时静止quiescence与可归属的结果证据授权一次看板提交忙碌busy会撤回终端发布宽限、有界重试与单开读在各适配器间共享。守卫与日志isRecord工具与log诊断。编排器唤醒src/hooks/orchestrator-wake/index.ts共享真实操作者消息判定isGenuineOperatorMessage控制wait_for_user闩锁的清除与空闲定时器的失效。模块拆分动机为什么把单体拆成策略子模块原模块曾是单体实现拆分带来了四方面收益这也是 codemap.md 中Module Decomposition Rationale一节的结论关注点分离pending 调用、任务上下文、看板状态现在是各自独立的职责可测试性每个子模块都能用聚焦的契约独立测试目录下配套了大量*.test.ts如 pending-call-tracker.test.ts、task-context-tracker 相关测试 等可维护性修改一个关注点如上下文跟踪不会影响无关逻辑可扩展性有上限的数据结构MAX_PENDING_TASK_CALLS、maxReusablePerAgent、maxContextLines防止无界内存增长。每个子模块遵守单一职责原则同时通过门面协作提供内聚的用户体验——这正是该目录架构的核心设计理念。小结task-session-manager是 oh-my-opencode-slim 多 Agent 自动委派体系的地基它以BackgroundJobBoard为单一事实来源用一套精心设计的钩子执行前/执行后、消息注入、生命周期事件把派发 → 跟踪 → 复用/恢复 → 对账 → 人工介入串成闭环并用别名、租约、终端门、容量上限与防呆守卫分发循环守卫、幻觉 ID 丢弃、身份解析纪律把状态管理的边界风险压缩到最小。理解这个模块就等于理解了整个项目如何做到在多个模型混合编排下安全地自动委派任务。赞分享人工智能AI AgentAgent 编排AI 技能【免费下载链接】oh-my-opencode-slimLean, fine tuned Opencode multi agent suite · Mix any models · Auto delegate tasks项目地址https://gitcode.com/gh_mirrors/oh/oh-my-opencode-slim点击查看免费下载相关推荐WinUtil 免费 Windows 系统优化工具完整指南重装系统后一小时把电脑配回顺手的样子WinUtil 免费 Windows 系统优化工具完整指南重装系统后一小时把电脑配回顺手的样子 刚重装完系统的人多半都体会过这种手足无措桌面光秃秃、软件一人工智能AI AgentAgent 编排AI 技能OOTDiffusion 虚拟试衣跑不起来模型文件缺失排查与配置速查OOTDiffusion 虚拟试衣跑不起来模型文件缺失排查与配置速查 刚克隆 OOTDiffusion 仓库、执行 run/run_ootd.py 终端就被人工智能计算机视觉媒体生成AI 应用3分钟下载电子课本PDFtchMaterial-parser 操作步骤3分钟下载电子课本PDFtchMaterial parser 操作步骤 tchMaterial parser 是国家中小学智慧教育平台的电子课本下载工具。复制网页爬虫教育上一篇ThinkPad风扇控制终极指南用TPFanCtrl2实现智能散热与极致静音下一篇HCCL TLS信息配置不一致EI0016故障排查指南通信域初始化阶段TLS开关与证书一致性校验详解创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。