@iniesta8888/agent-live 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/CODE_OF_CONDUCT.md +7 -0
  2. package/CONTRIBUTING.md +56 -0
  3. package/LICENSE +21 -0
  4. package/README.md +92 -0
  5. package/SECURITY.md +13 -0
  6. package/dist/adapter-sdk/index.d.ts +45 -0
  7. package/dist/adapter-sdk/index.d.ts.map +1 -0
  8. package/dist/adapter-sdk/index.js +106 -0
  9. package/dist/adapter-sdk/index.js.map +1 -0
  10. package/dist/content/compiler.d.ts +31 -0
  11. package/dist/content/compiler.d.ts.map +1 -0
  12. package/dist/content/compiler.js +218 -0
  13. package/dist/content/compiler.js.map +1 -0
  14. package/dist/content/graph-validator.d.ts +56 -0
  15. package/dist/content/graph-validator.d.ts.map +1 -0
  16. package/dist/content/graph-validator.js +226 -0
  17. package/dist/content/graph-validator.js.map +1 -0
  18. package/dist/content/library.d.ts +4 -0
  19. package/dist/content/library.d.ts.map +1 -0
  20. package/dist/content/library.js +45 -0
  21. package/dist/content/library.js.map +1 -0
  22. package/dist/content/registry.d.ts +34 -0
  23. package/dist/content/registry.d.ts.map +1 -0
  24. package/dist/content/registry.js +130 -0
  25. package/dist/content/registry.js.map +1 -0
  26. package/dist/content/runtime-content.d.ts +63 -0
  27. package/dist/content/runtime-content.d.ts.map +1 -0
  28. package/dist/content/runtime-content.js +78 -0
  29. package/dist/content/runtime-content.js.map +1 -0
  30. package/dist/content/schema.d.ts +142 -0
  31. package/dist/content/schema.d.ts.map +1 -0
  32. package/dist/content/schema.js +280 -0
  33. package/dist/content/schema.js.map +1 -0
  34. package/dist/content/validator.d.ts +35 -0
  35. package/dist/content/validator.d.ts.map +1 -0
  36. package/dist/content/validator.js +205 -0
  37. package/dist/content/validator.js.map +1 -0
  38. package/dist/core/agents.d.ts +56 -0
  39. package/dist/core/agents.d.ts.map +1 -0
  40. package/dist/core/agents.js +148 -0
  41. package/dist/core/agents.js.map +1 -0
  42. package/dist/core/limits.d.ts +15 -0
  43. package/dist/core/limits.d.ts.map +1 -0
  44. package/dist/core/limits.js +16 -0
  45. package/dist/core/limits.js.map +1 -0
  46. package/dist/core/mapping.d.ts +17 -0
  47. package/dist/core/mapping.d.ts.map +1 -0
  48. package/dist/core/mapping.js +94 -0
  49. package/dist/core/mapping.js.map +1 -0
  50. package/dist/core/protocol.d.ts +105 -0
  51. package/dist/core/protocol.d.ts.map +1 -0
  52. package/dist/core/protocol.js +6 -0
  53. package/dist/core/protocol.js.map +1 -0
  54. package/dist/core/state.d.ts +49 -0
  55. package/dist/core/state.d.ts.map +1 -0
  56. package/dist/core/state.js +216 -0
  57. package/dist/core/state.js.map +1 -0
  58. package/dist/creator/commands.d.ts +19 -0
  59. package/dist/creator/commands.d.ts.map +1 -0
  60. package/dist/creator/commands.js +44 -0
  61. package/dist/creator/commands.js.map +1 -0
  62. package/dist/creator/mode.d.ts +10 -0
  63. package/dist/creator/mode.d.ts.map +1 -0
  64. package/dist/creator/mode.js +23 -0
  65. package/dist/creator/mode.js.map +1 -0
  66. package/dist/creator/service.d.ts +199 -0
  67. package/dist/creator/service.d.ts.map +1 -0
  68. package/dist/creator/service.js +159 -0
  69. package/dist/creator/service.js.map +1 -0
  70. package/dist/index.d.ts +14 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +10 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/runtime/agent-live-runtime.d.ts +17 -0
  75. package/dist/runtime/agent-live-runtime.d.ts.map +1 -0
  76. package/dist/runtime/agent-live-runtime.js +50 -0
  77. package/dist/runtime/agent-live-runtime.js.map +1 -0
  78. package/dist/runtime/content-service.d.ts +75 -0
  79. package/dist/runtime/content-service.d.ts.map +1 -0
  80. package/dist/runtime/content-service.js +60 -0
  81. package/dist/runtime/content-service.js.map +1 -0
  82. package/dist/runtime/resource-guard.d.ts +17 -0
  83. package/dist/runtime/resource-guard.d.ts.map +1 -0
  84. package/dist/runtime/resource-guard.js +54 -0
  85. package/dist/runtime/resource-guard.js.map +1 -0
  86. package/dist/runtime/server.d.ts +39 -0
  87. package/dist/runtime/server.d.ts.map +1 -0
  88. package/dist/runtime/server.js +286 -0
  89. package/dist/runtime/server.js.map +1 -0
  90. package/dist/web/app.d.ts +1 -0
  91. package/dist/web/app.js +1317 -0
  92. package/dist/web/index.html +45 -0
  93. package/dist/web/office.js +350 -0
  94. package/dist/web/sprites.js +185 -0
  95. package/dist/web/style.css +288 -0
  96. package/dist/web/v2/bootstrap.js +276 -0
  97. package/dist/web/v2/content/README.md +17 -0
  98. package/dist/web/v2/content/agent-skins/studio-team.json +33 -0
  99. package/dist/web/v2/content/agent-skins/tiny-developers.json +33 -0
  100. package/dist/web/v2/content/atmospheres/default.json +13 -0
  101. package/dist/web/v2/content/atmospheres/rainy-night.json +37 -0
  102. package/dist/web/v2/content/catalog.json +14 -0
  103. package/dist/web/v2/content/component-library/activity-implementations.json +873 -0
  104. package/dist/web/v2/content/component-library/activity-recipes.json +25 -0
  105. package/dist/web/v2/content/component-library/agent-profile-templates.json +18 -0
  106. package/dist/web/v2/content/component-library/catalog.json +38 -0
  107. package/dist/web/v2/content/component-library/npc-templates.json +42 -0
  108. package/dist/web/v2/content/component-library/props.json +41 -0
  109. package/dist/web/v2/content/environments/local-office.json +31 -0
  110. package/dist/web/v2/content/environments/rainy-night.json +28 -0
  111. package/dist/web/v2/content/environments/static-office.json +27 -0
  112. package/dist/web/v2/content/layouts/boardroom-office.json +122 -0
  113. package/dist/web/v2/content/layouts/demo-office.json +88 -0
  114. package/dist/web/v2/content/layouts/lively-office.json +96 -0
  115. package/dist/web/v2/content/layouts/old-school-office.json +154 -0
  116. package/dist/web/v2/content/layouts/tech-open-office.json +132 -0
  117. package/dist/web/v2/content/life-activities/boardroom-routines.json +67 -0
  118. package/dist/web/v2/content/life-activities/none.json +10 -0
  119. package/dist/web/v2/content/life-activities/office-basics.json +39 -0
  120. package/dist/web/v2/content/life-activities/old-school-routines.json +74 -0
  121. package/dist/web/v2/content/life-activities/tech-office-routines.json +148 -0
  122. package/dist/web/v2/content/npcs/boardroom-staff.json +54 -0
  123. package/dist/web/v2/content/npcs/none.json +10 -0
  124. package/dist/web/v2/content/npcs/office-staff.json +25 -0
  125. package/dist/web/v2/content/npcs/old-school-staff.json +39 -0
  126. package/dist/web/v2/content/npcs/tech-office-staff.json +40 -0
  127. package/dist/web/v2/content/official-offices/boardroom-office.json +25 -0
  128. package/dist/web/v2/content/official-offices/old-school-office.json +25 -0
  129. package/dist/web/v2/content/official-offices/tech-open-office.json +25 -0
  130. package/dist/web/v2/content/presets/boardroom-office.json +21 -0
  131. package/dist/web/v2/content/presets/cozy-studio.json +19 -0
  132. package/dist/web/v2/content/presets/demo-office.json +19 -0
  133. package/dist/web/v2/content/presets/lively-office.json +19 -0
  134. package/dist/web/v2/content/presets/night-shift.json +19 -0
  135. package/dist/web/v2/content/presets/old-school-office.json +20 -0
  136. package/dist/web/v2/content/presets/refined-demo.json +20 -0
  137. package/dist/web/v2/content/presets/tech-open-office.json +21 -0
  138. package/dist/web/v2/content/props/default-office.json +23 -0
  139. package/dist/web/v2/content/props/extended-office.json +39 -0
  140. package/dist/web/v2/content/props/tech-office.json +28 -0
  141. package/dist/web/v2/content/styles/pixel-classic.json +160 -0
  142. package/dist/web/v2/content/styles/warm-studio.json +150 -0
  143. package/dist/web/v2/environment-runtime.d.ts +1 -0
  144. package/dist/web/v2/environment-runtime.js +138 -0
  145. package/dist/web/v2/graph-validator.d.ts +55 -0
  146. package/dist/web/v2/graph-validator.js +225 -0
  147. package/dist/web/v2/i18n.js +54 -0
  148. package/dist/web/v2/locales/en.json +209 -0
  149. package/dist/web/v2/locales/zh-CN.json +52 -0
  150. package/dist/web/v2/office-engine.d.ts +1 -0
  151. package/dist/web/v2/office-engine.js +145 -0
  152. package/dist/web/v2/office-renderer.d.ts +1 -0
  153. package/dist/web/v2/office-renderer.js +843 -0
  154. package/dist/web/v2/parity.html +10 -0
  155. package/dist/web/v2/parity.js +82 -0
  156. package/dist/web/v2/sprite-renderer.d.ts +1 -0
  157. package/dist/web/v2/sprite-renderer.js +242 -0
  158. package/dist/web/v2/static-content.js +48 -0
  159. package/dist/web/v2/style.css +140 -0
  160. package/dist/web/v2.html +68 -0
  161. package/docs/ADAPTER-DEVELOPMENT.md +328 -0
  162. package/docs/ADAPTER-SDK.md +109 -0
  163. package/docs/ARCHITECTURE.md +223 -0
  164. package/docs/COMPONENT-LIBRARY.md +212 -0
  165. package/docs/CUSTOMIZATION.md +163 -0
  166. package/docs/DEVELOPER.md +186 -0
  167. package/docs/DSH-ADAPTER-DESIGN.md +173 -0
  168. package/docs/OFFICE-THEMES.md +516 -0
  169. package/docs/PRESET-CONFIG.md +460 -0
  170. package/docs/RELEASE-CHECK.md +23 -0
  171. package/docs/TECHNICAL.md +515 -0
  172. package/docs/USING-CODEX.md +24 -0
  173. package/docs/USING-DSH.md +44 -0
  174. package/docs/USING-PI.md +50 -0
  175. package/docs/VISION.md +146 -0
  176. package/examples/adapter/local-office.mjs +52 -0
  177. package/package.json +89 -0
  178. package/skills/agent-live-adapter-builder/SKILL.md +30 -0
  179. package/skills/agent-live-adapter-builder/agents/openai.yaml +4 -0
  180. package/skills/agent-live-adapter-builder/references/investigation.md +9 -0
  181. package/skills/agent-live-adapter-builder/references/review.md +7 -0
  182. package/skills/agent-live-adapter-builder/scripts/create-adapter.mjs +26 -0
@@ -0,0 +1,328 @@
1
+ # Agent Live Adapter 开发指南
2
+
3
+ > 这是宿主调研与官方贡献指南。直接实现代码请先读 [Adapter SDK](ADAPTER-SDK.md);也可以把仓库中的 `agent-live-adapter-builder` Skill 交给自己的 Coding Agent。
4
+
5
+ Adapter Package 封装一个宿主的全部接入差异:安装入口、官方事实转换、可选控制能力、正常生命周期和展示装配。它可以启动 Viewer、Runtime 或注册宿主原生 View,但不定义办公室画面,也不应猜测宿主没有提供的信息。
6
+
7
+ 本文是第三方 Adapter 的主入口。公共架构见 [ARCHITECTURE.md](ARCHITECTURE.md),事件类型以 [`protocol.ts`](../plugins/agent-live/src/core/protocol.ts) 为准,Pi 与 Codex 实现仅作为宿主专用参考。DSH 的第一阶段方案见 [DSH-ADAPTER-DESIGN.md](DSH-ADAPTER-DESIGN.md)。
8
+
9
+ ## 1. 先确认宿主真正开放了什么
10
+
11
+ 开始编码前,先阅读宿主的官方文档、SDK 类型和示例,并记录以下内容:
12
+
13
+ | 调查项 | 需要回答的问题 |
14
+ | --- | --- |
15
+ | 官方扩展机制 | 官方称它为 Extension、Plugin、App Server、Hook、SDK,还是其他名称? |
16
+ | 安装入口 | 用户如何安装、启用、升级和卸载?是否需要重启宿主? |
17
+ | 生命周期 | 能否知道会话、用户请求、Agent 工作和工具执行何时开始或结束? |
18
+ | 数据粒度 | 提供完整对象、完成事件,还是增量更新?字段是否稳定、是否包含 ID? |
19
+ | 控制能力 | 能否创建或恢复会话、提交输入、中断运行、处理审批? |
20
+ | 多 Agent | 是否正式提供 Subagent 的身份、父子关系、任务和退出事件? |
21
+ | 历史能力 | 能否读取持久化会话、Turn 和工具记录?是否需要轮询? |
22
+ | UI 与命令 | 能否注册命令、按钮、WebView,或者只能返回本地 URL? |
23
+ | 安全与清理 | 权限由谁审批?页面、会话或宿主退出时如何停止本地服务? |
24
+
25
+ 描述调查结果时按以下优先级使用术语:
26
+
27
+ 1. 宿主官方术语和真实方法名。
28
+ 2. 行业通用术语,例如 JSON-RPC、notification、callback、polling。
29
+ 3. Agent Live 内部能力分类。
30
+
31
+ 不要把 Agent Live 的分类写成宿主的官方概念。比如 Codex 官方使用 App Server、Thread、Turn、Item、request 和 notification;“Controller Adapter”只是我们对这组能力的归纳。
32
+
33
+ 如果宿主没有正式公开所需能力,应明确降级或停止实现。不要读取私有数据库、注入宿主进程、解析不稳定日志或伪造事件,除非实现被明确标记为实验性方案,并由用户主动选择。
34
+
35
+ ## 2. 选择可实现的接入能力
36
+
37
+ 不同能力彼此独立;宿主支持一种,不代表一定支持其他能力。
38
+
39
+ | Agent Live 分类 | 行业含义 | 常见官方形态 | 对用户的效果 |
40
+ | --- | --- | --- | --- |
41
+ | 实时观察 | 接收宿主正在发生的事实 | Extension callbacks、SDK events、JSON-RPC notifications | 用户继续在原宿主工作,办公室实时变化 |
42
+ | 任务控制 | 从外部驱动宿主任务 | App Server、client SDK、session APIs | Agent Live 客户端可以提交和中断任务 |
43
+ | 节点上报 | 宿主在指定节点调用处理器 | lifecycle hooks、command hooks | 只能展示 Hook 明确提供的粒度 |
44
+ | 历史重建 | 读取已持久化的任务记录 | history/session/thread APIs | 可以延迟展示或回放,通常需要查询或轮询 |
45
+
46
+ 实时观察不等于获取宿主内部全部事件。Adapter 只能使用官方接口实际暴露的字段。任务控制接口也可能只返回聚合结果,不保证拥有实时观察能力。
47
+
48
+ 公共 SDK 不要求开发者填写一份容易失真的能力清单。`observe` 来自必需的 `connect()`;控制能力和嵌入式 View 根据实际实现的方法自动推导:
49
+
50
+ ```ts
51
+ export interface AdapterCapabilities {
52
+ observe: boolean;
53
+ prompt: boolean;
54
+ interrupt: boolean;
55
+ modelSelect: boolean;
56
+ approve: boolean;
57
+ embeddedView: boolean;
58
+ }
59
+ ```
60
+
61
+ | 字段 | 为 `true` 的最低条件 |
62
+ | --- | --- |
63
+ | `observe` | 能在任务运行期间持续获得至少状态或工作事件,而不只是启动后读取一次结果 |
64
+ | `prompt` | Adapter 能通过宿主正式接口提交新的用户请求 |
65
+ | `interrupt` | Adapter 能通过宿主正式接口请求停止当前工作 |
66
+ | `modelSelect` | Adapter 能读取或设置当前任务使用的模型;只显示固定名称不算支持 |
67
+ | `approve` | Adapter 能通过宿主正式接口提交审批决定 |
68
+ | `embeddedView` | 宿主提供正式 View Slot,且 Adapter 实现了挂载与清理 |
69
+
70
+ Subagent、模型信息和 Token 用量属于宿主事实:宿主提供可靠数据时直接映射为公共事件,不需要再声明一套开关。暂时无法映射的官方能力可以留在 Adapter 内部,但不能泄漏到 Core。
71
+
72
+ ## 3. Adapter 与其他模块的边界
73
+
74
+ ```text
75
+ 宿主官方接口
76
+
77
+ Adapter Package:入口、连接、接收、控制、翻译与正常生命周期
78
+ ↓ OfficeEvent
79
+ Core:状态和宿主无关语义
80
+
81
+ Presentation:本地 Runtime 或宿主原生 View
82
+
83
+ Office Engine:人物、路径、活动和环境
84
+
85
+ Renderer
86
+ ```
87
+
88
+ Adapter 应该负责:
89
+
90
+ - 根据宿主官方生命周期接收事实事件。
91
+ - 为真实 Agent 维护稳定 ID 和父子关系。
92
+ - 把宿主事件转换成 `OfficeEvent` 或调用 `OfficeState` 的对应操作。
93
+ - 在宿主允许时实现提交请求、中断和审批等控制方法。
94
+
95
+ 同一个 Adapter Package 还应该负责:
96
+
97
+ - 建立和关闭所需的宿主连接。
98
+ - 创建并装配 Core 与选定的 Runtime 或原生 View。
99
+ - 注册宿主命令、View、Skill、Tool 与安装入口。
100
+ - 按宿主要求决定何时启动、保持和关闭。
101
+ - 明确拥有并释放订阅、定时器、本地服务和自己创建的子进程。
102
+
103
+ Adapter 不应该负责:
104
+
105
+ - 指定人物坐标、路径、工位或家具。
106
+ - 创建 NPC、生活事件或视觉特效。
107
+ - 决定人物如何移动、使用设施或播放动画。
108
+ - 根据输出文本猜测工具、Subagent 或任务是否成功。
109
+ - 把宿主专用对象加入 `OfficeEvent`。
110
+ - 绕过公共 Creator、Compiler、Validator 修改 Custom Office。
111
+ - 为了让画面更丰富而生成宿主没有报告的工作事实。
112
+
113
+ ## 4. 公共事件协议
114
+
115
+ 所有 Adapter 最终使用 [`OfficeEvent`](../plugins/agent-live/src/core/protocol.ts)。
116
+
117
+ | 事件 | 含义 | 关键要求 |
118
+ | --- | --- | --- |
119
+ | `snapshot` | 当前完整状态,用于 Viewer 首次连接或恢复 | Agent、Session、日志必须自洽 |
120
+ | `session` | 会话模型、思考等级、忙闲和 Turn 数变化 | 不确定字段应省略,不要猜测 |
121
+ | `agent_join` | 一个真实 Agent 加入 | `id` 在其生命周期内稳定 |
122
+ | `agent_leave` | 一个真实 Agent 离开 | 必须对应已有 Agent;宿主不知道成功与否时省略 `ok`,不得猜测 |
123
+ | `agent_state` | Agent 的工作状态变化 | 使用公共 `AgentState` |
124
+ | `task` | 当前用户任务的短描述 | 控制长度,不复制完整敏感上下文 |
125
+ | `thought` | 宿主明确允许展示的思考摘要 | 不得把私有推理冒充摘要 |
126
+ | `say` | 面向用户的 Agent 文本增量或完成文本 | 流式内容不能重复累计 |
127
+ | `action` | 一次真实工具或工作动作开始 | `toolCallId` 必须可关联 |
128
+ | `action_end` | 对应动作完成 | `ok` 来自宿主事实 |
129
+ | `delegate` | 父 Agent 把任务交给子 Agent | 双方 ID 必须稳定 |
130
+ | `usage` | 当前会话的用量 | 产品统一使用会话累计口径 |
131
+
132
+ 公共状态为 `idle`、`thinking`、`working`、`waiting`、`talking`、`done`、`error`。公共动作为 `type`、`archive`、`server`、`whiteboard`、`phone`、`delegate`、`coffee`。
133
+
134
+ 宿主工具名称应先通过公共映射转换为工作语义。没有可靠映射时,回退到普通工作动作,而不是增加宿主专用枚举。Layout 再决定动作最终发生在哪个设施。
135
+
136
+ ## 5. 建立事件映射表
137
+
138
+ 编码前先提交一张映射表。左侧必须使用宿主官方名称,右侧才使用 Agent Live 事件。
139
+
140
+ ```text
141
+ 宿主官方事件/方法 可用字段 Agent Live
142
+ ────────────────────────────────────────────────────────────────
143
+ <session started> session id, model session + agent_join
144
+ <user request started> text, turn id task + thinking
145
+ <tool started> tool name, call id action
146
+ <tool completed> call id, status action_end
147
+ <assistant delta> text delta say
148
+ <task completed> status, usage done/error + usage
149
+ <subagent started> child id, parent id, task agent_join + delegate
150
+ <subagent completed> child id, status agent_leave
151
+ ```
152
+
153
+ 每行还应注明通信形式、事件粒度、是否可能重复或乱序、ID 作用域,以及缺失时的降级行为。
154
+
155
+ 一个实时 Adapter 至少要能稳定产生:主 Agent 加入、会话忙闲、任务与真实状态、至少一种真实工作动作或可靠回答、正常与异常结束,以及初始 `snapshot`。
156
+
157
+ 如果只能读取完成后的历史,不应声明 `observe: true`;应等待公共 Replay 合同建立后接入历史重建。
158
+
159
+ ## 6. 推荐实现结构
160
+
161
+ 第三方 Adapter 默认是独立 Node 包,不进入 Agent Live 源码目录,也不修改其他 Adapter:
162
+
163
+ ```text
164
+ agent-live-adapter-<host>/
165
+ ├── adapter.ts 官方事件到 Core 的转换
166
+ ├── client.ts 可选:官方协议或 SDK 的薄封装
167
+ ├── launcher.ts 可选:连接、Runtime 与正常退出策略
168
+ ├── view.ts 可选:宿主原生 View 集成
169
+ ├── entry.ts 宿主插件或扩展入口
170
+ └── types.ts 可选:宿主公开类型的最小本地声明
171
+ ```
172
+
173
+ 公共 SDK 示例:
174
+
175
+ ```ts
176
+ import { defineAdapter } from "@iniesta8888/agent-live";
177
+
178
+ export default defineAdapter({
179
+ id: "example",
180
+ name: "Example Agent",
181
+ connect({ host, office }) {
182
+ return host.subscribe((event) => {
183
+ const mapped = mapHostEvent(event);
184
+ if (mapped) office.publish(mapped);
185
+ });
186
+ },
187
+ });
188
+ ```
189
+
190
+ 使用独立 Viewer 的最小骨架:
191
+
192
+ ```ts
193
+ const runtime = new AgentLiveRuntime(cwd);
194
+ const adapter = createHostEventAdapter({ state: runtime.state, hostClient });
195
+
196
+ try {
197
+ await adapter.start();
198
+ await runtime.start({ port, onViewerCountChange: handleViewerCount });
199
+ } catch (error) {
200
+ await Promise.allSettled([adapter.close(), runtime.close()]);
201
+ throw error;
202
+ }
203
+
204
+ // 何时执行由当前宿主的 Adapter 策略决定。
205
+ await Promise.allSettled([adapter.close(), runtime.close()]);
206
+ ```
207
+
208
+ 这只是职责示例,不是要求所有 Adapter 实现相同的 `start/close` 接口。具体回调注册、连接恢复和退出时机必须遵循宿主官方生命周期。宿主提供正式 View Slot 时,Adapter 可以直接注册原生 View,不创建 `AgentLiveRuntime`,也不能为了结构一致而额外启动 HTTP 服务。
209
+
210
+ Agent Live 的公共资源兜底完全位于 Engine/Runtime 内部,Adapter 开发者不需要也不能向其中登记资源。它只负责 Agent Live 公共实现启动或占用的本地服务、连接、定时器、内存事件记录和临时文件。宿主连接、宿主进程以及 Adapter 自己创建的资源,均由宿主和 Adapter 按其正式生命周期负责。
211
+
212
+ 官方事件直接映射到 Core,不先发明 `<Host>Fact`。如果同一官方通道中的 started/completed、增量/完成事件需要关联,可在 Adapter 内使用私有 map 或 cursor;它们是协议适配细节,不是共享业务层。一个事实只选择一个权威来源,禁止为了“更完整”同时订阅多个来源并重复发出 OfficeEvent。
213
+
214
+ ## 7. 身份、顺序和异常处理
215
+
216
+ ### Agent 身份
217
+
218
+ - 主 Agent 可以使用 Adapter 内部稳定 ID,例如 `main`。
219
+ - Subagent 优先使用宿主提供的 thread/session/agent ID。
220
+ - 昵称和角色不能作为唯一 ID。
221
+ - 同一个 Agent 的后续事件必须复用 ID,不能重复加入并替换主 Agent。
222
+ - Agent 数量与工位数量相互独立;超出画面容量由公共上限处理。
223
+
224
+ ### 事件顺序
225
+
226
+ - 收到动作结束但没有开始时,不伪造完整调用。
227
+ - 重复通知按宿主事件 ID 或 `toolCallId` 去重。
228
+ - 增量文本只追加新片段;完成事件不能再次追加全文。
229
+ - Turn 完成后清理未结束动作并进入稳定状态。
230
+ - 中断请求成功不代表已经停止;等待宿主正式完成或取消通知。
231
+
232
+ ### 连接与退出
233
+
234
+ - 本地服务只监听 `127.0.0.1`。
235
+ - Adapter 必须明确自己拥有的宿主连接、View 和 Runtime(如有)。
236
+ - Viewer 关闭后按公共生命周期退出,不遗留轮询器、子进程或监听器。
237
+ - 宿主断线时有限恢复,不能无限高速重连。
238
+ - 定时器、订阅和子进程都必须在 `close()` 中释放。
239
+
240
+ ## 8. Creator 接入是独立能力
241
+
242
+ Creator 不属于事件映射,也不要求 Adapter 复制 Creator、Compiler 或 Validator。宿主若支持命令、Tool 和每轮上下文扩展,Adapter 只负责把这些官方扩展点绑定到 Agent Live 提供的公共 Creator 合同。
243
+
244
+ 如果宿主支持 Tool、Skill、命令或生命周期 Hook,完整接入应提供:
245
+
246
+ 1. 注册 `/agent-live custom` 与 `/agent-live exit` 等用户命令。
247
+ 2. 将 Custom 状态限定在当前宿主会话或任务内。
248
+ 3. 在 Custom 状态下绑定公共 Tool 和上下文;每次合法修改直接生效。
249
+ 4. 普通状态不把自然语言误判为 Office 编辑。
250
+ 5. 退出、任务结束或 Agent Live 关闭时清理 Custom 状态。
251
+
252
+ 如果宿主没有这些能力,实时办公室 Adapter 仍可成立,但应声明暂不支持自然语言自定义。不要为此复制 Creator 逻辑。
253
+
254
+ ## 9. 最小验证门
255
+
256
+ ### 静态合同
257
+
258
+ - [ ] Adapter 包含唯一 `id`、官方产品名,且可选能力均有真实实现。
259
+ - [ ] Core、Runtime 和 Renderer 未导入宿主 SDK。
260
+ - [ ] Adapter 未写入坐标、家具、NPC 或 Preset。
261
+ - [ ] 未增加宿主专用 `OfficeEvent`。
262
+
263
+ ### 单 Agent 流程
264
+
265
+ - [ ] 启动后只出现一个主 Agent。
266
+ - [ ] 用户任务进入宿主真实支持的状态。
267
+ - [ ] 工具开始与结束正确配对。
268
+ - [ ] 正常完成、失败和中断回到稳定状态。
269
+ - [ ] 可选信息缺失时页面仍正常工作。
270
+
271
+ ### 多 Agent 流程
272
+
273
+ - [ ] 只有宿主正式提供 Subagent 身份与生命周期时才运行此组测试。
274
+ - [ ] 子 Agent 不替换主 Agent,并拥有不同稳定 ID。
275
+ - [ ] 委派、完成和退出顺序正确。
276
+ - [ ] 超过画面容量时不会重叠、崩溃或破坏状态。
277
+
278
+ ### 生命周期
279
+
280
+ - [ ] 重复启动不会意外创建两个 Integration 实例或两个 Runtime。
281
+ - [ ] Viewer 刷新可以重新获得 `snapshot`。
282
+ - [ ] Viewer 关闭、宿主退出和异常启动都会释放服务及宿主连接。
283
+ - [ ] 重连不会重复 Agent、文本或工具事件。
284
+
285
+ ### 项目回归
286
+
287
+ ```bash
288
+ npm run check
289
+ npm run validate:package
290
+ ```
291
+
292
+ 公共合同入口是 `npm run validate:adapter-sdk`。宿主特定事件序列仍应在独立 Adapter 包内补充测试。
293
+
294
+ ## 10. 提交 Adapter 时应包含什么
295
+
296
+ 一个可审查的 Adapter 变更至少包含:
297
+
298
+ 1. 宿主官方名称、文档链接、版本范围和安装方式。
299
+ 2. 官方接口到 `OfficeEvent` 的映射表。
300
+ 3. 基于公共 `defineAdapter()` 的实现代码。
301
+ 4. 启动、停止、失败和可选 Subagent 的自动测试。
302
+ 5. 一次真实宿主测试记录。
303
+ 6. 已知限制和明确的降级行为。
304
+ 7. 第三方依赖、权限、日志和本地数据说明。
305
+
306
+ 评审顺序固定为:先确认宿主事实和官方接口,再检查公共协议映射,最后检查画面表现。画面正确不能替代事件和生命周期正确。
307
+
308
+ ## 11. 当前官方参考实现
309
+
310
+ ### Pi
311
+
312
+ 入口:[`packages/pi/src/adapter.ts`](../packages/pi/src/adapter.ts)
313
+
314
+ Pi Adapter 使用 Pi Extension API 注册官方生命周期事件回调。它适合参考进程内实时观察、模型变化、工具调用和 Subagent 映射,但 Pi 专用事件名不能复制到其他宿主。
315
+
316
+ ### Codex
317
+
318
+ 入口:[`src/adapters/codex/adapter.ts`](../plugins/agent-live/src/adapters/codex/adapter.ts)
319
+
320
+ Codex Adapter 使用 Codex App Server 协议,通过 JSON-RPC request 控制由客户端建立的 Thread/Turn,并读取 App Server notification。它适合参考外部客户端、审批、增量 Item、停止请求和子进程清理,但 Agent Live 的“控制/观察”分类不是 Codex 官方术语。
321
+
322
+ ### DeepSeek Harness
323
+
324
+ 入口:[`dsh/src/adapter.ts`](../plugins/agent-live/dsh/src/adapter.ts) 与 [`dsh/src/client.tsx`](../plugins/agent-live/dsh/src/client.tsx)
325
+
326
+ DSH Adapter 使用官方 `conversation.view`,从 Web Client 已有的 Session、Conversation、模型、用量和 Subagent Projection 构造有界 Snapshot,再增量映射为 `OfficeEvent`。它适合参考宿主原生 View、Snapshot 差分、Tab 重建和无额外 HTTP Runtime 的集成;`dsh/src/index.ts` 只负责在 Host 侧注册 Creator 所需的正式扩展,不是第二条工作事件桥。
327
+
328
+ 选择参考实现时,应根据宿主官方扩展形态选择最接近的一套,而不是根据画面效果选择。
@@ -0,0 +1,109 @@
1
+ # Agent Live Adapter SDK
2
+
3
+ This is the public development manual for connecting a coding-agent host to Agent Live. Use only exports from `@iniesta8888/agent-live` or `@iniesta8888/agent-live/adapter-sdk`; importing files under `plugins/agent-live/src` is unsupported.
4
+
5
+ Install the published SDK from npm:
6
+
7
+ ~~~bash
8
+ npm install @iniesta8888/agent-live
9
+ ~~~
10
+
11
+ ## The minimum adapter
12
+
13
+ An adapter has one required job: subscribe to official host events and publish equivalent `OfficeDelta` events.
14
+
15
+ ~~~ts
16
+ import { defineAdapter, type OfficeDelta } from "@iniesta8888/agent-live";
17
+
18
+ interface Host {
19
+ subscribe(listener: (event: unknown) => void): () => void;
20
+ }
21
+
22
+ function mapHostEvent(event: unknown): OfficeDelta | undefined {
23
+ // Map documented host data. Return undefined when no reliable mapping exists.
24
+ }
25
+
26
+ export default defineAdapter<Host>({
27
+ id: "example",
28
+ name: "Example Agent",
29
+ connect({ host, office }) {
30
+ return host.subscribe((event) => {
31
+ const mapped = mapHostEvent(event);
32
+ if (mapped) office.publish(mapped);
33
+ });
34
+ },
35
+ });
36
+ ~~~
37
+
38
+ `connect()` may return a cleanup function or an object with `close()`. `connectAdapter()` only connects the adapter: it does not start a server, open a page, or wire controller methods to HTTP endpoints. The host entry point performs that composition and chooses when to close it. Agent Live cleans up the resources its Runtime owns when `runtime.close()` is called.
39
+
40
+ ## Run a complete example
41
+
42
+ After `npm ci` and `npm run build` in this repository:
43
+
44
+ ~~~bash
45
+ node examples/adapter/local-office.mjs
46
+ ~~~
47
+
48
+ Open the printed local URL; Ctrl+C closes the example. [The example](../examples/adapter/local-office.mjs) imports only public `@iniesta8888/agent-live` exports, connects a simulated host, starts an authenticated Viewer, and exposes selection and Creator operations. Copy it into your independent adapter package and replace the host subscription. It does not invoke a model or register a host plugin for you.
49
+
50
+ `npm run validate:sdk-example` tests that consumer after a build, including selection, customization, reopening and cleanup in a temporary data directory. `check:ci` includes it.
51
+
52
+ ## Reuse Creator
53
+
54
+ The public exports include `OfficeContentService`, `CreatorService`, `CreatorCommandRouter`, `CreatorModeRegistry`, `CREATOR_MODE_CONTEXT`, and the `OfficeSpec` / `OfficePatch` types.
55
+
56
+ Create content with `OfficeContentService.create()`, construct `CreatorService(content.registry, content.library)`, then `CreatorCommandRouter(service)`. Register `commands.execute()` as a host tool. Use `service.listOffices()` / `selectOffice(id)` for discovery and selection. The router supports `list_offices`, `list_components` and `customize`; valid changes apply immediately. Do not recreate validation or edit files yourself.
57
+
58
+ If the host supports scoped prompt hooks, register explicit `custom` / `exit` commands and use the mode registry/context during that host session. Otherwise use explicit single-invocation customization. Closing the integration must clear its Creator mode. Do not install hooks the host does not support.
59
+
60
+ ## Optional host controls
61
+
62
+ Declare only methods backed by official host APIs:
63
+
64
+ ~~~ts
65
+ interface ControllableHost extends Host {
66
+ submit(text: string): Promise<unknown>;
67
+ interrupt(): Promise<unknown>;
68
+ }
69
+
70
+ export function createControlledAdapter(host: ControllableHost) {
71
+ return defineAdapter<ControllableHost>({
72
+ id: "example",
73
+ name: "Example Agent",
74
+ connect({ host, office }) {
75
+ return host.subscribe((event) => {
76
+ const mapped = mapHostEvent(event);
77
+ if (mapped) office.publish(mapped);
78
+ });
79
+ },
80
+ controls: {
81
+ prompt: (text) => host.submit(text),
82
+ interrupt: () => host.interrupt(),
83
+ },
84
+ });
85
+ }
86
+ ~~~
87
+
88
+ Capabilities are derived from implemented methods. Do not manually claim support. Subagents, model information, token usage and approval-waiting states are ordinary `OfficeDelta` data. Only responding to an approval is an optional control.
89
+
90
+ The launcher must explicitly route its UI or transport to these methods. The standalone server's `OfficeControls` type is also exported; do not assume declaring `controls` on a definition automatically creates a controller UI.
91
+
92
+ ## Embedded views
93
+
94
+ Add `mountView(host)` only when the host provides a documented native view slot. Return its cleanup function. A host may embed the standalone Viewer URL, or supply its own native bundling/transport like DSH. This hook is a lifecycle callback, not a ready-made embedded renderer. The current runnable SDK example covers the standalone Viewer; a no-HTTP native view still needs host-specific integration. Do not fork the rendering logic.
95
+
96
+ ## Evidence before code
97
+
98
+ Before implementation, record the official extension mechanism and versions, event names and fields, stable identities, delivery semantics, optional controls, native view APIs, missing capabilities and degradation. Do not infer private events from UI text, scan undocumented storage, or parse prose to invent tool or subagent state.
99
+
100
+ ## Validation
101
+
102
+ Test main-agent lifecycle, paired tool calls, duplicate and missing data, disconnect and idempotent cleanup, officially exposed subagents, and every optional control. Run:
103
+
104
+ ~~~bash
105
+ npm run validate:adapter-sdk
106
+ npm run check
107
+ ~~~
108
+
109
+ For guided development, use the bundled `agent-live-adapter-builder` skill. It creates an independent package, capability report, event map and test skeleton without modifying Agent Live internals.
@@ -0,0 +1,223 @@
1
+ # Agent Live 架构
2
+
3
+ Agent Live 通过宿主专用 Adapter Package 接入 coding agent,再由公共 Engine 渲染办公室。Adapter Package 封装该宿主的安装入口、事件转换、正常生命周期和展示方式;Agent Live 公共代码只兜底清理 Engine/Runtime 自己启动或占用的资源。
4
+
5
+ ## 统一架构
6
+
7
+ ```mermaid
8
+ flowchart TB
9
+ classDef host fill:#FFF4D6,stroke:#9B6B18,color:#33230A
10
+ classDef adapter fill:#DCEBFF,stroke:#3E6EA8,color:#14283F
11
+ classDef core fill:#DDF5E8,stroke:#377A58,color:#153526
12
+ classDef engine fill:#DDF6F5,stroke:#347A78,color:#143735
13
+ classDef presentation fill:#FFE4E1,stroke:#A65650,color:#45201D
14
+ classDef content fill:#F2F2F2,stroke:#686868,color:#242424
15
+
16
+ subgraph H["Coding Agent 官方能力"]
17
+ PI["Pi Extension API<br/>callbacks · commands"]:::host
18
+ CX["Codex App Server<br/>JSON-RPC requests · notifications"]:::host
19
+ DS["DeepSeek Harness / Cordis<br/>agent/* · session/event · UI slots"]:::host
20
+ end
21
+
22
+ subgraph A["Adapter Package|封装全部宿主差异"]
23
+ PIA["Pi Adapter<br/>Extension Entry · Observer<br/>Local Runtime · Pi lifecycle"]:::adapter
24
+ CXA["Codex Adapter<br/>CLI Entry · Observer + Controller<br/>App Server · Local Runtime"]:::adapter
25
+ DSA["DSH Adapter<br/>Client-side Observer<br/>conversation.view · DSH lifecycle"]:::adapter
26
+ end
27
+
28
+ subgraph C["Agent Live Core|唯一公共语义"]
29
+ REG["Agent Registry<br/>身份 · 父子关系 · 数量上限"]:::core
30
+ MAP["Office State + Mapping<br/>状态 · 动作 · 工具语义"]:::core
31
+ BUS["OfficeEvent Stream<br/>snapshot · task · action · say · usage"]:::core
32
+ end
33
+
34
+ subgraph P["Transport / View Integration|按宿主选择"]
35
+ RT["Local Runtime<br/>HTTP · SSE · 自动退出"]:::presentation
36
+ VIEW["DSH conversation.view Bridge<br/>session-scoped store"]:::presentation
37
+ end
38
+
39
+ subgraph E["Office Engine + Renderer|所有宿主共享"]
40
+ ENG["Office Engine<br/>人物状态机 · 路径 · 活动 · 时间环境 · 回放"]:::engine
41
+ REN["Renderer<br/>Canvas · Sprite · UI"]:::engine
42
+ end
43
+
44
+ subgraph O["Office Content"]
45
+ PRE["Official Presets"]:::content
46
+ CUSTOM["Local Custom Office"]:::content
47
+ CREATOR["Creator<br/>Schema · Compiler · Validator"]:::content
48
+ end
49
+
50
+ PI --> PIA
51
+ CX --> CXA
52
+ DS --> DSA
53
+ PIA --> REG
54
+ CXA --> REG
55
+ DSA --> REG
56
+ REG --> MAP --> BUS
57
+ PIA -.owns.-> RT
58
+ CXA -.owns.-> RT
59
+ DSA -.registers.-> VIEW
60
+ BUS --> RT --> ENG
61
+ BUS --> VIEW --> ENG
62
+ ENG --> REN
63
+ PRE --> ENG
64
+ CUSTOM --> ENG
65
+ CREATOR --> CUSTOM
66
+ ```
67
+
68
+ 这张图中的三条宿主链路必须共享同一个 Core、Engine 和 Renderer,而不是分别建立三套业务模型。每个 Adapter Package 可以按照宿主要求选择完全不同的启动、关闭、控制和展示方式。
69
+
70
+ ### 各层所有权
71
+
72
+ | 层 | 负责 | 不负责 |
73
+ | --- | --- | --- |
74
+ | Host | 官方事件、请求、UI 扩展点和持久化能力 | Agent Live 的业务语义 |
75
+ | Adapter Package | 安装入口、官方 payload 翻译、可选控制能力、正常生命周期和展示装配 | 定义公共办公室语义、NPC 行为和画法 |
76
+ | Core | Agent 身份、父子关系、状态、动作语义、容量规则和 OfficeEvent | 导入宿主 SDK、决定人物路线或画法 |
77
+ | Office Engine | 将 Core 事实和 Office Content 运行成办公室世界:人物状态机、路径、设施、NPC 日程、时间环境和回放 | 理解 Pi、Codex、DSH 原始事件;直接绘图 |
78
+ | Renderer | 绘制 Engine 计算出的世界状态和 UI | 业务规则、宿主连接和任务控制 |
79
+ | Runtime / View Bridge | 把 OfficeEvent 送到 Engine;由 Adapter 选择独立 Runtime 或宿主原生 View | 重新解释宿主事件或实现办公室规则 |
80
+ | Creator / Content | 声明式办公室内容的生成、校验、保存和选择 | 监听或控制 Agent Loop |
81
+
82
+ ### Core
83
+
84
+ `plugins/agent-live/src/core/` 定义所有宿主共享的稳定语言:
85
+
86
+ - `protocol.ts`:Agent、Session、Action 和 OfficeEvent。
87
+ - `state.ts`:员工、任务、日志、用量和流式思考状态。
88
+ - `mapping.ts`:通用工具语义到办公室动作的映射。
89
+
90
+ Core 不得导入 Pi、Codex 或浏览器 UI。
91
+
92
+ ### Engine
93
+
94
+ Engine 是 Agent Live 的办公室模拟层,回答“这个统一事实在办公室里如何发生”:
95
+
96
+ - 根据 Agent 状态选择工作、等待、交谈或空闲活动。
97
+ - 根据 Layout 的通道、目标点和障碍物规划人物移动。
98
+ - 分配可用设施,而不是把 Agent 数量与工位数量强绑定。
99
+ - 运行 NPC 班次、喝水、上厕所、聊天等生活事件。
100
+ - 驱动时间、天气、灯光和历史回放速度。
101
+
102
+ Engine 只消费 Core 的 `OfficeEvent` 和经过校验的 Office Content。它不能读取宿主 payload,也不能自行制造“工具执行成功”等工作事实。Renderer 只负责把 Engine 的世界状态画出来。
103
+
104
+ Engine 的宿主无关空间模型位于 `web/v2/office-engine.js`,负责导航、目标点、设施选择和环境查询;`environment-runtime.js` 负责时间、天气与班次。`app.js` 是浏览器 Scene Controller,消费 OfficeEvent、推进人物与生活活动并把世界状态交给 Renderer;`office-renderer.js` 和 `sprite-renderer.js` 只处理 Canvas 绘制。Engine 不包含宿主 SDK、HTTP/SSE 或 DSH View 代码。
105
+
106
+ ### Runtime
107
+
108
+ `plugins/agent-live/src/runtime/` 管理一次 Agent Live 实例:
109
+
110
+ - `agent-live-runtime.ts`:统一持有 OfficeState、本地服务和清理流程。
111
+ - `server.ts`:仅监听 `127.0.0.1`,提供静态文件、SSE 和可选控制接口。
112
+
113
+ Runtime 是“独立浏览器 Viewer”这种展示形态的公共基础设施,不是所有 Adapter 的必经层。它不判断当前宿主;Pi、Codex Adapter Package 使用它,DSH 原生 View 不使用它。什么时候创建和关闭 Runtime 由对应 Adapter 决定。
114
+
115
+ `resource-guard.ts` 是 Runtime 的宿主无关内部兜底工具,不是一个架构层,也不对 Adapter 开放资源登记协议。它只清理 Agent Live 公共实现自己启动或占用的资源,例如本地 HTTP/SSE 服务、连接、定时器、内存事件记录以及未来可能使用的临时文件。Adapter、宿主和第三方插件创建的资源均由各自负责,公共 Guard 不介入。
116
+
117
+ ### Adapter
118
+
119
+ 三个官方 Adapter 按交付边界放置,而不是塞进 Core 包:
120
+
121
+ - `packages/pi/`:独立 Pi npm 包,包含 Extension 入口、Observer 事件转换和打包后的公共 Runtime/Viewer。
122
+ - `plugins/agent-live/src/adapters/codex/`:Codex App Server Client、事件转换、Controller 和 launcher;构建为 `dist/codex-plugin/` Marketplace 插件。
123
+ - `plugins/agent-live/dsh/`:独立 DSH npm 包,注册 `conversation.view` 并把 Session / Conversation Snapshot 转换为 OfficeEvent;详细设计见 [DSH-ADAPTER-DESIGN.md](DSH-ADAPTER-DESIGN.md)。
124
+
125
+ Adapter 自行决定是否管理 Runtime、宿主服务或原生 View,但不能直接控制坐标、NPC 或画法。公共 SDK 根据实际实现的控制方法推导可选能力,不再维护第二份手写布尔声明。接入新 coding agent 时,开发者只需新增一个 Adapter Package,不需要理解额外的 Integration 架构层。
126
+
127
+ Adapter 不增加中间的 `<Host>Fact` 公共层。官方事件已经是事实来源,直接映射到 Core 即可;只有某个宿主确实需要乱序关联或 payload 合并时,才在其 Adapter 内部增加私有 tracker,不能把它扩散为第二套公共协议。
128
+
129
+ 同一个语义事实必须指定一个权威来源。例如 DSH 的 Agent 生命周期来自 `agent/*`,用户消息、工具调用、最终回答、用量和模型来自 `session/event`;`agent/assistant-stream` 只用于瞬时流式展示。不得同时消费 `tools/*` 和 `session/event` 来重复生成同一工具动作。这里所说的“去重”是宿主边界内的防御和关联,不是 Core 或所有 Adapter 都必须拥有的一层。
130
+
131
+ ### Creator
132
+
133
+ Creator 将宿主模型产生的受约束 Office Seed / Patch 编译为本地 Custom Office。它不调用模型、不修改或重打包插件,也不新增 Runtime 能力。
134
+
135
+ 当前实现分布为:
136
+
137
+ ```text
138
+ content/schema.ts Office Spec、Seed 与 Patch 合同
139
+ content/compiler.ts Preset / Seed + Patch → 校验后的候选 Office
140
+ content/validator.ts 引用、容量、NPC、活动与环境校验
141
+ content/registry.ts Official / Custom Office 注册、保存与选择
142
+ creator/service.ts Patch 校验、原子保存与选择
143
+ creator/commands.ts list_offices / list_components / customize 三个受限内部操作
144
+ creator/mode.ts 按宿主 Session 隔离的 active / inactive 编辑范围
145
+ ```
146
+
147
+ 官方 Preset 随 Agent Live 发布;Custom Office 保存在用户本地。只有官方 Engine、Adapter 或组件能力升级时,用户才需要更新 GitHub 插件。
148
+
149
+ ## 启动与选择
150
+
151
+ Adapter 和 Office 是两个独立选择:
152
+
153
+ ```text
154
+ 宿主插件入口 → 加载对应 Adapter Package
155
+ Office Registry → Custom Office 或 Official Preset
156
+ ```
157
+
158
+ - Pi:Pi Adapter Package → Extension Observer + Local Runtime。
159
+ - Codex:Codex Adapter Package → App Server Controller + Local Runtime。
160
+ - DSH:Plugin Bundle → Client-side Observer + `conversation.view`,不启动额外 Runtime。
161
+ - 没有有效 Custom Office 时回退到官方 `tech-open-office`。
162
+
163
+ 禁止通过扫描本机进程猜测 Adapter。
164
+
165
+ ## 依赖规则
166
+
167
+ ```text
168
+ core → 不依赖其他业务层
169
+ runtime → core
170
+ renderer → protocol contract + content
171
+ adapter → core + host API + optional runtime/view bridge
172
+ creator → content schema + validator;不依赖 Adapter
173
+ ```
174
+
175
+ 审查新代码时,只要出现以下情况就应拒绝合并:
176
+
177
+ - Core 导入某个 coding agent SDK。
178
+ - Adapter 写入画面坐标或直接操作 Canvas。
179
+ - Preset 定义协议之外的新工作事件。
180
+ - Creator 通过生成任意代码绕过声明式 Schema。
181
+ - Custom Office 覆盖安装目录中的官方 Preset。
182
+
183
+ ## 当前实现与迁移方向
184
+
185
+ 三个 Adapter Package 已遵循同一边界:Pi 由 Extension 入口管理,Codex 的 `launcher.ts` 管理 App Server、Runtime 与 Viewer 策略,DSH 使用原生 View 生命周期。公共空间 Engine、Scene Controller 和 Renderer 已分文件,Adapter 不包含办公室坐标、NPC 或绘制规则。
186
+
187
+ | 能力 | Pi | Codex | DSH |
188
+ | --- | --- | --- | --- |
189
+ | 官方事实入口 | Extension callbacks | App Server notifications / requests | Client Session / Conversation Snapshot |
190
+ | Adapter 角色 | Observer | Observer + Controller | Observer |
191
+ | 正常生命周期策略 | Pi Adapter | Codex Adapter launcher | DSH Plugin / View lifecycle |
192
+ | 展示 | Local Runtime + Browser | Local Runtime + Browser | `conversation.view` 原生页面 |
193
+ | 控制入口 | 原宿主 UI | Agent Live Local Client | 原 DSH UI |
194
+
195
+ ### 一句话辨别
196
+
197
+ | 模块 | 它回答的问题 |
198
+ | --- | --- |
199
+ | Adapter | 如何接入这个宿主,并把它报告的事实交给 Agent Live? |
200
+ | Core | 这在 Agent Live 中是什么统一事实,是否合法? |
201
+ | Engine | 这个事实在办公室世界中如何运行和表现? |
202
+ | Renderer | 这个世界状态具体怎么画出来? |
203
+ | Runtime | 独立网页需要怎样传输事件、服务资源并安全退出? |
204
+
205
+ ## 自定义体验
206
+
207
+ 统一显式入口为 `/agent-live custom`,普通模式下不隐式解释为办公室编辑。支持动态上下文的宿主会把状态保持在当前会话内,直到 `/agent-live exit`、会话结束或插件卸载。宿主 Agent 调用 Creator 的受限操作生成 Patch;公共服务完成校验、原子保存和选择,失败时继续使用上一个有效 Office。Codex Skill 当前只保证调用当轮的显式自定义,不声称持续接管后续普通对话。
208
+
209
+ Pi 通过 `before_agent_start` 在已进入 Creator Mode 的当前会话中注入公共 Creator 状态;DSH 通过自己的会话级命令、Tool 与系统提示扩展装配同一合同。两者都由 `/agent-live custom` 明确进入,并由 `/agent-live exit` 明确退出。
210
+
211
+ Codex 当前不提供持续 Creator Mode:用户调用 Agent Live Skill 时同时描述本轮修改,Skill 在同一轮调用公共 Creator Command Router。它不会通过 Hook 接管之后的普通 Codex 对话。三种宿主最终都只把受限 Patch 交给同一 Creator Service;差异只在宿主如何提供上下文和 Tool 入口。
212
+
213
+ ## 未来:Agent 日记
214
+
215
+ 当前回放只保存当前展示实例所需的有界、带时间戳标准事件。Pi / Codex 的记录随 Local Runtime 生命周期结束而清除;DSH 在 Web Client 内为最近使用的 Session 保留有界 journal,页面客户端结束后不会形成持久日记。未来可在此基础上增加 **Agent Diary**:
216
+
217
+ - 按日期和 Agent 汇总任务、状态、工具动作、协作与结果。
218
+ - 使用 Codex/Pi 等宿主保存的会话历史作为任务事实来源。
219
+ - Agent Live 只持久化标准事件、办公室动作和回放时间线,不复制完整推理、原始工具输出或敏感消息正文。
220
+ - 支持从日记进入“某某的一天”跨会话回放,并允许用户查看、导出和删除本地记录。
221
+ - 默认完全本地保存,提供保留期限和关闭持久化的设置。
222
+
223
+ 该能力属于 Runtime 的可选本地存储模块,不应进入 Adapter,也不应改变 OfficeEvent 的宿主无关语义。