ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

oh-my-opencode-slim 生命周期 Hooks 架构:缓存安全注入与多 Agent 任务编排的底层机制

oh-my-opencode-slim 生命周期 Hooks 架构:缓存安全注入与多 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点击查看免费下载oh-my-opencode-slim 是一个面向 OpenCode 的精简但精准调优的多 Agent 插件套件其全部运行时能力都挂在 OpenCode 插件体系的生命周期 Hooks 上消息/提示词转换、工具执行拦截、事件路由、缓存安全注入以及运行时命令拦截。本文以仓库内src/hooks/codemap.md为核心骨架结合源码实现逐层拆解这套 Hook 体系的设计、装配顺序与关键机制读者读完可以掌握Hook 工厂如何被组织与装配、如何在不动摇 provider 提示词缓存的前提下向出站消息注入内容、以及 orchestrator 与后台任务会话是如何通过这些 Hook 实现可恢复编排的。hooks 模块的职责定位src/hooks/是插件面向 OpenCode 宿主暴露的全部生命周期切入点的实现集合。根据 codemap 的职责声明它覆盖五类工作消息/提示词转换message/prompt transforms在请求真正发往模型之前改写消息内容工具执行拦截tool-execute interception在tool.execute.before/tool.execute.after两个切点介入工具的校验、改写与事后处理事件处理event handling消费event钩子传递的会话生命周期事件缓存安全注入cache-safe prompt injection所有需要追加到出站 payload 的内容必须经由统一的、保证 provider prompt-cache 前缀不被破坏的通道运行时命令拦截runtime command interception为/deepwork、/reflect、/loop等运行时命令注册执行前处理。架构上有一个关键约定每一个 Hook 都是一个工厂函数factory function由index.ts桶式导出barrel-export返回 OpenCode 实际调用的 hook point 处理器。插件主入口 src/index.ts 只从桶出口导入而不逐个文件导入这保证了装配点唯一、依赖关系清晰。核心架构五个基础构件工厂桶出口Factory Barrelsrc/hooks/index.ts 是全部 Hook 工厂的唯一出口导出内容覆盖完整生命周期工具侧createApplyPatchHook、createSearchPathGuardHook、createAbsolutePathRescueHook、createToolLoopGuardHook消息转换侧createPhaseReminderHook、createPostFileToolNudgeHook、createFilterAvailableSkillsHook、createChatHeadersHook、createTaskSessionManagerHook事件侧createCacheMonitorHook、createOrchestratorWakeScheduler并导出ORCHESTRATOR_WAKE_TEXT等醒神文本常量命令侧createDeepworkCommandHook、createReflectCommandHook、createLoopCommandHook兜底与恢复createJsonErrorRecoveryHook、createAutoUpdateCheckerHook、ForegroundFallbackManager模型回退管理器共享辅助件SessionLifecycle、cache-safe-injection、chat-headers、command-hook-utils、image-hook、typesSessionLifecycle会话删除协调器src/hooks/session-lifecycle.ts 是会话生命周期协调器解决了多 Hook 各自监听session.deleted导致的重复与混乱清理回调注册有状态的 Hook 通过onSessionDeleted(callback)注册自己的清理回调而不是各自实现session.deleted处理器主入口在收到session.deleted事件时统一调用dispatchSessionDeleted(sessionId)分发见 src/index.ts。单个回调抛错会被捕获并记录日志不影响其他回调执行。pending 会话信号通道markPending(sessionId)/consumePending(sessionId)实现**消费一次consume-once**语义——consumePending是原子的每次markPending只有唯一一个调用方能拿到true用于避免多个消费者重复处理同一个待处理会话。Cache-safe injection唯一合法的注入通道src/hooks/cache-safe-injection.ts 是整个模块最核心的机制。其动机写在该文件头部注释中provider 的 prompt cache 是对渲染后请求tools → system → messages的精确字节前缀匹配任何改写或重排早期对话内容的转换都会使首个变化字节之后的所有内容缓存失效导致会话内后续每次请求都重新支付完整输入成本与延迟。为此它提供两组互补 API确定性追加appendTaggedSyntheticPart(message, spec)在既有消息的尾部追加一段带标签的合成文本 part。它要求内容必须是会话稳定输入的纯函数这样下一轮重新执行转换时会产出相同位置、相同字节天然安全。易变内容区stripTaggedContent(messages, metadataKey)appendTrailingVolatileMessage(messages, info, spec)用于作业看板job board、状态块这类回合间会变化的内容先剥掉所有此前注入的出现并删除因此被清空的消息再在 payload 最末尾重新追加一条合成尾消息。这样变动只发生在 prompt 尾部早期前缀保持字节稳定。支撑实现值得注意的细节标签机制createTaggedSyntheticPart构造的 part 带有synthetic: true标志和metadata[metadataKey] true标签isTaggedPart/hasTaggedPart/isVolatileTaggedMessage据此识别与去重。规则被 cache-safety 属性测试强制永不修改或重排早期消息、永不注入无标签 part、永不把时间戳或随机性放进尾部之前的注入内容。缓存断点提示SyntheticPartCacheHinttype: ephemeral | persistent可选ttlSeconds会被复制到创建的 part 上供 anthropic-messages / google-vertex / bedrock-converse / openrouter 等作为手动 cache-breakpoint 放置v1 调用方从不传它因此 v1 payload 保持字节一致而 v2 上下文桥通过runWithSyntheticPartCacheHintScopesetDefaultSyntheticPartCacheHint用AsyncLocalStorage隔离并发会话的默认提示——因为 v2 宿主并发服务不同会话的请求模块级全局变量会被跨会话的 set/restore 相互污染。Command hook helper 与消息类型src/hooks/command-hook-utils.ts 提供registerCommandHook(opencodeConfig, commandName, template, description)被 deepwork、reflect、loop 三个命令型 Hook 共享向 OpenCode 配置中注册命令若已存在则跳过并返回false。src/hooks/types.ts 定义统一的消息结构MessageInforole、agent、sessionID、id、MessageParttype、可选text、开放索引、MessageWithPartsinfoparts以及供 foreground-fallback 重放使用的辅助函数isReplayableUserMessage、partsFromReplayMessage——它同时兼容 v1 的{info, parts}形状和 v2 的{type: user, text}形状OpenCode 1.18 起的 SDK HTTP API。Hook 分类总览原 codemap 用一张表概括了六大类 Hook 与其挂载点完整继承如下CategoryFactoriesHook pointsPrompt transformscreatePhaseReminderHook、createPostFileToolNudgeHook、createChatHeadersHook、task-session-manager board injection、processImageAttachmentsexperimental.chat.messages.transform、chat.headersTool interceptioncreateApplyPatchHook(tool)、createSearchPathGuardHook、task-session-managertool.execute.before/tool.execute.afterError recoverycreateJsonErrorRecoveryHook、createAutoUpdateCheckerHookmessage transform、tool-execute afterLifecycle/eventtask-session-manager、createCacheMonitorHook、createOrchestratorWakeSchedulereventRuntime commandscreateDeepworkCommandHook、createReflectCommandHook、createLoopCommandHookcommand.execute.beforeSkill visibilitycreateFilterAvailableSkillsHookmessage transformModel fallbackForegroundFallbackManagerevent-drivenmessage.updated/session.error/session.status这张表的落地位置在 src/index.ts 返回的插件对象中event处理器L1435 起、command.execute.beforeL1767 起、chat.headersL1805、chat.messageL1809 起、experimental.chat.system.transformL1942 起、experimental.chat.messages.transformL2007 起、tool.execute.beforeL1740 起与tool.execute.afterL2084 起。消息处理管线转换链的装配顺序原 codemap 给出了消息处理流程其关键点是experimental.chat.messages.transform中的组合顺序是刻意编排的。对照 src/index.ts 的实现实际执行顺序为OpenCode 收到聊天消息插件先做一轮显示名改写对所有 user 消息的文本 part 执行rewriteDisplayNameMentions把 agent 显示名提及规范化为运行时 agent 名processImageAttachments处理图片附件当 orchestrator 模型不支持图片输入时将图片字节替换为委托给 observer的文本提示并在 60 秒内只弹一次 toast见IMAGE_SKIPPED_DEBOUNCE_MStask-session-manager 先执行先稳定仍在运行的任务 tool part再重水合rehydrate历史运行中的任务最后通过 cache-safe helpers 注入 Background Job Board——这一步必须在提醒门控之前做以修复会话映射随后依次执行postFileToolNudge文件工具后提示、phaseReminder阶段提醒、filterAvailableSkills按 agent 权限策略过滤可见技能最后由taskSessionManagerHook.injectBackgroundJobBoard在尾部注入作业看板转换后的消息发往模型chat.headers转发到 OpenCode 的 header 槽位v1 宿主直接转发v2 宿主由 adapter 桥接到session.hook(model.request)详见 src/v2/codemap.md模型响应/事件被 cache monitor遥测与 orchestrator-wake scheduler空闲唤醒计时观察。工具拦截链的顺序同样讲究。tool.execute.before按此顺序执行applyPatch→absolutePathRescue→searchPathGuard→taskSessionManagerHook→toolLoopGuard。注释明确指出路径救援必须先于搜索守卫否则守卫会先拦截掉 grep/glob 在缺失路径上的调用救援永远见不到可救的路径而 tool-loop-guard 必须放在所有可能拒绝的 before 钩子之后否则被拒绝的调用不会产生tool.execute.after事件会在 pending 调用表里留下永不消费的条目。tool.execute.after则全部包了一层wrapPostToolHook做错误隔离单个钩子失败只记日志不阻塞其余钩子。Hook 注册流程Hook 的装配没有中央注册表而是在调用点直接组合插件初始化src/index.ts 的OhMyOpenCodeLite工厂依次调用各个 Hook 工厂得到 handler 对象src/index.ts把返回的 handler 直接接进插件对象的 hook 字段tool.execute.before、event、chat.headers等有状态的 Hook 通过SessionLifecycle.onSessionDeleted注册清理回调OpenCode 在消息/工具/事件生命周期中按需调用这些 Hook。值得注意的是config钩子deepworkCommandHook.registerCommand、reflectCommandHook.registerCommand、loopCommandHook.registerCommand都通过registerCommandHook在 OpenCode 配置阶段注册各自命令这正是命令型 Hook与配置装配结合的体现。事件观察event hook事件钩子是插件感知会话状态的主要通道src/index.ts 的扇出顺序清晰可读token 流增量事件直接短路message.part.delta、session.next.text.delta、session.next.reasoning.delta在每个推理/文本 chunk 都会触发插件没有对应工作直接return避免无谓扇出cache monitor观察完成的 assistant 消息中的tokens.cache.read/write记录 prompt-cache bust/plateau 警告纯观察fail opentask-session-manager将created、idle、busy、error、deleted、server.instance.disposed等会话生命周期事件路由给其 reconcilerorchestrator-wake scheduler追踪连续父会话空闲并触发周期唤醒提示受hasInputWait与 continuation-model 接缝门控TUI 状态簿记session.status的 busy/retry/idle/completed/stopped/error/failed、message.updated的 provider/model、session.created的父子链接都被记录用于侧边栏活动展示与模型继承解析foreground-fallback消费message.updated/session.error/session.status检测限流与错误触发运行时模型回退session.deleted事件统一触发sessionLifecycle.dispatchSessionDeleted随后清理会话元数据。dispose钩子也值得一提它依次释放 terminal gate、取消 foreground fallback 的初始延迟定时器、向 task-session-manager 与 orchestrator-wake 广播server.instance.disposed、调用clearAllWakeSessions()清空进程级 wake 门保证opencode reload后新一代插件不会继承旧代的两次唤醒无进展上限、释放 admission runtime 租约。缓存安全注入从实现到验证闭环缓存安全不是口号仓库为其构建了四层互补验证见 docs/cache-verification.md持续 CI 测试bun testsrc/hooks/cache-safety.property.test.ts 把增长中的对话反复经过真实转换管线镜像src/index.ts的组合顺序断言回合间字节前缀稳定性、易变内容隔离到带标签尾消息、在墙钟/随机性变化下的确定性并有一个 drift guard——当src/index.ts增删或重排转换步骤而测试未同步更新时直接失败src/hooks/cache-payload.snapshot.test.ts 对插件注入的每个 prompt 表面phase reminder、orchestrator 系统提示、规范转换 payload做黄金快照src/cache-safety-tripwire.test.ts 扫描 prompt 组装目录检索Date.now、Math.random、randomUUID、performance.now等易变输入模式。离线确定性载荷验证bun run verify:cache-stability需要预先精确提供opencode-ai1.18.2的二进制路径OPENCODE_BIN/absolute/path/to/node_modules/.bin/opencode在本地捕获 provider 上断言四个主模型请求、system/tool/options 投影稳定、对话输入追加式前缀稳定等。在线缓存冒烟bun run cache:smoke一键启动真实opencode serve运行脚本化场景plain、tools、nudge、todos、long、board、board-churn、running-lane、agents读取 assistant 消息的tokens.cache.read/write并给出判定检测 SUSPECT非首请求、输入 ≥4096 token、读到 0 缓存与 plateaucache-read冻结在相同非零值 ≥3 次且累计 ≥6144 未缓存输入两种失败签名。退出码 0/1/2/3 分别表示正常/检测到失效/无结论/设置错误。运行时缓存监控src/hooks/cache-monitor/index.ts 是纯观察型的现场安全网。它订阅message.updated只解析完成态消息time.completed存在对每会话维护状态并输出三类警告警告触发条件含义possible prompt-cache bust会话此前命中过缓存随后某个 ≥2048 token 的请求读到 0 缓存 token同一 bust 段仅一次会话中途 prompt 前缀字节发生变化never hit the provider cache从首轮起每个 ≥2048 token 请求都读 0 缓存连续 ≥3 次且累计未缓存输入 ≥100K token每会话一次前缀每轮都在变v2.2.5 checkpoint-board 回归的现场形态或 provider 无 prompt cachecache-read plateaucache-read冻结在同一非零值连续 ≥4 次且期间累计 ≥50K 未缓存输入issue #874 签名可复用前缀停止增长建议改用backgroundJobs.strategy: checkpoint-compatible状态有界最多跟踪 256 个会话、每会话 512 条消息 ID超出即淘汰最旧项。集成全景消费者、子目录与依赖消费者主插件src/index.ts从桶出口导入全部工厂并装配 handlertask-session-manager所有 prompt 注入都依赖cache-safe-injection.ts删除协调依赖session-lifecycle.tsorchestrator-wake以 task-session-manager 的hasInputWait与 continuation-model 接缝为门控foreground-fallback使用 src/hooks/types.ts 的重放辅助isReplayableUserMessage、partsFromReplayMessage并把可重试/延迟错误上报给 task-session-manager 的事件路由器。子目录职责继承自原 codemap 并补充源码信息DirectoryResponsibilityabsolute-path-rescue/通过重新锚定最长工作区后缀匹配改写猜错且 ENOENT 的绝对工具路径仅限无歧义候选apply-patch/结构化apply_patch的解析、匹配、恢复、重写管线auto-update-checker/启动更新检测、缓存处理、可选安装提示cache-monitor/纯观察型 prompt-cache 遥测看门狗deepwork//deepwork运行时命令filter-available-skills/按 agent 权限策略过滤技能可见性foreground-fallback/交互式会话在限流/错误时的模型回退json-error-recovery/畸形 JSON / 工具输出恢复辅助loop-command//loop迭代重试命令orchestrator-wake/周期 orchestrator 唤醒调度器 进程级门phase-reminder/强制 orchestrator 工作流阶段的提醒转换post-file-tool-nudge/读/写文件后提示委托感知的下一步reflect//reflect运行时命令search-path-guard/在tool.execute.before中按宿主工具路径解析语义预检grep/glob的args.path以可操作的错误快速失败替代上游 ripgrep execution failed 噪音或静默的父目录搜索task-session-manager/可恢复任务会话跟踪、作业看板注入、对账tool-loop-guard/检测字节完全相同的重复工具调用第 3 次警告、第 5 次阻断带任务生命周期豁免与每回合 wait 工具计数依赖OpenCode SDKMessageWithParts、MessageInfo与 Hook 签名类型Node.jsfs、crypto图片附件、带标签 part 哈希Utilssrc/utils/ 下的logger、guards、任务解析、internal-initiator parts。错误处理与性能考量原 codemap 的最后两个小节总结了工程取舍直接继承并展开错误处理三原则Hook 全部 best-effort文件系统/转换失败只记日志Hook 继续处理剩余消息cache monitor 对任何意外事件形状 fail open遥测绝不阻断事件处理orchestrator-wake scheduler 在 SDK 错误时选择抑制而不是重试风暴。性能考量缓存安全优先所有注入必须走 tagged/volatile 辅助函数以保留 provider prompt-cache 前缀对应backgroundJobs.strategy的两种模式——latest替换先前看板消息checkpoint-compatible保留它们只追加变化的看板快照见 src/config/schema.ts防抖清理图片清理与运行时状态对账跑在定时器上而非每个事件有界状态cache monitor 与 wake gate 都设定了跟踪会话上限如 cache monitor 的 256 会话 / 512 消息idle 对账用每会话 token 使过期定时器失效。小结src/hooks/是 oh-my-opencode-slim 全部运行时行为的中枢。它用工厂桶出口 调用点组合的组织方式保持装配透明用 SessionLifecycle 统一会话清理语义用 cache-safe-injection 把向出站 payload 加内容收敛为唯一且经过属性测试、快照测试与线上监控三重保障的通道再用精心编排的转换链与工具拦截链支撑起多 Agent 编排、后台任务看板与模型回退等上层能力。理解这套 Hook 架构是深入这个插件其余一切模块agents、task-session-manager、orchestrator-wake、foreground-fallback的前提。赞分享人工智能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点击查看免费下载相关推荐oh-my-openagentomo-opencodeHooks 架构全解54 个生命周期 Hook 的五层编排体系oh my openagentomo opencodeHooks 架构全解54 个生命周期 Hook 的五层编排体系 本篇技术指南围绕 OmOoh my人工智能AI Agent代码智能体多智能体MCP ClientsAgent 编排告别臃肿右键菜单用ContextMenuManager一步到位完成Windows右键菜单终极清理告别臃肿右键菜单用ContextMenuManager一步到位完成Windows右键菜单终极清理 上个月帮朋友装了几款日常软件一周后他的右键菜单就长成了小人工智能AI AgentAgent 编排AI 技能oh-my-opencode-slim 插件核心工具层源码导读src/utils 的后台任务生命周期、会话管理与安全基础设施oh my opencode slim 插件核心工具层源码导读src/utils 的后台任务生命周期、会话管理与安全基础设施 导读 src/utils/人工智能AI AgentAgent 编排AI 技能上一篇任务栏空间告急RBTray为你重新定义Windows窗口管理下一篇NetCoreServer实战案例如何用10行代码构建高并发网络服务创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表