初始化 agent_ops 文档治理体系
This commit is contained in:
@@ -0,0 +1,878 @@
|
||||
# LineUp App 最终设计方案
|
||||
|
||||
**版本:** 1.0(当前开发基线)
|
||||
**状态:** 当前 App 设计的唯一汇总入口
|
||||
**日期:** 2026-08-06
|
||||
**来源:** [App 层架构方案](lineup-app-layer-architecture.md)、[Runtime 与 App SDK 架构方案](lineup-runtime-sdk-architecture.md)、[运行时与智能体工具](运行时与智能体工具.md)、[UI Surface 与 App Capability 协议](lineup-ui-surface-protocol.md)
|
||||
|
||||
**专题约束:** 远端 Agent 的角色、Agent Tool 与本地 UI Action / Host 生命周期意图的入口边界,以 [运行时与智能体工具](运行时与智能体工具.md) 为准。
|
||||
|
||||
---
|
||||
|
||||
## 0. 一句话定义
|
||||
|
||||
**LineUp 是运行在用户设备上的协作 Runtime,也就是整个产品的本地协调中心。**
|
||||
|
||||
Runtime 负责连接 AppServer 和 Remote Agent,保存会话与消息,管理应用、工具、权限和
|
||||
本地恢复。图文聊天、应用注册表、语音对话、画板和游戏则是在这个底座上运行的 App。
|
||||
用户使用 App 完成操作,Agent 发来消息或请求;两边都先交给 Runtime 处理,因此任何 App
|
||||
都不需要、也不能自己处理连接、登录态或系统权限。
|
||||
|
||||
```text
|
||||
Remote Agent
|
||||
│ 标准 LineUp 消息
|
||||
▼
|
||||
AppServer / IM
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ LineUp Runtime │
|
||||
│ │
|
||||
│ 连接 · 会话 · 消息筛选 · App 管理 · Tool 管理 │
|
||||
│ 权限 · Artifact · 存储 · Outbox · 恢复 · 审计 │
|
||||
└─────────────┬───────────────────────────┬───────────────┘
|
||||
│ Runtime SDK │ Host Provider
|
||||
▼ ▼
|
||||
Core / Installed App Tauri / OS
|
||||
chat · app-registry 文件 · 麦克风
|
||||
voice · whiteboard 通知 · 窗口
|
||||
game · … 安全存储
|
||||
```
|
||||
|
||||
## 1. 本方案的结论与优先级
|
||||
|
||||
本文件收敛正式方案目录下的三份已有文档,并在冲突处做出当前开发阶段的明确选择。
|
||||
|
||||
| 主题 | 最终决定 |
|
||||
|---|---|
|
||||
| App 的本体 | 整个产品是 `LineUpRuntime`;聊天不是 Runtime 本身。默认的 `Interaction App` 负责组织人与 Agent 的主交互,当前实现形态是 `chat`/图文 IM。 |
|
||||
| 默认入口 | `Interaction App` 是当前默认和 Recovery App;当前默认模式是 `im`(代码兼容作用域仍为 `chat`),以后可切换到实时音频或视频模式。 |
|
||||
| App 之间的关系 | App 只调用 Runtime SDK,不直接访问 AppServer、Agent、另一个 App 或 Tauri 特权 API。 |
|
||||
| Agent 交互 | Agent 只与 Runtime 通信;Runtime 按会话和应用作用域筛选并投递给 App。 |
|
||||
| 路由最小键 | 所有可路由消息必须有 `app_scope` 与 `conversation_id`;可选 `instance_id`、`operation_id`、`call_id`。 |
|
||||
| App 生态阶段 | 当前只使用本地短作用域,如 `chat`、`whiteboard`、`draw-and-guess`;暂不引入供应商身份、反向域名 App ID 或全局命名空间。 |
|
||||
| 丰富交互 | 标准内容先用可信内建组件;复杂互动用受限 Surface;设备/系统动作只能经 Capability Gateway。 |
|
||||
| Agent 工具 | App 在 SDK 源码中声明方法;构建生成 Manifest 的不可执行 Tool 描述,Runtime 汇总为动态 Inventory;Agent 只能调用当前 Inventory 中的方法。 |
|
||||
| Runtime SDK | SDK 提供状态订阅、Agent 消息订阅、Action、Tool、应用导航、Artifact、当前 App 子会话的通用业务数据、Capability 和生命周期接口。业务数据由 Runtime 持久化和隔离,App 不直接拥有存储。 |
|
||||
| Host | Tauri Desktop Host 与同代码的 Web Reference Host 是当前唯一实现/验收基线:前者是正式桌面外壳,后者是浏览器开发和验证入口;它们不是两个客户端。不规划独立 Android/Kotlin 客户端或 Wails Host。 |
|
||||
|
||||
本文件优先于来源文档中关于**后续 Runtime 重构**的结构描述。来源文档中的 M0~M4 完成记录、当前已实现字段和历史验收事实仍然有效;它们不自动成为新 Runtime 的长期模块边界。
|
||||
|
||||
## 2. 系统边界
|
||||
|
||||
### 2.1 Runtime、App 与 Host:先分清三者
|
||||
|
||||
这三个词经常同时出现,但职责不同:Runtime 是后台协调者,App 是用户看到的功能,Host
|
||||
是让 Runtime 运行在桌面窗口或浏览器中的外壳。Host 不能绕过 Runtime 直接把系统能力
|
||||
交给 App 或 Agent。
|
||||
|
||||
```text
|
||||
Runtime
|
||||
管理连接、状态、应用、工具、权限和副作用。
|
||||
|
||||
App
|
||||
面向用户或 Agent 的功能单元;只能通过 SDK 与 Runtime 协作。
|
||||
|
||||
Host
|
||||
提供操作系统或 WebView 能力;由 Runtime 使用,不直接暴露给 App/Agent。
|
||||
```
|
||||
|
||||
| 主体 | 必须负责 | 明确不负责 |
|
||||
|---|---|---|
|
||||
| Runtime | 连接 AppServer/Agent、管理会话与路由、安排 App 生命周期、Tool、Capability、持久化和审计 | 具体页面 DOM、任意 App 的业务 UI。 |
|
||||
| Chat App | 图文会话、时间线、输入、任务/交互卡片和 Artifact 基础展示 | `fetch` AppServer、同步 cursor、Agent 原始包解析、文件系统。 |
|
||||
| App Registry App | 让用户查看已安装 App,并请求安装/启用/禁用/移除或选择默认入口 | 直接写 Registry、删除 Bundle、绕过验签。 |
|
||||
| Installed App | 自己的交互体验、已声明 Tool、已声明事件和私有状态 | Tauri `invoke`、Host DOM、token、任意网络和其他 App 数据。 |
|
||||
| Tauri Host Provider | 在 Runtime 授权后实现文件、音频、通知、窗口和安全存储等系统操作 | 协议解释、应用策略和 Agent 路由。 |
|
||||
|
||||
### 2.2 关键禁止项
|
||||
|
||||
```text
|
||||
App → AppServer / Agent 直接网络连接 禁止
|
||||
App → 直接构造并发送未校验 Agent Envelope 禁止
|
||||
Surface → Tauri invoke / 父页面 DOM / 登录态 禁止
|
||||
Agent → 任意 App JavaScript 函数或 Host 特权 API 禁止
|
||||
Agent → 静默安装、启用、禁用或移除 App 禁止
|
||||
Surface Event → 直接执行系统能力 禁止
|
||||
```
|
||||
|
||||
## 3. Runtime 的内部模型
|
||||
|
||||
### 3.1 三类输入输出
|
||||
|
||||
Runtime 采用 Event / Command / Effect 分层。
|
||||
|
||||
```text
|
||||
Event:已经发生的事实
|
||||
Agent 文本、任务进度、用户点击、画板变更、录音完成、连接断开。
|
||||
|
||||
Command:希望 Runtime 处理的动作
|
||||
发送消息、调用 Tool、启动 App、启用 App、请求保存文件。
|
||||
|
||||
Effect:Runtime 决定执行的副作用
|
||||
网络发送、文件选择、录音、通知、创建 Surface、写存储。
|
||||
```
|
||||
|
||||
处理顺序固定为:
|
||||
|
||||
```text
|
||||
接收 Event / Command
|
||||
→ 验证与授权
|
||||
→ 更新 Runtime State
|
||||
→ 持久化事实 / Outbox
|
||||
→ 产生 Effect
|
||||
→ Effect 结果重新进入 Runtime,成为 Event
|
||||
→ 生成面向 App 的状态投影或消息投递
|
||||
```
|
||||
|
||||
第一版采用“事件驱动状态机 + 必要快照”,不实施完整 Event Sourcing。关键入站事件、用户决定、Tool 终态、outbox 和审计需持久化;纯渲染细节、焦点和滚动位置不必写入 Runtime 事实日志。
|
||||
|
||||
### 3.2 顶层状态
|
||||
|
||||
```text
|
||||
identity
|
||||
用户、设备、认证会话。
|
||||
|
||||
connection
|
||||
AppServer 连接、sync cursor、重试、实时状态、outbox。
|
||||
|
||||
conversations
|
||||
conversation、关联 Agent、消息引用、任务、交互、Artifact 元数据。
|
||||
|
||||
apps
|
||||
App Registry、默认 App、运行实例、每个 App 的可靠 Inbox、启动状态与按 App 子会话隔离的通用业务数据。
|
||||
|
||||
tools
|
||||
Tool 声明、Inventory revision、调用记录、operation 与进度。
|
||||
|
||||
capabilities
|
||||
权限请求、用户决定、系统权限、执行状态与最小审计。
|
||||
```
|
||||
|
||||
### 3.3 Runtime 生命周期
|
||||
|
||||
```text
|
||||
created
|
||||
→ restoring
|
||||
→ authenticating
|
||||
→ synchronizing
|
||||
→ online
|
||||
↘ reconnecting / offline_degraded
|
||||
→ stopping
|
||||
→ stopped
|
||||
```
|
||||
|
||||
启动时 Runtime 必须恢复 App Registry、默认入口、cursor、outbox、App Inbox、未完成 Tool 和可恢复实例。追平服务器历史后才开始正常实时投递;离线时可接受的用户/App Action 进入 outbox,重连后以幂等键和顺序发送。
|
||||
|
||||
## 4. 应用模型
|
||||
|
||||
### 4.1 本地应用作用域
|
||||
|
||||
当前阶段使用 Runtime 本地注册的 `app_scope`,而不是全球 App 身份:
|
||||
|
||||
```text
|
||||
chat
|
||||
app-registry
|
||||
settings
|
||||
voice
|
||||
whiteboard
|
||||
draw-and-guess
|
||||
runtime
|
||||
```
|
||||
|
||||
`app_scope` 的职责仅是本机启动、消息路由、Tool 路由、存储隔离和实例归属。它不是供应商身份,不要求跨市场唯一,也不承担开放生态的所有权模型。
|
||||
|
||||
未来如需市场、多供应商和跨设备分发,可以在 Manifest 中增加稳定身份映射;但不能改变本方案中的 `app_scope + conversation_id` 路由与隔离语义。
|
||||
|
||||
### 4.2 应用类型
|
||||
|
||||
| 类型 | 典型项 | 来源与执行方式 | 管理规则 |
|
||||
|---|---|---|---|
|
||||
| Core App | `chat`、`app-registry`、`settings` | 跟随 Runtime 发行的可信代码 | 不可由市场 Bundle 覆盖;`chat` 不可移除。 |
|
||||
| Installed App | `voice`、`whiteboard`、`draw-and-guess` | 经 Runtime 验证的 Bundle,在受限 Surface 中运行 | 可安装、启用、禁用、更新、回滚、移除。 |
|
||||
| Capability | 录音、选文件、保存、通知 | Tauri/OS 经 Runtime Host Provider 提供 | 不是 App,也不是自动授予的权限。 |
|
||||
|
||||
### 4.3 App Registry 与默认入口
|
||||
|
||||
Runtime App Manager 是安装和状态的唯一事实源:
|
||||
|
||||
```ts
|
||||
type AppRecord = {
|
||||
app_scope: AppScope;
|
||||
kind: "core" | "installed";
|
||||
installed_version: string;
|
||||
previous_version?: string;
|
||||
enabled: boolean;
|
||||
install_state: "installed" | "updating" | "failed";
|
||||
active_instance_count: number;
|
||||
installed_at: string;
|
||||
enabled_at?: string;
|
||||
};
|
||||
|
||||
interface RuntimeAppManager {
|
||||
listApps(filter?: AppListFilter): readonly AppRecord[];
|
||||
getApp(appScope: AppScope): AppRecord | undefined;
|
||||
install(request: InstallAppRequest): Promise<AppOperation>;
|
||||
enable(appScope: AppScope): Promise<AppOperation>;
|
||||
disable(appScope: AppScope, options?: DisableAppOptions): Promise<AppOperation>;
|
||||
update(appScope: AppScope, targetVersion?: string): Promise<AppOperation>;
|
||||
rollback(appScope: AppScope): Promise<AppOperation>;
|
||||
remove(appScope: AppScope, options?: RemoveAppOptions): Promise<AppOperation>;
|
||||
launch(request: LaunchAppRequest): Promise<AppInstanceHandle>;
|
||||
closeInstance(instanceID: AppInstanceID): Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
App Registry App 只调用上述接口,不直接管理 Bundle 文件。安装、验证、启用、升级和移除是异步操作,必须有可观察的 `AppOperation`。
|
||||
|
||||
Runtime Shell 始终独立于上层 App,负责应用切换、全局连接状态、通知和安全恢复。其启动目标优先级:
|
||||
|
||||
```text
|
||||
显式目标(深链接 / 通知)
|
||||
→ 可安全恢复的前台实例
|
||||
→ 用户设定的 Default App
|
||||
→ chat Recovery App
|
||||
```
|
||||
|
||||
`chat` 是当前图文 IM 主入口,也是不可移除的 Recovery App。未来用户可将 `voice` 设为默认入口;这只改变主要交互方式,不改变会话、Agent、outbox 或 Artifact 的归属。
|
||||
|
||||
### 4.4 App 实例生命周期
|
||||
|
||||
```text
|
||||
not_running → launching → active → backgrounded → suspended
|
||||
↘ restoring → active
|
||||
active / suspended → closing → closed
|
||||
↘ failed
|
||||
```
|
||||
|
||||
- Chat 与 App Registry 默认是单一全局实例;
|
||||
- 工具型 App 默认按 `conversation_id` 创建实例,可用 `instance_id` 区分同会话的多个实例;
|
||||
- 禁用阻止新调用并收口现有实例;移除在实例关闭且用户确认后清理 Bundle/私有数据;
|
||||
- Surface 被回收时 App 通过 Runtime snapshot 恢复,不能重复发送先前的用户事件。
|
||||
|
||||
### 4.5 Runtime 编排、Interact 与扩展 App
|
||||
|
||||
`Interaction App` 是默认的人与 Agent 交互应用,但它不是整个 App 生态的调度器。应用
|
||||
启动、Tool 路由、前后台焦点、实例生命周期和恢复均由 Runtime 管理;Interact 只负责
|
||||
当前主会话的交互体验,以及把扩展 App 的结果投影回会话。
|
||||
|
||||
```text
|
||||
LineUp Runtime
|
||||
├── App Registry / App Instance Manager
|
||||
├── Tool Router / App Router
|
||||
├── Focus Manager / Lifecycle Manager
|
||||
└── Conversation / Store / Outbox
|
||||
│
|
||||
├── Interaction App(Core App)
|
||||
│ ├── IM mode:文字、图片、短消息
|
||||
│ ├── Audio mode:实时语音
|
||||
│ ├── Video mode:实时视频
|
||||
│ └── 标准交互原语:choice / confirm / input
|
||||
│
|
||||
└── Installed App
|
||||
├── whiteboard
|
||||
├── draw-and-guess
|
||||
└── task-dashboard
|
||||
```
|
||||
|
||||
Runtime 的职责是判断一个 Agent 请求应由哪个应用实例、交互模式或标准组件承接;Interact
|
||||
不直接执行任意 Tool,也不负责切换其他 App 的前台状态。它通过 SDK 接收 Runtime 已经
|
||||
校验过的交互事件,并提交声明性用户 Action。
|
||||
|
||||
应用焦点是 Runtime 状态的一部分:
|
||||
|
||||
```text
|
||||
interaction:audio-001 running / foreground
|
||||
↓ Agent 请求启动 draw-and-guess
|
||||
interaction:audio-001 background 或 suspended
|
||||
draw-and-guess:game-001 starting → running / foreground
|
||||
```
|
||||
|
||||
原来的实例不会因为切换前台就被删除。Runtime 保存焦点栈和实例状态,以便游戏结束、用户
|
||||
退出或新应用失败时恢复原来的 Interaction App 和会话模式。
|
||||
|
||||
一次“启动你画我猜”的完整流程是:
|
||||
|
||||
```text
|
||||
Agent launch(draw-and-guess)
|
||||
→ Runtime 校验 Envelope、Inventory、Manifest、参数和 App 状态
|
||||
→ 创建 draw-and-guess App Instance
|
||||
→ 保存当前 Interaction App/Audio Instance 的焦点位置
|
||||
→ 将旧实例切换为 background / suspended
|
||||
→ 将新实例切换为 foreground
|
||||
→ App 通过 SDK 创建自己的 Surface 并接收用户操作
|
||||
→ 结果经 Runtime 持久化、审计并回传 Agent
|
||||
→ 游戏结束或关闭后恢复焦点栈中的 Interaction App
|
||||
```
|
||||
|
||||
标准选择框、确认框和输入框属于 Interaction App 的内建交互原语,不需要作为独立安装包;
|
||||
画板、游戏和复杂任务面板属于可安装扩展 App,与 Interaction App 是 Runtime 上的平级应用。
|
||||
|
||||
因此,Runtime 负责“能否调用、调用到哪里、哪个实例在前台以及如何恢复”;Interact 负责
|
||||
“如何在主交互体验中呈现和协调结果”;扩展 App 负责“具体功能和自己的交互界面”。
|
||||
|
||||
## 5. 消息、筛选与实时订阅
|
||||
|
||||
### 5.1 统一路由 Envelope
|
||||
|
||||
Runtime 对跨边界、需要传输或审计的消息使用统一路由 Envelope;所有这类消息都必须带作用域。Envelope 统一的是消息承载、作用域与校验字段,不能抹平来源边界:远端 Agent Tool、本地 UI Action 与 Host 生命周期意图是三条独立入口,必须保留不同的 sender、来源校验与审计类型。用户 UI 不能因为复用了同一内部业务动作而被视为或包装成 Agent Tool:
|
||||
|
||||
```ts
|
||||
type RuntimeEnvelope = {
|
||||
v: 1;
|
||||
id: string;
|
||||
type: string;
|
||||
timestamp: string;
|
||||
|
||||
sender: {
|
||||
kind: "agent" | "runtime" | "app" | "user" | "host";
|
||||
id: string;
|
||||
};
|
||||
|
||||
target: {
|
||||
kind: "runtime" | "app";
|
||||
app_scope: AppScope;
|
||||
instance_id?: AppInstanceID;
|
||||
};
|
||||
|
||||
scope: {
|
||||
app_scope: AppScope;
|
||||
conversation_id: ConversationID;
|
||||
instance_id?: AppInstanceID;
|
||||
operation_id?: OperationID;
|
||||
};
|
||||
|
||||
correlation?: {
|
||||
reply_to?: string;
|
||||
call_id?: ToolCallID;
|
||||
inventory_revision?: string;
|
||||
sequence?: number;
|
||||
};
|
||||
|
||||
payload: JsonValue;
|
||||
};
|
||||
```
|
||||
|
||||
全局 Runtime 事件同样保留作用域:
|
||||
|
||||
```text
|
||||
target.app_scope = runtime
|
||||
scope.app_scope = runtime
|
||||
conversation_id = runtime:global
|
||||
```
|
||||
|
||||
### 5.2 现有协议兼容
|
||||
|
||||
当前 Tauri 实现与 M0~M4 golden fixture 使用 `lineup.v1.*` 类型,以及 Surface payload 内的旧 `app.id` 字段。这些是**当前实现兼容事实**,不能在没有版本迁移和 golden fixture 的情况下直接删除。
|
||||
|
||||
Runtime 重构的规则是:
|
||||
|
||||
```text
|
||||
旧 LineUp v1 Envelope
|
||||
→ Runtime Compatibility Adapter
|
||||
→ 补齐/映射 app_scope、conversation_id、instance_id
|
||||
→ RuntimeEnvelope
|
||||
→ App SDK
|
||||
```
|
||||
|
||||
新的 Runtime/App SDK 边界不得再依赖旧 `app.id` 的供应商命名语义。R0 负责冻结新旧字段的映射表、拒绝规则和双向 fixture;在映射完成前,旧协议继续只由 Runtime 适配层处理,App 永远不直接读取它。
|
||||
|
||||
### 5.3 Runtime 筛选链
|
||||
|
||||
```text
|
||||
Transport 原始输入
|
||||
→ 版本、type、app_scope/conversation_id、大小、schema 校验
|
||||
→ Agent 身份与会话关联校验
|
||||
→ id / sequence / cursor 去重与顺序处理
|
||||
→ App 安装、启用、版本、Host 兼容性校验
|
||||
→ Tool / Capability、Inventory、参数、策略、App 启动和前台条件校验
|
||||
→ conversation / instance / operation 所属关系校验
|
||||
→ Manifest 订阅声明与 SDK 订阅条件求交
|
||||
→ Runtime Event / App Inbox / cursor 持久化
|
||||
→ 向目标 App SDK 投递标准化消息
|
||||
```
|
||||
|
||||
Runtime 不广播原始 Agent 消息。相同 conversation 下,Chat 和 Voice 可以收到经 Runtime 投影的 Agent status;白板只收到本实例声明的 patch、Tool 调用和 lifecycle 事件,除非其 Manifest 明确申请并获准其他订阅。
|
||||
|
||||
### 5.4 App SDK 的实时 Agent 消息能力
|
||||
|
||||
SDK 同时提供实时订阅和可靠 Inbox 补读:
|
||||
|
||||
```ts
|
||||
interface AgentMessageAPI {
|
||||
list(request?: {
|
||||
conversation_id?: ConversationID;
|
||||
after?: AgentMessageCursor;
|
||||
limit?: number;
|
||||
}): Promise<AgentMessagePage>;
|
||||
|
||||
subscribe(
|
||||
options: {
|
||||
conversation_id?: ConversationID;
|
||||
types?: readonly AgentMessageType[];
|
||||
include_pending?: boolean;
|
||||
},
|
||||
handler: (message: AgentAppMessage) => Promise<void> | void,
|
||||
): Unsubscribe;
|
||||
|
||||
acknowledge(message_id: string): Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
投递语义:
|
||||
|
||||
1. Runtime 先校验、标准化和持久化,后调用订阅者;
|
||||
2. 每条消息有唯一 `message_id`,App 必须幂等处理;
|
||||
3. 展示类消息可自动 ACK;Tool 调用、状态 patch 和需业务处理的消息要求 App 显式 ACK;
|
||||
4. App 未运行、暂停或崩溃时,消息进入该 App 的 Inbox;恢复后 `list()` 与 `subscribe()` 补齐;
|
||||
5. App 禁用、移除或不兼容时,Runtime 对关键 Agent 调用返回确定拒绝,不能静默丢弃。
|
||||
|
||||
实际投递集是:
|
||||
|
||||
```text
|
||||
Manifest agent_subscriptions
|
||||
∩ SDK subscribe filter
|
||||
∩ App 当前权限
|
||||
∩ conversation / instance scope
|
||||
∩ Agent target app_scope
|
||||
∩ Runtime Policy
|
||||
```
|
||||
|
||||
## 6. Runtime SDK v1
|
||||
|
||||
SDK 是上层 App 使用 Runtime 的唯一标准入口。Core App 拿到完整 App SDK;Installed App 只得到同一语义的受限 Surface Bridge SDK。
|
||||
|
||||
```ts
|
||||
interface LineUpAppRuntimeSDK {
|
||||
readonly app: AppContext;
|
||||
readonly lifecycle: AppLifecycleAPI;
|
||||
readonly state: AppStateAPI;
|
||||
readonly agentMessages: AgentMessageAPI;
|
||||
readonly actions: AppActionAPI;
|
||||
readonly tools: AppToolAPI;
|
||||
readonly apps: AppNavigationAPI;
|
||||
readonly artifacts: ArtifactAPI;
|
||||
readonly sessionData: MiniAppSessionDataAPI;
|
||||
readonly capabilities: CapabilityRequestAPI;
|
||||
readonly diagnostics: DiagnosticsAPI;
|
||||
}
|
||||
```
|
||||
|
||||
### 6.1 Context、状态和生命周期
|
||||
|
||||
```ts
|
||||
interface AppContext {
|
||||
app_scope: AppScope;
|
||||
app_version: string;
|
||||
instance_id: AppInstanceID;
|
||||
kind: "core" | "installed";
|
||||
entrypoint: string;
|
||||
scope: {
|
||||
conversation_id?: ConversationID;
|
||||
operation_id?: OperationID;
|
||||
parent_instance_id?: AppInstanceID;
|
||||
};
|
||||
granted_permissions: readonly AppPermission[];
|
||||
}
|
||||
|
||||
interface AppStateAPI<ViewModel = unknown> {
|
||||
snapshot(): ViewModel;
|
||||
subscribe(listener: (view: ViewModel, change: AppStateChange) => void): Unsubscribe;
|
||||
}
|
||||
```
|
||||
|
||||
App 只读取按其 Scope 裁剪的 View Model,不读取全量 Runtime State。生命周期包含 `start`、`foreground`、`background`、`suspend`、`restore` 与 `closing`;Runtime 保留禁用、移除和强制收口的最终权力。
|
||||
|
||||
### 6.2 Action、Tool 与跨 App 导航
|
||||
|
||||
```ts
|
||||
interface AppActionAPI {
|
||||
dispatch(action: AppAction): Promise<CommandReceipt>;
|
||||
}
|
||||
|
||||
interface AppToolAPI {
|
||||
onInvoke(listener: (call: AppToolInvocation) => Promise<AppToolOutcome>): Unsubscribe;
|
||||
progress(request: { call_id: ToolCallID; progress: ToolProgress }): Promise<void>;
|
||||
complete(request: { call_id: ToolCallID; result: JsonValue }): Promise<void>;
|
||||
fail(request: { call_id: ToolCallID; code: AppToolErrorCode; message?: string }): Promise<void>;
|
||||
}
|
||||
|
||||
interface AppNavigationAPI {
|
||||
listAvailable(): readonly AppSummary[];
|
||||
launch(request: LaunchAppRequest): Promise<AppInstanceHandle>;
|
||||
focus(instanceID: AppInstanceID): Promise<void>;
|
||||
close(instanceID: AppInstanceID): Promise<void>;
|
||||
openDefaultApp(): Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
App 只能提交声明性 Action,不能构造原始 Agent Envelope。跨 App 打开、聚焦和关闭也必须经 Runtime 校验目标 App 的启用状态、入口、展示模式和会话作用域。
|
||||
|
||||
### 6.3 MiniApp session data、Artifact 与 Capability
|
||||
|
||||
Runtime 为当前 MiniApp App 子会话提供一份受限的通用 JSON 数据字典。MiniApp 定义其中的业务语义、嵌套
|
||||
结构、`current` / `history`、是否保存历史以及业务上是否允许修改;Runtime 不需要、也不得根据每个 App 的
|
||||
字段定义专属接口或业务 schema。Runtime 是隔离、并发裁决、持久化、恢复和技术性清理的唯一所有者。它不是
|
||||
供 App 跨 scope 查询或读写的数据库,也不等同于 Conversation Store、Tool/operation Store、outbox 或 Artifact Store。
|
||||
|
||||
```ts
|
||||
interface MiniAppSessionDataAPI<Data extends JsonObject = JsonObject> {
|
||||
get(): Promise<{ data: Data | null; revision: number }>;
|
||||
replace(request: { data: Data; expected_revision: number }): Promise<{ revision: number }>;
|
||||
subscribe(listener: (snapshot: { data: Data | null; revision: number }) => void): Unsubscribe;
|
||||
}
|
||||
```
|
||||
|
||||
`sessionData` 的同步语义是通用 SDK 契约:空数据固定为 `{ data: null, revision: 0 }`;订阅在 Runtime 的当前
|
||||
`app_scope + app_session_id` 串行顺序中注册,首次回调一定是注册时的完整快照,随后回调的 revision 严格递增。因而
|
||||
`get()` 与 `subscribe()` 之间的成功写入不会丢失:它要么已成为订阅首帧,要么作为紧随其后的更新到达。重复 / 旧
|
||||
revision 由 SDK 忽略;revision 跳跃或 Bridge 重连时,SDK 重新 `get()` 并建立新订阅。`expected_revision` 冲突只
|
||||
拒绝旧写入,不自动合并 MiniApp 业务数据;多入口协作写入是后续专项 Runtime 设计,不能由本通用 JSON 接口猜测。
|
||||
|
||||
每次调用的存储边界由不可伪造的 SDK context 推导:
|
||||
|
||||
```text
|
||||
app_scope + app_session_id
|
||||
```
|
||||
|
||||
App 不得指定、读取或写入其他 App、其他 App 子会话、Conversation Store 或 Runtime 内部记录。Runtime 只校验
|
||||
JSON 合法性、通用大小 / 解析深度配额与 `expected_revision`;旧 Surface、重复点击或并发写入不能覆盖较新的数据。
|
||||
刷新、Surface 重载和 Runtime 重启后,Runtime 向同一个 App 子会话恢复最后一个有效数据版本。App 禁用或移除时,
|
||||
Runtime 按用户确认和全局保留策略清理其数据;业务数据是否“历史只读”由 MiniApp 自己定义,不作为 Runtime 的
|
||||
统一业务语义。
|
||||
|
||||
MiniApp session data 不替代 Runtime operation。凡是会影响 Agent Tool 终态、deadline、outbox、焦点、权限或
|
||||
实例生命周期的动作,仍必须通过 Runtime Command / operation 原子裁决。例如 Pomodoro 可以将显示状态保存在
|
||||
自己的 session data,但 `ends_at` 到期、用户中断与唯一 Tool result 必须由 Runtime 的 deadline operation 负责,
|
||||
不能由 MiniApp 自行完成或直接发送结果。完成后写入 IM 的记录是独立、不可变的静态副本,不会随 MiniApp 后续
|
||||
修改 session data 而改变。
|
||||
|
||||
```text
|
||||
Artifact
|
||||
Runtime 管理元数据、受限读取、创建、会话引用、下载和用户保存。
|
||||
|
||||
Session Data
|
||||
Runtime 为每个 app_scope + app_session_id 提供隔离的通用 JSON 数据;管理 revision、配额、恢复与
|
||||
生命周期清理,不理解 MiniApp 的业务 schema。UI 动画、滚动位置等短暂渲染状态不必持久化。
|
||||
|
||||
Capability
|
||||
App 以 purpose + input 请求;Runtime 决定是否确认、调用 Host、审计并返回受控结果。
|
||||
```
|
||||
|
||||
Capability SDK 形状:
|
||||
|
||||
```ts
|
||||
interface CapabilityRequestAPI {
|
||||
request<T extends JsonValue>(request: {
|
||||
capability: CapabilityName;
|
||||
purpose: string;
|
||||
input: JsonValue;
|
||||
scope?: AppScope;
|
||||
}): Promise<CapabilityResult<T>>;
|
||||
}
|
||||
```
|
||||
|
||||
Runtime 必须检查:Manifest 声明、App 启用状态、Host 支持、前台要求、用户确认、系统权限、策略、速率限制和审计。结果只能是 `completed`、`cancelled_by_user`、`permission_denied`、`unsupported_on_host`、`policy_denied`、`expired` 或受控 `failed`,不暴露路径、token 或底层原生异常。
|
||||
|
||||
## 7. Tool、Inventory 与 Agent 调用
|
||||
|
||||
### 7.1 App Tool 声明
|
||||
|
||||
每个 App 可以声明 Agent 可调用 Tool。当前的完整定位是:
|
||||
|
||||
```text
|
||||
app_scope / method / contract_version
|
||||
|
||||
whiteboard / board.create / 1
|
||||
voice / voice.request_recording / 1
|
||||
draw-and-guess / game.start_round / 1
|
||||
```
|
||||
|
||||
由 SDK Tool 声明生成的 Manifest Tool 描述至少包括:标题、面向 Agent 的说明、输入/输出 JSON Schema、调用模型、超时、幂等性、前台要求、风险等级、App 启动策略和可能使用的 Capability;它是安装和运行时使用的产物,不是开发者再维护的一份 Tool 源文件。
|
||||
|
||||
调用模型固定为:
|
||||
|
||||
| 模型 | 用途 | 示例 |
|
||||
|---|---|---|
|
||||
| `query` | 只读、快速 | 查询画板摘要。 |
|
||||
| `command` | 确定性状态改变 | 创建白板、开始一局游戏。 |
|
||||
| `interactive` | 必须等待用户参与 | 录音、填写复杂表单。 |
|
||||
| `operation` | 长时间执行并有进度 | 导出画板、处理大文件。 |
|
||||
|
||||
### 7.2 动态 Runtime Inventory
|
||||
|
||||
Runtime 向每个活跃 Agent 会话发布 revisioned Inventory。它包含当前可用的标准组件、已启用 App、Surface、Tool 和 Capability;它不是安装命令,也不携带 Bundle 源码、token、文件路径或用户私有内容。
|
||||
|
||||
```text
|
||||
Agent 可见 Tool
|
||||
= 已验证 Manifest Tool
|
||||
∩ App enabled
|
||||
∩ Host supported
|
||||
∩ 用户 / 组织策略允许
|
||||
∩ Agent + conversation scope 允许
|
||||
∩ 所需前置条件满足
|
||||
```
|
||||
|
||||
App 启用、禁用、更新、撤销、Host 能力变化或策略收紧后,Runtime 增加 revision 并重新发布。Agent 的 Tool 调用必须携带 `inventory_revision`;旧 revision 的调用必须安全拒绝并提示 Agent 刷新清单。
|
||||
|
||||
### 7.3 Tool 调用闭环
|
||||
|
||||
```text
|
||||
Agent tool.invoke
|
||||
→ Runtime 校验 Envelope / Inventory / Tool / 参数 / Scope
|
||||
→ Tool Router 判断直接执行、启动 App、切换前台或等待用户交互
|
||||
→ App Instance / Focus Manager 创建或切换实例
|
||||
→ Interaction App、交互模式或扩展 App 承接请求
|
||||
→ Runtime / App SDK 发送 protocol receipt、progress / result / error
|
||||
→ Runtime 校验输出、持久化、更新焦点并回传 Agent
|
||||
```
|
||||
|
||||
长期 Tool 的协议状态与业务结果必须分开:`accepted` 表示 Runtime 已接收请求,`progress` 表示业务正在推进或刚刚
|
||||
真正开始;它们是按 `call_id` 持久化、可重放的协议事实,不受 Tool output schema 约束。只有最终 `result`(或
|
||||
受控 `error`)才必须通过 Tool 的 output schema,且同一 call_id 只能有一个最终业务结果。对于 Pomodoro,只有
|
||||
Host 已确认前台且 Runtime 创建 operation 后的 `started` progress,才允许 Agent 向用户说“已经开始计时”。
|
||||
|
||||
MiniApp 启动也使用同一条 protocol receipt / progress 通道,而不让 MiniApp 直接联系 Agent:Runtime 持久化
|
||||
`starting → ready | failed | cancelled` 后,向触发启动的 call_id 发送 `accepted / starting`、`activation_ready`、
|
||||
`activation_failed` 或 `activation_cancelled`。Agent 收到 ready 后再发送依赖调用是推荐方式,但 Runtime 必须持久化并
|
||||
等待提前到达的合法 `app_ready` / `foreground_required` 调用,ready 后按到达顺序执行;失败 / 取消时受控拒绝等待调用。
|
||||
`activation_not_required` 调用不等待,Pomodoro 的 `interrupt` 因此可以取消启动中的专注。Pomodoro 的 `started` 已同时
|
||||
表示 activation ready、已在前台且计时真实开始,不额外发送重复的 `activation_ready`。
|
||||
|
||||
至少支持以下确定错误码:
|
||||
|
||||
```text
|
||||
cancelled_by_user permission_denied app_disabled
|
||||
app_not_installed app_version_mismatch tool_not_visible
|
||||
invalid_arguments foreground_required operation_expired
|
||||
handler_failed
|
||||
```
|
||||
|
||||
Agent Tool 是 App 在 SDK 源码中声明、构建生成 Manifest Tool 描述后由 Runtime 发布给远端 Agent 的业务调用契约;它不是用户 UI 的公共操作入口。Capability 是 Runtime / Host 的系统能力。Agent Tool 可在 Runtime 裁决后请求 Capability,但不会因声明 Tool 自动获得麦克风、文件或剪贴板权限;本地 UI Action 也必须走自己的 SDK / Bridge 校验路径。
|
||||
|
||||
## 8. Surface 与安全边界
|
||||
|
||||
### 8.1 标准组件优先
|
||||
|
||||
文字、Markdown、图片、链接、状态、任务进度、choice、confirm、input、Artifact 基础预览优先采用 Runtime / Core App 的可信内建渲染器。它们必须可访问、可测试、可离线恢复,并保持 Markdown sanitizer、外链保护和严格 schema。
|
||||
|
||||
Surface 仅用于画板、地图、图表、复杂表单、游戏、专业编辑器等内建组件不足以表达的复杂交互。
|
||||
|
||||
### 8.2 Installed App Surface
|
||||
|
||||
下载型 App 运行在隔离容器中:
|
||||
|
||||
```text
|
||||
iframe sandbox="allow-scripts"
|
||||
- 不带 allow-same-origin
|
||||
- 不带 allow-popups / allow-top-navigation / allow-forms
|
||||
- 默认 CSP 禁止网络和外部脚本
|
||||
- 只经严格 postMessage / Surface Bridge SDK 通信
|
||||
```
|
||||
|
||||
Runtime/Host 必须验证 `event.source`、当前 `instance_id`、消息类型、事件名、JSON schema、消息大小和声明的投递策略。Surface 只能接收 state patch、触发已声明事件、处理已声明 Tool 调用、通过 Bridge 使用 Runtime 提供的当前 App 子会话 session data 和请求受控 Capability。
|
||||
|
||||
Surface 不能:
|
||||
|
||||
```text
|
||||
读取父页面 DOM、localStorage 或 token
|
||||
调用 Tauri invoke
|
||||
访问其他 App 的数据和实例
|
||||
直接访问 Agent / AppServer
|
||||
任意联网、导航、弹窗或加载远端脚本
|
||||
直接执行 app.call / 系统能力
|
||||
```
|
||||
|
||||
用户在 Surface 中的操作只是 App Event;需要系统副作用时,Runtime 仍按 Capability 规则确认、执行和审计。
|
||||
|
||||
### 8.3 Bundle 与发布
|
||||
|
||||
当前已验证的生产安全原则保持不变:Bundle 必须是不可变 artifact,执行前检查来源、大小、SHA-256、签名、Host 兼容性和回滚条件;验证失败不得进入 active cache。开发期 inline bundle 只能是受限开发 fixture,不是长期市场供应方式。
|
||||
|
||||
本阶段仅定义本地 `app_scope`,不定义开放市场发布者身份。Bundle 信任、App 管理和 Tool 可见性仍必须由 Runtime 控制;将来引入供应商身份时须以新 Manifest 版本扩展,不能放宽本节隔离规则。
|
||||
|
||||
## 9. App Manifest 最小契约
|
||||
|
||||
Manifest 的 tools 区块由 MiniApp SDK 的 `defineAgentTools(...)` 在构建时生成。开发者在代码中声明 Tool、schema、
|
||||
activation requirement 和本地 handler,不维护第二份手写描述;生成的 Manifest 只保存不可执行的公开契约,Bundle
|
||||
内部 SDK 自己保存 `method → handler` 映射。
|
||||
|
||||
```json
|
||||
{
|
||||
"format": "lineup.app.v1",
|
||||
"app_scope": "whiteboard",
|
||||
"version": "1.0.0",
|
||||
"runtime_sdk": {
|
||||
"api_version": "1",
|
||||
"required_features": [
|
||||
"app.lifecycle.v1",
|
||||
"app.tools.v1",
|
||||
"surface.state.v1",
|
||||
"app.session-data.v1"
|
||||
],
|
||||
"optional_features": ["artifact.create.v1"]
|
||||
},
|
||||
"entrypoints": [
|
||||
{"id": "canvas", "kind": "contextual", "default_eligible": false}
|
||||
],
|
||||
"agent_subscriptions": [
|
||||
{"type": "lineup.app.state.patch", "scope": "instance"},
|
||||
{"type": "lineup.tool.invoke", "scope": "conversation"}
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
"method": "board.create",
|
||||
"contract_version": "1",
|
||||
"handling": "direct",
|
||||
"delivery": "miniapp_sdk",
|
||||
"activation_requirement": "app_ready",
|
||||
"input_schema": {"type": "object", "additionalProperties": false},
|
||||
"output_schema": {"type": "object", "additionalProperties": false}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Runtime 在安装、启用和启动时验证 SDK API 版本与 feature 集;App 不兼容、未启用或当前 Host 不支持时,不得进入 Inventory、创建实例或接收 Tool 调用。
|
||||
|
||||
## 10. Tauri 参考实现的最终模块边界
|
||||
|
||||
```text
|
||||
lineup-app/
|
||||
├── runtime-core/
|
||||
│ ├── communication/ AppServer transport、sync、outbox
|
||||
│ ├── coordination/ event、state、router、policy、audit
|
||||
│ ├── apps/ app registry、instance manager、default app
|
||||
│ ├── tools/ tool registry、inventory、call lifecycle
|
||||
│ ├── capabilities/ capability gateway
|
||||
│ └── persistence/ runtime store、app inbox、instance state snapshot、artifact metadata
|
||||
├── runtime-sdk/
|
||||
│ ├── app.ts Core App SDK
|
||||
│ ├── manifest.ts App/Tool/Subscription 类型
|
||||
│ ├── protocol.ts RuntimeEnvelope / schema
|
||||
│ ├── errors.ts 稳定错误码
|
||||
│ └── testkit/
|
||||
├── surface-sdk/
|
||||
│ ├── bridge.ts sandbox message bridge
|
||||
│ └── surface.ts Installed App 最小 SDK
|
||||
└── tauri/
|
||||
├── src/
|
||||
│ ├── bootstrap/ 应用启动装配层
|
||||
│ ├── runtime-host/ Web/Tauri Host Provider adapter
|
||||
│ ├── shell/ switcher、default、recovery
|
||||
│ └── core-apps/ chat、app-registry、settings
|
||||
└── src-tauri/ Rust 文件、音频、通知、窗口 Provider
|
||||
```
|
||||
|
||||
`lineup-app/tauri/src/main.ts` 是当前 Tauri/Web Host 的启动装配入口:它创建 Host 侧适配、
|
||||
`LineUpRuntime` 与默认 Runtime App Host,并把它们接起来。它不创建或持有 Transport、
|
||||
Store、sync loop、outbox,也不解析原始 Agent payload。现阶段仍有可信 Renderer、Surface
|
||||
与 Capability 的 Host 集成代码;后续可以继续迁移这些 UI 适配,但不得把 Runtime 所有权
|
||||
重新放回 `main.ts`。
|
||||
|
||||
可直接迁移的现有基础:
|
||||
|
||||
| 当前模块 | 最终归属 |
|
||||
|---|---|
|
||||
| `transport-adapter.ts` | `runtime-core/communication/` |
|
||||
| `conversation-store.ts` | `runtime-core/persistence/` |
|
||||
| `interaction-kernel.ts` | `runtime-core/coordination/` 的协议入口/兼容适配基础 |
|
||||
| Tool/Task/Execution 状态机 | Chat App 的投影 + Runtime call state |
|
||||
| `surface-registry.ts` | `runtime-core/apps/` 的 App Registry 基础 |
|
||||
| `surface-instance-manager.ts` | `runtime-core/apps/` 的 Instance Manager 基础 |
|
||||
| Bundle manifest/cache/policy | `runtime-core/apps/` 与 Execution Plane |
|
||||
| `client-inventory.ts` | `runtime-core/tools/` 的动态 Inventory Publisher |
|
||||
| `capability-*` | `runtime-core/capabilities/` |
|
||||
| `trusted-dom-renderers.ts` | `tauri/src/core-apps/chat/` |
|
||||
|
||||
## 11. 实施顺序
|
||||
|
||||
### F0:冻结契约与兼容映射
|
||||
|
||||
- 定义 `RuntimeEnvelope`、`app_scope`、`conversation_id`、`instance_id`、`operation_id`、`call_id` 的类型和校验;
|
||||
- 定义旧 `lineup.v1.*` 到 RuntimeEnvelope 的兼容映射;
|
||||
- 定义 Runtime SDK v1、Surface Bridge SDK v1、App Manifest、Tool Descriptor 和错误码;
|
||||
- 为全部契约建立 golden fixture;不改变当前可验证的 M0~M4 行为。
|
||||
|
||||
### F1:Runtime Core 与 Interaction Core App(当前 `chat` 实现)
|
||||
|
||||
- 从 `main.ts` 提取单一 `LineUpRuntime`;
|
||||
- Runtime 独占 Transport、Store、outbox、原始消息校验和筛选;
|
||||
- 将当前图文 IM 迁为 Interaction Core App 的 `chat` 实现;
|
||||
- 当前 `chat` 用 `state.subscribe()` 和 `agentMessages.subscribe()` 获取已验证投影,不再依赖 Transport;
|
||||
- 保持登录、同步、本地回显、Markdown、Tool Call、Task、Artifact 的回归行为。
|
||||
|
||||
#### MVP-R1 实施状态(2026-08-04)
|
||||
|
||||
F0 与 F1 中支撑图文聊天迁移的最小闭环已落地并经自动化回归验证。此处的“完成”仅指下列 MVP 边界;Manifest、Installed App、完整 Tool Inventory 和应用市场仍属于后续阶段。
|
||||
|
||||
| MVP 项 | 当前实现 | 验证位置 |
|
||||
|---|---|---|
|
||||
| Runtime 单一所有权 | `LineUpRuntime` 唯一创建并持有 `TransportAdapter`、`ConversationStore`、`InteractionKernel`、同步循环与 outbox。 | `tauri/src/runtime/coordination/lineup-runtime.ts`、`lineup-runtime.test.ts` |
|
||||
| Core App 入口 | `CoreAppRegistry` 记录当前可作为默认入口的 Core App;`CoreAppHostRegistry` 再根据 `app_scope` 找到对应的可信装配器。当前默认实现仍是 `chat`,但 `main.ts` 不再直接依赖 Chat 内部 Renderer 和 Shell。 | `runtime/app-management/app-registry.ts`、`runtime-app-host.ts`、`core-apps/chat/chat-app-host.ts`、`runtime-app-host.test.ts` |
|
||||
| Chat SDK 边界 | Chat 仅以 `ChatRuntimeSDK` 订阅状态/Agent 消息、读取 Inbox、ACK,并以 Runtime Action 发送文本或交互动作。 | `runtime/app-management/app-sdk.ts`、`main.ts` |
|
||||
| 作用域与旧协议兼容 | 入站消息先经 `resolveIncomingScope`;旧 `lineup.v1` 自动映射为当前会话的 `chat` 作用域,显式非法或不匹配的 scope 在投递前拒绝。 | `runtime/coordination/runtime-envelope.ts`、`lineup-runtime.test.ts` |
|
||||
| 恢复与幂等 | `ConversationStore` 持久化 App Inbox;未 ACK 消息在 Runtime 重建后恢复,同一 `message_id` 不重复投递。 | `runtime/persistence/conversation-store.ts`、`conversation-store.test.ts`、`lineup-runtime.test.ts` |
|
||||
|
||||
本阶段不修改 AppServer 或 Hermes 的既有 `lineup.v1` 协议。兼容层只存在于 Runtime 内部,因此上层 Chat App 不读取旧协议字段,也不需要同步升级远端。
|
||||
|
||||
### F2:App Registry 与默认 App
|
||||
|
||||
- 将开发期 Surface Registry 迁为 Runtime App Registry;
|
||||
- 实现 App Instance Manager、App Focus Manager 和生命周期状态(foreground/background/suspended);
|
||||
- 实现 Runtime Tool Router / App Orchestrator:校验 Tool 后决定直接执行、启动 App、切换前台或等待用户交互;
|
||||
- 实现 App 启用、禁用、移除、版本记录、实例收口和默认入口选择;
|
||||
- 实现 `app-registry` Core App;
|
||||
- 将当前 `chat` 作为 Interaction App 的 IM 实现,为后续 Audio/Video 模式预留 entrypoint 和恢复策略。
|
||||
|
||||
### F3:Tool Registry、Inventory 与 SDK Inbox
|
||||
|
||||
- 解析 Manifest Tool/Subscription 并计算可见性;
|
||||
- 在 Runtime 连接与状态变化时同步 revisioned Inventory 给 Agent;Tool 可声明是否需要启动 App、是否要求前台以及结束后是否恢复原焦点;
|
||||
- 实现 Agent Tool → Runtime → App SDK → result/progress 的可靠闭环;
|
||||
- 将 MVP-R1 已实现的 Chat App Inbox、ACK、断线/崩溃恢复和拒绝码推广为所有受管理 App 的通用可靠投递机制。
|
||||
- 实现 `app.session-data.v1`:按 `app_scope + app_session_id` 隔离的通用 JSON 数据、revision 并发控制、
|
||||
通用配额、重启恢复与 lifecycle 清理;Runtime 不校验 MiniApp 业务 schema,且它不得替代 Tool/operation/outbox
|
||||
的终态裁决。
|
||||
|
||||
### F4:第一个 Installed App
|
||||
|
||||
- 选择画板或任务面板作为第一个完整 Installed App;
|
||||
- 验收 install → enable → Inventory → Tool 调用 → App 启动/前台切换 → Surface 事件 → Agent result → 原前台恢复 → disable/remove;
|
||||
- 语音/视频属于 Interaction App 的模式或受 Runtime 管理的扩展 App,必须复用 Runtime SDK、Tool、Artifact 和 Capability 通道,不建立独立 Agent 通信链路。
|
||||
|
||||
## 12. 完成准入条件
|
||||
|
||||
```text
|
||||
消息与隔离
|
||||
[ ] 缺少/非法 app_scope 或 conversation_id 的可路由消息被拒绝。
|
||||
[ ] App 不能收到其他 App 或其他 conversation 的 Agent 原始消息。
|
||||
[ ] App 未运行时关键消息可从 Inbox 有界恢复,重复投递不重复执行。
|
||||
|
||||
应用管理
|
||||
[ ] 启用/禁用/移除改变 Tool 可见性,并更新 Agent Inventory revision。
|
||||
[ ] 默认 App 失效时必定回退至 Interaction App 的 IM/`chat` Recovery 入口。
|
||||
[ ] 禁用/移除能收口活动实例、焦点栈、调用和私有数据清理流程。
|
||||
[ ] Agent 启动扩展 App 时,Runtime 能将当前前台实例切换到后台,并在扩展结束后恢复原焦点。
|
||||
|
||||
工具与能力
|
||||
[ ] Agent 只能调用当前 Inventory 中、参数 schema 合法的 Tool。
|
||||
[ ] Tool 的 result/progress/error 经 Runtime 校验、持久化和审计。
|
||||
[ ] MiniApp 只能读取和替换自身 App 子会话的合法 JSON session data;旧 revision、跨 App / 子会话、超配额
|
||||
和失效 SDK context 均被 Runtime 拒绝,刷新/重启后仅恢复最后一个有效版本。
|
||||
[ ] MiniApp session data 不能直接完成 Tool、写 outbox、改变焦点或绕过实例生命周期。
|
||||
[ ] App / Surface 无法绕过 Capability Gateway 获得系统权限。
|
||||
|
||||
安全
|
||||
[ ] Installed App 无法访问 Tauri invoke、Host DOM、token、任意网络或其他 App 数据。
|
||||
[ ] Bundle 只有在完整性和签名验证后才可运行;失败可回滚且不污染 active cache。
|
||||
```
|
||||
|
||||
## 13. 旧文档的后续定位
|
||||
|
||||
| 文档 | 保留价值 | 在本方案后的定位 |
|
||||
|---|---|---|
|
||||
| [App 层架构方案](lineup-app-layer-architecture.md) | M0~M4 已实现边界、测试和验收事实;Markdown、Surface、Capability 原则 | 迁移基础与历史实施记录。 |
|
||||
| [Runtime 与 App SDK 架构方案](lineup-runtime-sdk-architecture.md) | Runtime、App Manager、Tool Registry、SDK、消息筛选的完整初稿 | 被本文件收敛后的详细来源;以本文件的 `app_scope` 和实施顺序为准。 |
|
||||
| [UI Surface 与 App Capability 协议](lineup-ui-surface-protocol.md) | Surface sandbox、bridge、Capability 风险分级、inventory 和 Bundle 安全规则 | 协议细节来源;R0 需完成其旧字段到 RuntimeEnvelope 的版本化映射。 |
|
||||
|
||||
以后新增 App 设计、SDK 方法、Agent Tool、Surface 或 Capability 时,先修改本文件的边界/契约,再实施代码和细节协议,避免重新把功能堆回聊天页面或创建绕开 Runtime 的平行通道。
|
||||
Reference in New Issue
Block a user