ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

如何开发Aether扩展:Extension API教程,给AI Agent注入自定义设置页与实时Widget

如何开发Aether扩展:Extension API教程,给AI Agent注入自定义设置页与实时Widget

【免费下载链接】Aether

Codex for Android, iOS & Mac. | Aether 扶摇

项目地址:https://gitcode.com/gh_mirrors/aether33/Aether
点击查看免费下载

Aether 是一款运行在 Android、iOS 与 Mac 上的 AI Agent 应用(被称为"口袋里的 Codex")。它最大的亮点之一是开放的Extension API:你只需一个包含 TypeScript 脚本的 npm 包,就能给 Aether 的 AI Agent 注入自定义设置页、实时 Widget、命令、拦截器等能力。本教程带你从零搭建第一个 Aether 扩展包,理解"Surface 表面插槽 + 声明式 UI 树 + 原生设置页"三件套,并附上官方示例与常见坑位。

一、先看懂:Aether 扩展包的三种形态

Aether 沿用 Pi Coding Agent 的"可信代码"扩展模型,一个扩展包可以同时包含三种能力(完整定义见 docs/AETHER_EXTENSIONS.md):

形态配置字段特点
Pi 扩展pi.extensionsAgent 工具、命令、hooks,与 Pi 生态兼容
Script 扩展aether.extensionsTypeScript/JS 编写,热重载,可直接改 UI 与应用逻辑
Native Modaether.nativeKotlin/DEX 编译产物,可直接调用 Android 与 Compose,需重启加载

包结构非常直观,本质上就是一个package.json加入口脚本:

{ "name": "my-aether-mod", "version": "1.0.0", "pi": { "extensions": ["./agent.ts"] }, "aether": { "api": { "min": 2, "max": 2 }, "extensions": ["./android.ts"] } }

⚠️ 注意:Aether 有意不做权限沙箱——安装扩展即意味着信任它可以访问 Node 运行时、Android 应用上下文与本地工作区。请只安装你信任的扩展。

导入后的扩展会放在 Aether 托管的 Alpine 文件系统中(~/.aether/extensions),所有入口脚本都被监听,文件改动后自动原子化热重载;加载失败时保留上一个可用运行时,错误会显示在 Extensions 页面上。

二、一键搭建:创建并导入你的第一个扩展

1. 克隆仓库获取参考代码

git clone https://gitcode.com/gh_mirrors/aether33/Aether

2. 安装类型声明包(只含类型声明,运行时实现由 Aether 注入):

npm install --save-dev @baimoqilin/aether-extension-api

声明源码位于 packages/extension-api/src/index.ts,AetherExtensionAPI接口就是你在扩展里能拿到的全部能力:ui、host、services、state、storage、messages以及一系列register*方法。

3. 编写入口脚本。官方示例 examples/aether-extension/index.ts 是最小完整参考:

import { defineAetherExtension, ui } from "@baimoqilin/aether-extension-api"; export const activateAether = defineAetherExtension((aether) => { aether.registerSurface("chat.composer.top", { id: "quick-tools", render: ({ storage }) => ui.card([ ui.row([ ui.button(`Count ${storage.count ?? 0}`, "increment", { tone: "neutral" }), ui.button("Prefill", "prefill"), ], { wrap: true }), ]), }); });

4. 打包导入:将目录压缩为 zip,在 Aether 的设置 → Extensions(扩展页)中点击导入即可(导入逻辑实现于 PiExtensionManager.kt,会自动处理npm ci --omit=dev依赖安装)。

三、实时 Widget:registerSurface 与声明式 UI 树

想给 AI Agent 界面加一块实时刷新的状态卡片,用registerSurface把内容"塞"进指定插槽即可,无需替换任何内置 UI。常用插槽一览:

插槽位置
chat.top聊天顶栏下方
chat.list.start/chat.list.end消息列表首/尾
chat.composer.top输入框正上方(Widget 最佳位置)
settings.hub设置中枢顶部
drawer.header/drawer.footer会话抽屉固定头/尾
aether.registerSurface("chat.composer.top", { id: "status", order: 10, render: ({ is_running, draft_input, storage }) => ui.row([ ui.text(is_running ? "Agent running" : "Ready"), ui.text(`${String(draft_input).length} chars`), ui.text(`Count: ${storage.count ?? 0}`), ]), });

关键点:

  • 声明式 UI 树:ui.text / card / column / row / button / switch / input / progress / web等原语,最终由 Aether 用原生 Compose 渲染,视觉风格与内置界面完全一致;
  • 实时性:render接收的 context 含is_running、draft_input等公共状态,Agent 开始/结束、输入变化都会触发重渲染;
  • 持久化:aether.storage.get/set自动落盘到~/.aether/app-extension-state.json,重启不丢;
  • 响应交互:ui.button("Increment", "increment")点击后触发你注册的aether.registerAction("increment", ...),再调用aether.invalidate()即可局部刷新。

进阶:替换、包裹、隐藏内置组件

比 Surface 更强的是registerComponent,它针对具名内置组件提供before / after / replace / wrap / hide五种模式,按order排序、最后一个replace生效:

aether.registerComponent("chat.composer.skillPicker", { id: "remove-native-picker", mode: "hide", // 隐藏内置 Skill 选择器 order: 100, });

典型目标包括chat.screen、settings.screen、chat.composer.actionTray等。需要完全自由的 HTML 微界面时,还有ui.web({ height, html })逃生舱,可通过Aether.postMessage()回调回已注册的 action。

四、注入自定义设置页:registerSettings

这是扩展"原生感"最强的能力:registerSettings会在设置的Extensions 分组(位于 Reliability 与 Agent Skills 之间)里为你生成一整页原生设置,沿用 Aether 内置页的卡片、间距与字体——你只提供数据,不能覆盖样式。

aether.registerSettings({ id: "preferences", icon: "settings", title: "Preferences", subtitle: "Extension behavior", sections: [{ title: "General", settings: [ { id: "endpoint", type: "text", label: "Endpoint", default: "https://example.com" }, { id: "enabled", type: "toggle", label: "Enabled", default: true }, { id: "mode", type: "select", label: "Mode", options: [ { value: "fast", label: "Fast" }, { value: "quality", label: "Quality" }, ], default: "fast" }, ], }], });
  • 支持的控件:text、password、textarea、number、toggle、select/dropdown、segmented、tab、slider、button、link、label、divider等,完整枚举见 AetherSettingType;
  • 值按扩展 × 页 × 设置项三元组自动持久化,热重载后自动恢复;
  • 支持categories二级分类,先显示分类列表再进入子页;
  • AI 也能改你的设置:Aether Agent 可通过aether_config_get({ categories: ["extensions"] })查看该页,并用aether_config_set替你调整开关和取值。

五、让扩展"活"起来:状态、服务与拦截

Script Mod 与 Aether 内核之间还有三条通道(接口定义见 docs/AETHER_EXTENSIONS.md):

  1. aether.state:读写公共状态,如draft_input(预填输入框)、selected_model_key(切模型)、agent_mode_enabled;支持transaction批量操作:
await aether.state.transaction([ { path: "draft_input", value: "Review the current changes." }, { path: "agent_mode_enabled", value: true }, ]);
  1. aether.services:可发现、可替换的服务注册表(内置skills、state等),高优先级注册可覆盖核心实现:
const skills = await aether.services.invoke("skills", "list");
  1. aether.intercept:拦截内置操作(如chat.new、skills.selection),返回{ cancel: true, reason }即可阻止操作——比如锁定某个 Skill 不允许取消。

此外还有低层aether.host.invoke()桥,覆盖app.sendMessage、app.newChat、app.setModel、runtime.execute(执行 Alpine/Termux 命令)等方法,详见宿主方法表。

六、官方示例与生态扩展巡礼

仓库自带可直接导入的参考实现:

  • examples/aether-extension/:Pi + Aether 双形态组合包,含输入框上方卡片、原生设置页、before_send事件改写,是最推荐的新手起点;
  • examples/global-skills-mod/:展示如何用声明式 UI 替换原生 action tray、直写 Aether 原生 Skill 选择服务,并新增全局 Skills 页——"组合 UI 替换 + 真实应用状态"的标准范式。

仓库extensions/目录下还有三个生产级扩展可作进阶阅读:

扩展能力
pi-mcp-adapter/接入任意 MCP Server,OAuth、工具审批、资源面板
pi-subagents/多 Agent 编排、调度、独立视图
pi-web-access/数十种搜索/抓取后端与网页提取

七、常见坑位与最佳实践清单

  • 🔁热重载是原子的:所有脚本工厂必须全部加载成功才会替换运行时;失败会保留旧运行时并在 Extensions 页报错。aether.api的min/max版本不兼容会直接拒绝加载;
  • 🚀Native Mod 需重启:DEX 类路径只在进程启动时发现,增删改 Native Mod 必须重启 Aether;崩溃循环时 Aether 会自动进入Native Mod Safe Mode(跳过全部 Native Mod 但保留脚本扩展),可在扩展页一键重新启用;
  • 📦依赖自动安装:zip 导入时,有 lockfile 走npm ci --omit=dev,否则npm install --omit=dev;捆绑的node_modules会原样使用;
  • 🎨只做数据,不碰样式:设置页与 Surface 的视觉由 Aether 原生渲染,别想着自定义布局;需要自由样式请用ui.web;
  • 📝命名规范:与 Pi 共用的包,把 Pi 工厂作为default export,Aether 工厂导出为activateAether,即可一份代码两端运行。

照着 examples/aether-extension/ 改三行代码,你就已经拥有第一个能跑在 AI Agent 里的实时 Widget 和原生设置页了。更多细节请阅读 docs/AETHER_EXTENSIONS.md 的完整 API 说明。

【免费下载链接】Aether

Codex for Android, iOS & Mac. | Aether 扶摇

项目地址:https://gitcode.com/gh_mirrors/aether33/Aether
点击查看免费下载

相关推荐

上一篇:OpenScholar 官方实现深度解析:基于 peS2o 检索与自反馈循环的科研文献综述生成管线
下一篇:bk-cmdb 业务容器拓扑树缓存接口(get_biz_kube_cache_topo)解析:一次请求取回 Cluster、Namespace、Workload 全量层级

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进