
【免费下载链接】aos-ceAOS Community Edition: the open agent operating system.项目地址https://gitcode.com/gh_mirrors/ao/aos-ce点击查看免费下载aos-hook-adapter-oracle是 AOSAOS Community Edition中负责前端钩子协议翻译的胶囊capsule它将经过认证校验的 Codex、Claude、Grok 前端 hook 信封转换为 AOS 标准的hook.v1.event.*协议事件。本文基于 README、实现源码 与 钩子架构文档 完整梳理该适配器的职责边界、事件映射表、响应模式、信封校验规则与发布/订阅配置帮助你理解 AOS 中前端协议翻译与标准钩子策略解耦这一设计的落地方式。一、定位与职责边界只做翻译不做裁决README 对适配器职责的界定非常明确该胶囊只拥有协议翻译职责owns protocol translation only不拥有下游钩子策略也不把观察事件observation events转化为授权决策。两条具体边界值得强调user_prompt_submit只收集有界的additional_context回复且只针对当前精确的宿主回合exact host turn收集pre_tool_use与permission_request在本中继上是纯观察事件原生工具native tool的拒绝deny决策仍留在astrid-gate/broker 的决策路径上——只有那条路径的响应 schema 才能表达 deny。这一点在源码中有直接印证。[src/lib.rs](https://link.gitcode.com/i/5b6c4ce80874e0a99f05972323f58a7f)中定义了两个响应模式#[derive(Debug, Clone, Copy, PartialEq, Eq)] enum ResponseMode { /// Publish the canonical event but do not attach a reply solicitation. Observe, /// Collect bounded additional_context for the exact host turn. AdditionalContext, }docs/hooks.md中给出的整体管道也说明了适配器的位置frontend plugin - authenticated ingress in capsule-mcp - exact oracle.v1.hook.validated.frontend topic - one frontend adapter // 即本胶囊 - canonical hook.v1.event.semantic-hook - zero or more independent subscriber capsules - optional correlation-scoped replies - adapter-shaped frontend response即认证入口ingress在capsule-mcp中完成本胶囊订阅已验证主题oracle.v1.hook.validated.frontend翻译后发布到标准钩子总线最终由capsule-mcp把响应按前端传输支持的形状回传。AOS 将标准钩子总线与任何特定 agent 产品解耦因此新增前端只需新增一个适配胶囊而不必改动路由器或内核。二、入口三个每个认证主题恰好一个所有者的处理器本胶囊在 Capsule.toml 中声明了它订阅的三个已验证主题与三个处理函数[subscribe] # Exactly one adapter owns each authenticated frontend topic. No priority is # set: these are protocol ingress points, not a middleware chain. oracle.v1.hook.validated.codex { wit opaque, handler on_codex_hook } oracle.v1.hook.validated.claude { wit opaque, handler on_claude_hook } oracle.v1.hook.validated.grok { wit opaque, handler on_grok_hook } # Dynamic, correlation-scoped response collection for prompt-context hooks. hook.v1.response.message_received.* { wit opaque }[publish]部分声明两条出口[publish] hook.v1.event.* { wit unicity-astrid/wit/hook/hook-event-request } oracle.v1.hook.response.* { wit opaque }源码中三个处理器通过#[astrid::interceptor(...)]宏注册全部汇入同一个入口函数handle_oracle_hook(expected: Frontend, payload)以Frontend::Codex / Claude / Grok枚举区分前端#[capsule] impl OracleHookAdapter { #[astrid::interceptor(on_codex_hook)] pub fn on_codex_hook(self, payload: serde_json::Value) - Result(), SysError { handle_oracle_hook(Frontend::Codex, payload) } // on_claude_hook / on_grok_hook 同构 }注释明确写道每个精确的已验证主题恰好由一个适配器拥有exactly one adapter owns each authenticated frontend topic。docs/hooks.md进一步指出同一 raw 主题上安装第二个适配器属于部署错误——raw 协议入口只有一个所有者扩展发生在下游的标准钩子主题上。这也是配置中刻意不设置priority的原因它们是协议入口点不是中间件链。三、事件映射表三个前端各自的翻译规则适配器为每个前端维护独立的事件映射表源码注释说明这是有意为之上游插件当前已归一化到通用名称但每个前端可以独立演化而不会削弱其他适配器的接受面。映射函数结构为common_mapping(event)三个前端共享的通用映射codex_mapping / claude_mapping / grok_mapping各前端对stop等特殊事件的差异化处理其余事件回落到common_mapping。3.1 通用映射common_mapping前端事件标准钩子canonical_hook响应模式session_startsession_startObservesession_endsession_endObserveuser_prompt_submitmessage_receivedAdditionalContextpre_tool_usebefore_tool_callObservepermission_requestbefore_tool_callObservepost_tool_useafter_tool_callObservepre_compacton_compaction_startedObservepost_compacton_compaction_completedObservesubagent_startsubagent_startObservesubagent_stopsubagent_stopObserve表中除user_prompt_submit外全部为Observe模式。源码对pre_tool_use | permission_request的注释点明了原因本中继外层响应 schema 只能携带 context因此这些事件在此只是观察绑定原生工具决策走astrid-gate。3.2 三个前端的差异stop与message_display这是 README 着墨最多、也是适配器中最容易被误解的部分前端事件映射结果原因Codexstopmessage_sentper-turn 事件携带last_assistant_messageClaudestopmessage_sent同上Claudemessage_displaymessage_displayed渲染期间以delta携带响应文本Grokstopsession_end兼容性例外Codex 与 Claude 的stop是回合级响应事件而非会话终止它们携带已完成回合的last_assistant_message因此发布为标准message_sent只有显式的session_end事件才映射为标准session_end。Grok 是显式的兼容性例外当前安装的 Grok hook 契约没有暴露一个独立的、已验证的终止事件因此其stop被映射为标准session_end。源码注释写道在 Grok 上游 hook 契约提供独立的、已验证的 per-turn 响应事件之前保留现有解释。Claudemessage_display把渲染中的delta批次发布为标准message_displayedCodex 侧对message_display返回None不支持。单元测试对这四条规则做了精确断言见 src/lib.rs 测试模块#[test] fn codex_and_claude_stop_are_response_events_not_session_termination() { assert_eq!(Frontend::Codex.mapping(stop), Some(observe(message_sent))); assert_eq!(Frontend::Claude.mapping(stop), Some(observe(message_sent))); assert_eq!(Frontend::Codex.mapping(session_end), Some(observe(session_end))); assert_eq!(Frontend::Claude.mapping(session_end), Some(observe(session_end))); } #[test] fn grok_stop_remains_an_explicit_session_termination_exception() { assert_eq!(Frontend::Grok.mapping(stop), Some(observe(session_end))); }docs/hooks.md补充了一条关键结论这些响应事件在本中继上是观察性质的——下游策略可以检查和报告它们但不能声称收回前端已经产出的文本cannot claim to retract text that the frontend has already produced。四、信封格式与校验OracleHookEvent的完整字段约束上游capsule-mcp完成 bearer token 认证并剥离 token 后本胶囊收到的是无 token 的已验证信封。源码中的反序列化结构如下#[derive(Debug, Deserialize)] struct OracleHookEvent { schema_version: u8, principal_id: String, host: String, session_id: String, event: String, correlation_id: String, route_id: String, delivery_id: String, #[serde(default)] turn_id: OptionString, #[serde(default)] workspace_id: OptionString, payload: serde_json::Value, }validate_oracle_hook对该信封执行一组严格校验任一失败都会记 warn 日志并丢弃该事件仍返回 Ok不让上游重试风暴校验项规则失败原因字符串schema_version必须等于 1unsupported schema versionhost绑定必须与已验证主题对应的前端名一致codex/claude/grokhost does not match validated topic事件支持性前端映射表中必须存在该事件unsupported host eventsession_id/event/delivery_id干净分段非空、≤128 字节、仅 ASCII 字母数字加_-invalid routed segmentroute_id小写十六进制恰好 64 字符invalid route identifiercorrelation_id小写十六进制恰好 32 字符invalid route identifierdelivery_id绑定必须等于{route_id}-{correlation_id}delivery identifier does not bind route and correlationturn_id若存在非空且 ≤256 字节invalid optional routing metadataworkspace_id若存在干净分段 ≤128 字节invalid optional routing metadatapayload序列化后 ≤ 1 MiBMAX_HOST_PAYLOAD_BYTES 1024 * 1024host payload exceeds limit干净分段校验同时承担了主题走私防护session_id中不允许出现.is_clean_segment只接受 ASCII 字母数字、_、-因此类似../session或codex.session的值都会被拒绝无法通过段名注入改变主题路由。测试用例直接验证了这一点#[test] fn event_and_session_cannot_add_topic_segments() { let mut event host_event(codex); event.session_id codex.other.to_owned(); assert_eq!( validate_oracle_hook(Frontend::Codex, event), Err(invalid routed segment) ); }此外还有一个身份一致性检查handle_oracle_hook会用runtime::caller()取内核打戳kernel-stamped的调用者主体与信封中的principal_id比对不一致即丢弃。这是前端进程不可信命名主体原则的落点——认证由内核打戳的调用方身份背书而非信封自述。五、发布路径标准事件如何带上双重命名翻译完成后dispatch_oracle_hook按响应模式分两条路径Observe 模式直接ipc::publish_json(hook.v1.event.{hook}, request)不订阅任何回复主题AdditionalContext 模式先订阅hook.v1.response.message_received.{correlation_id}再发布事件然后进入有界的上下文收集循环。发布到标准总线的请求体是HookEventRequest来自astrid_sdk::contracts::hook其payload字段是一个CanonicalOraclePayload结构为#[derive(Debug, Serialize)] struct CanonicalOraclePayloada { principal_id: a str, host: a str, session_id: a str, source_event: a str, // 原始前端事件名如 stop、user_prompt_submit #[serde(skip_serializing_if Option::is_none)] turn_id: Optiona str, #[serde(skip_serializing_if Option::is_none)] workspace_id: Optiona str, payload: a serde_json::Value, // 原始前端 payload 嵌套保留 }注意两个设计要点原始 payload 嵌套保留nested under canonical provenance而不是把不可信的键扁平化进信封——这是 docs/hooks.md Adding a frontend 清单中的第 5 条correlation_id只在 AdditionalContext 模式下透传到标准请求观察类事件保持无关联测试canonical_request_keeps_observation_uncorrelated验证了 observe 请求的correlation_id为None避免下游订阅者误以为可以对该事件做出响应整个标准事件序列化后不得超过MAX_CANONICAL_EVENT_BYTES1 MiB超限直接以HostError失败。测试canonical_events_retain_user_prompt_and_assistant_response_text验证了文本保留语义user_prompt_submit的prompt文本与 Codexstop的last_assistant_message都原样出现在标准事件的嵌套payload中source_event字段分别保留为user_prompt_submit与stop。六、user_prompt_submit的有界上下文收集message_received是唯一走 AdditionalContext 模式的事件。collect_additional_context的实现约束如下均为 src/lib.rs 中的常量常量值语义HOST_HOOK_COLLECT_DEADLINE_MS1000 ms收集总截止期HOOK_QUIESCENCE_MS25 ms收到至少一条回复后的静默窗口MAX_HOST_CONTEXT_BYTES64 KiB合并后上下文的总字节上限收集循环的行为动态等待窗口尚无回复时等待剩余总时限已有回复后只等待 25 ms 静默窗口收到一批回复后即尽快收敛回复身份过滤只接受回复主题精确匹配 且 内核验证主体与principal_id相同的消息其余记 warn 并丢弃格式要求每条回复必须是含非空字符串additional_context字段的 JSON否则丢弃并记 warn整体作废语义若 IPC 轮询报告dropped ! 0或lagged ! 0扇出丢失/滞后则丢弃全部已收集的 partial context并返回None——宁可无上下文也不给出不完整上下文字节上限push_context以 checked 算术累计含 2 字节分隔符超过 64 KiB 的后续片段被丢弃。测试combined_context_stays_inside_relay_limit精确验证了上限边界两条 context 恰好填满 64 KiB含\n\n分隔符后第三条被拒。合并输出所有片段以\n\n连接成单个字符串作为响应信封中的context字段。这与docs/hooks.md中 Additional context 一节完全一致适配只接受同主体回复在 64 KiB 内合并若响应订阅报告 lag 或 loss 则丢弃整个部分结果。七、响应回传与路由生命周期canonical_hook的双字段设计处理结束后适配器把响应发布到oracle.v1.hook.response.{delivery_id}响应结构为#[derive(Debug, Serialize)] struct OracleHookResponsea { schema_version: u8, principal_id: a str, host: a str, session_id: a str, /// 由本前端适配器选定的标准生命周期/观察分类。 /// 源前端事件仍保留在 event 字段中。 canonical_hook: a str, event: a str, correlation_id: a str, route_id: a str, delivery_id: a str, #[serde(skip_serializing_if Option::is_none)] context: OptionString, }README 对canonical_hook与event分开的解释是适配器响应把源event与canonical_hook独立保留这样认证路由的清理cleanup可以跟随标准生命周期语义同时不抹掉前端溯源信息frontend provenance。这条设计如何被消费看 capsule-mcp 的 host_hooks 模块relay_response订阅oracle.v1.hook.response.*重新校验主体、会话 token 与route_id由host session_id token经 blake3 派生derive_route_id然后中继到精确的astrid.v1.response.{delivery_id}主题——即前端 uplink 等待的响应retires_session_route决定何时清理已认证路由删除 KV 中的 session token响应带canonical_hook仅当canonical_hook session_end时才退役路由。因此 Codex/Claude 的stopcanonical 为message_sent不会退役路由Grok 的stopcanonical 为session_end则会分阶段升级兼容若响应没有canonical_hook旧版适配器只有源event显式为session_end时才退役。测试only_real_session_end_retires_the_authenticated_route覆盖了这条兼容矩阵的全部四个分支。同时注意入口侧的对称约束capsule-mcp只在session_start或user_prompt_submitcan_register时向 KV 注册 session token32–128 字节、纯 ASCII 字母数字并用恒定时间比较tokens_match逐字节异或校验 token验证通过后才发布无 token 的ValidatedHostHook到oracle.v1.hook.validated.{host}。测试validated_shape_does_not_contain_token断言了已验证信封中不存在token字段。八、下游订阅的约定省略 priority保持独立扇出README 的最后一句给出了对下游标准钩子订阅者的规范约定通常应省略priority以保持独立扇出independent fan-out。docs/hooks.md 对此有完整契约观察类订阅者不要设置 priority。相等的默认优先级保持独立并发扇出每个订阅者都看到原始事件且一个订阅者无法抑制另一个不要用 priority 给前端适配器排序——每个已认证 raw 主题只有一个适配器所有者只有对显式声明为绑定binding的中间件主题才设置优先级且此时同一主题上的所有匹配处理器会从扇出转为单一有序链。文档为绑定中间件保留了指导性优先级带优先级带用途要求行为10-19校验与归一化当安全依赖拒绝时畸形输入返回Deny而非Err20-39安全与策略收窄deny 可中断链任何层不得扩大先前授权40-79确定性转换转换后的 payload 必须显式且经过测试80-99富化enrichment不得把 deny 重新解释为 allow100provider/应用执行只接收前一阶段接受的 payload九、构建形态与依赖从 Cargo.toml 可见该胶囊以cdylib形式编译为 WASMCapsule.toml中组件文件为aos_hook_adapter_oracle.wasm类型为executable运行于astrid-version 0.10.1依赖仅astrid-sdk、serde、serde_json。源码头部开启#![deny(unsafe_code)]、#![deny(clippy::all)]与#![warn(missing_docs)]是一个完全无 unsafe 的纯协议转换实现。十、如何扩展新增前端时的检查清单docs/hooks.md 的 Adding a frontend 一节该适配器的映射表与校验代码正是这份清单的实践给出了 8 步清单可作为参照实现核对添加认证入口与前端专属的已验证主题添加一个适配胶囊或一张隔离的 handler 表做精确的主题/host 绑定只映射语义真正等价的事件把每条映射分类为 observation / context / binding把原始 payload 嵌套保留在标准溯源之下不扁平化不可信键对输入、标准输出、关联标识、回复与等待时间全部设定边界添加负面测试跨主题 host 声明、主体不一致、主题走私、过期路由、超尺寸 payload、回复丢失、不支持的事件不改动内核——翻译与策略都属于胶囊层。本胶囊自带的负面测试恰好覆盖了清单中的多数项跨主题 host 声明each_validated_topic_binds_its_exact_host、delivery 绑定delivery_binds_route_and_correlation、主题走私event_and_session_cannot_add_topic_segments、上下文边界combined_context_stays_inside_relay_limit与观察/上下文模式区分canonical_request_keeps_observation_uncorrelated。小结aos-hook-adapter-oracle展示了 AOS 前端钩子体系的一个关键设计把翻译从策略中剥离。它用独立映射表消化三个前端在stop语义上的差异用严格分段/十六进制/字节边界校验抵御主题走私与超尺寸输入用eventcanonical_hook双字段让路由生命周期清理既不破坏前端溯源、又与标准事件语义对齐并用部分丢失即整体作废的上下文收集策略保证additional_context要么完整、要么不存在。对于要在此体系上添加新前端、或编写下游hook.v1.event.*订阅胶囊的开发者上述映射表、信封约束与 priority 约定就是可以直接对照实施的契约。赞分享【免费下载链接】aos-ceAOS Community Edition: the open agent operating system.项目地址https://gitcode.com/gh_mirrors/ao/aos-ce点击查看免费下载相关推荐Impeccable Design Hook 实战指南在 Claude Code、Cursor、Codex、Grok 与 Copilot 中为 UI 文件安装自动设计检测钩子Impeccable Design Hook 实战指南在 Claude Code、Cursor、Codex、Grok 与 Copilot 中为 UI 文件安装AI 技能前端CLIdsh-pluginUnicity AOSaos-ceCapsule 构建全生命周期实战从脚手架、编译、安装到诊断与升级Unicity AOSaos ceCapsule 构建全生命周期实战从脚手架、编译、安装到诊断与升级 本文基于 aos ce 仓库中 capsule foUnicity AOS 元框架实战aos-ce 中 meta-harness Skill 如何驱动智能体主动扩展自身世界Unicity AOS 元框架实战aos ce 中 meta harness Skill 如何驱动智能体主动扩展自身世界 本文以 aos ce 仓库中 met上一篇Flipper Zero社区治理终极指南如何建立高效的贡献者协作体系下一篇Java注解继承toBeBetterJavaer元注解组合创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考