feat(runtime): establish miniapp kernel and sdk design
This commit is contained in:
@@ -0,0 +1,733 @@
|
||||
# LineUp App 迭代定义:MiniApp SDK v1 与内置参考 MiniApp
|
||||
|
||||
**迭代编号:** 03.sdk_and_coreapp
|
||||
**状态:** 目标设计,待实现
|
||||
**日期:** 2026-08-04
|
||||
**前置基线:** [00.base.md](00.base.md)、[01.kernel.md](01.kernel.md)
|
||||
**权威架构:** [APP架构设计.md](../APP架构设计.md)
|
||||
|
||||
## 1. 迭代目标
|
||||
|
||||
本迭代不建设应用市场、服务端 Catalog、远程下载或第三方发布能力。它的目标是定义并实现
|
||||
**LineUp MiniApp SDK v1**,再用多个随 LineUp 开发版本内置的参考 MiniApp 验证这份 SDK。
|
||||
|
||||
```text
|
||||
LineUp App
|
||||
→ LineUp Runtime
|
||||
→ LineUp MiniApp SDK v1
|
||||
→ Interact MiniApp
|
||||
→ Task Dashboard MiniApp
|
||||
→ Whiteboard MiniApp
|
||||
```
|
||||
|
||||
本迭代完成后,应能证明:
|
||||
|
||||
```text
|
||||
Runtime 能以同一套 SDK 语义承载系统级 MiniApp 与受限参考 MiniApp;
|
||||
MiniApp 只能通过 SDK 收消息、接 Tool、报告进度/结果/错误、请求生命周期与 Surface;
|
||||
Runtime 始终拥有通信、Tool、焦点、存储、权限和审计的最终决定权。
|
||||
```
|
||||
|
||||
这里的“内置”指 `bundled-development`:MiniApp 的 Manifest、代码和测试 fixture 随当前
|
||||
LineUp 开发 Host 提供。它们不是远程下载的 Bundle,也不等于已经开放的应用市场。
|
||||
|
||||
## 2. 本迭代的产品与信任模型
|
||||
|
||||
### 2.1 正确层级
|
||||
|
||||
```text
|
||||
LineUp App 用户使用的主应用
|
||||
├── App Shell / Host 挂载、切换、通知、恢复、Host Provider
|
||||
├── LineUp Runtime 通信、可靠性、MiniApp 调度和安全决策
|
||||
└── MiniApps 运行在 Runtime 上的功能单元
|
||||
├── System MiniApp: Interact
|
||||
├── Bundled Reference: Task Dashboard
|
||||
└── Bundled Reference: Whiteboard
|
||||
```
|
||||
|
||||
Runtime 不是一个与 MiniApp 平级的产品 App;它是 LineUp App 内部提供给 MiniApp 的运行环境。
|
||||
|
||||
### 2.2 Interact 的定位
|
||||
|
||||
`Interact` 是第一个系统级 MiniApp,是用户与 Agent 的默认入口:
|
||||
|
||||
```text
|
||||
Interact
|
||||
├── IM Mode:本迭代必须实现并适配 SDK
|
||||
├── Audio Mode:只定义 SDK / 生命周期扩展位,不实现真实媒体能力
|
||||
├── Video Mode:只定义 SDK / 生命周期扩展位,不实现真实媒体能力
|
||||
└── IM 标准交互的默认 Renderer Provider:notice / choice / confirm / input
|
||||
```
|
||||
|
||||
当前实现仍保持兼容名称:
|
||||
|
||||
```text
|
||||
产品概念:Interact MiniApp
|
||||
当前 app_scope:chat
|
||||
当前目录:tauri/src/core-apps/chat/
|
||||
```
|
||||
|
||||
本迭代不得把 `chat` 重命名为 `interact`,不得迁移目录或旧 `lineup.v1` scope;命名迁移另行
|
||||
定义,避免破坏已验证的通信与恢复行为。
|
||||
|
||||
### 2.3 相同语义,不同权限视图
|
||||
|
||||
所有 MiniApp 都遵守 MiniApp SDK v1 的同一语义;系统级与参考/已安装 MiniApp 的区别是来源和
|
||||
UI 容器,而不是是否可以绕过 Runtime。
|
||||
|
||||
| 能力 | Interact System MiniApp | Task Dashboard / Whiteboard |
|
||||
|---|---:|---:|
|
||||
| 读取自身 Inbox、ACK | 可以 | 可以 |
|
||||
| 接收 Runtime Tool Call | 可以 | 可以 |
|
||||
| 上报 progress / result / error | 可以 | 可以 |
|
||||
| 请求前台、后台、关闭 | 可以,Runtime 决定 | 可以,Runtime 决定 |
|
||||
| 请求 Surface / Capability | 可以,经 Policy | 可以,经 Policy |
|
||||
| 使用可信内建 DOM | 可以 | Task Dashboard 可由受信 Host adapter 挂载;Whiteboard 必须走受限 Surface |
|
||||
| 直接访问 Transport、Store、Agent | 不可以 | 不可以 |
|
||||
| 直接访问 Tauri、Host DOM 根节点、任意网络 | 不可以 | 不可以 |
|
||||
| 修改 Focus、Registry、其他 MiniApp 数据 | 不可以 | 不可以 |
|
||||
|
||||
## 3. MiniApp SDK v1 契约
|
||||
|
||||
SDK 是 Runtime 根据 Manifest、实例状态、scope 和 Policy 注入的受限对象。SDK 中的所有写操作都
|
||||
是 **request**,不是对 Host、Store、Transport 或其他 MiniApp 的直接命令。
|
||||
|
||||
```ts
|
||||
interface LineUpMiniAppSDK {
|
||||
readonly context: MiniAppContext;
|
||||
|
||||
readonly inbox: MiniAppInboxAPI;
|
||||
readonly tools: MiniAppToolAPI;
|
||||
readonly ui: StandardInteractionAPI;
|
||||
readonly lifecycle: MiniAppLifecycleAPI;
|
||||
readonly surfaces: MiniAppSurfaceAPI;
|
||||
readonly capabilities: MiniAppCapabilityRequestAPI;
|
||||
}
|
||||
|
||||
type MiniAppContext = {
|
||||
app_scope: string;
|
||||
instance_id: string;
|
||||
conversation_id: string;
|
||||
app_version: string;
|
||||
state: "starting" | "foreground" | "background" | "suspended";
|
||||
};
|
||||
```
|
||||
|
||||
`context` 由 Runtime 在创建实例时注入。MiniApp 不可传入、伪造或修改 `app_scope`、
|
||||
`instance_id`、`conversation_id`,也不可获得用户身份、Agent 身份、登录 token、AppServer
|
||||
地址、Transport endpoint 或其他实例上下文。
|
||||
|
||||
### 3.1 Inbox API
|
||||
|
||||
```ts
|
||||
interface MiniAppInboxAPI {
|
||||
list(after_message_id?: string): readonly MiniAppMessage[];
|
||||
subscribe(listener: (message: MiniAppMessage) => void): Unsubscribe;
|
||||
acknowledge(message_id: string): boolean;
|
||||
}
|
||||
```
|
||||
|
||||
行为约束:
|
||||
|
||||
```text
|
||||
Agent / Runtime 消息
|
||||
→ Runtime 校验 Envelope、scope、目标 app_scope、instance 和去重
|
||||
→ 先持久化到该 MiniApp Inbox
|
||||
→ SDK 投递已筛选消息
|
||||
→ MiniApp 成功接管后 ACK
|
||||
→ Runtime 移除该可投递记录
|
||||
```
|
||||
|
||||
后台化、刷新、Surface 重载、断线和 Runtime 重启不得丢失未 ACK 的 Inbox 消息。MiniApp 只能
|
||||
列出和 ACK 自己 `app_scope + conversation_id + instance_id` 范围内的投递。
|
||||
|
||||
### 3.2 Tool API
|
||||
|
||||
```ts
|
||||
interface MiniAppToolAPI {
|
||||
subscribe(listener: (call: MiniAppToolCall) => void): Unsubscribe;
|
||||
get(call_id: string): MiniAppToolCall | undefined;
|
||||
reportProgress(call_id: string, progress: MiniAppToolProgress): Promise<CommandReceipt>;
|
||||
complete(call_id: string, result: JsonObject): Promise<CommandReceipt>;
|
||||
fail(call_id: string, failure: MiniAppToolFailure): Promise<CommandReceipt>;
|
||||
cancel(call_id: string, reason?: string): Promise<CommandReceipt>;
|
||||
}
|
||||
```
|
||||
|
||||
每一个调用都必须有 Runtime 持久化的通用记录:
|
||||
|
||||
```ts
|
||||
type RuntimeToolCallRecord = {
|
||||
call_id: string;
|
||||
tool_id: string;
|
||||
inventory_revision: string;
|
||||
app_scope: string;
|
||||
instance_id?: string;
|
||||
conversation_id: string;
|
||||
status:
|
||||
| "received"
|
||||
| "routing"
|
||||
| "waiting_for_app"
|
||||
| "running"
|
||||
| "submitted"
|
||||
| "completed"
|
||||
| "failed"
|
||||
| "cancelled"
|
||||
| "expired"
|
||||
| "rejected";
|
||||
input: JsonObject;
|
||||
result?: JsonObject;
|
||||
error_code?: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
};
|
||||
```
|
||||
|
||||
`complete`、`fail`、`cancel` 绝不能直接发送网络请求。Runtime 必须验证:
|
||||
|
||||
```text
|
||||
call_id 属于当前 MiniApp instance
|
||||
调用状态允许此迁移
|
||||
结果符合 ToolDescriptor.output_schema
|
||||
调用不是重复终态
|
||||
调用仍属于当前 conversation / scope
|
||||
MiniApp 和 Tool 仍处于启用状态
|
||||
```
|
||||
|
||||
验证成功后,Runtime 持久化记录和审计,再写入可靠 outbox 并回传 Agent。
|
||||
|
||||
### 3.3 Lifecycle API
|
||||
|
||||
```ts
|
||||
interface MiniAppLifecycleAPI {
|
||||
requestForeground(): Promise<CommandReceipt>;
|
||||
requestBackground(): Promise<CommandReceipt>;
|
||||
requestClose(reason?: string): Promise<CommandReceipt>;
|
||||
}
|
||||
```
|
||||
|
||||
MiniApp 只能请求,不能直接改变焦点或挂载其他 MiniApp:
|
||||
|
||||
```text
|
||||
MiniApp requestClose()
|
||||
→ Runtime 检查 pending Tool、Surface、operation 和 Policy
|
||||
→ 允许关闭或返回受控拒绝码
|
||||
→ 若关闭成功,Runtime 调整 focus stack
|
||||
→ Runtime 恢复前一有效 foreground instance
|
||||
```
|
||||
|
||||
### 3.4 标准交互 API
|
||||
|
||||
SDK v1 通过 `sdk.ui` 提供由 **Runtime 管理的标准交互库**。这是一组低复杂度、可恢复、可审计的
|
||||
标准输入输出,不是 Interact 专有 API,也不是 MiniApp 取得 Host 弹窗权限的旁路。Runtime 创建、
|
||||
持久化和校验记录,并依据调用者、容器和 Shell Policy 选择实际呈现方式。
|
||||
|
||||
每次请求的 `owner` 必须由 Runtime 根据 SDK 已绑定的 `MiniAppContext` 自动注入;MiniApp 不能传入、
|
||||
伪造或覆盖 `app_scope`、`instance_id`、`conversation_id` 或 `surface_id`。调用者可选提供
|
||||
`parent_call_id`,但 Runtime 必须验证该调用属于当前实例且状态允许关联,不能将其作为可信 owner。
|
||||
|
||||
```ts
|
||||
interface StandardInteractionAPI {
|
||||
request(
|
||||
request: StandardInteractionRequest,
|
||||
options?: {
|
||||
parent_call_id?: string;
|
||||
presentation?: "default" | "inline" | "modal";
|
||||
expires_at?: string;
|
||||
},
|
||||
): Promise<InteractionReceipt>;
|
||||
|
||||
get(interaction_id: string): StandardInteractionRecord | undefined;
|
||||
subscribe(listener: (record: StandardInteractionRecord) => void): Unsubscribe;
|
||||
cancel(interaction_id: string, reason?: string): Promise<CommandReceipt>;
|
||||
}
|
||||
|
||||
type StandardInteractionRequest =
|
||||
| NoticeRequest
|
||||
| ChoiceRequest
|
||||
| ConfirmRequest
|
||||
| InputRequest;
|
||||
```
|
||||
|
||||
第一版固定支持以下四种原语:
|
||||
|
||||
| 原语 | 用途 | 用户结果 |
|
||||
|---|---|---|
|
||||
| `notice` | 安全显示只读提示、状态或下一步说明。 | `acknowledged`;也可由 Runtime 记录为只读。 |
|
||||
| `choice` | 单选、多选或有限按钮选择。 | 有序且去重的 `action_ids`。 |
|
||||
| `confirm` | 明确同意/取消一个可解释操作。 | `approved: boolean`。 |
|
||||
| `input` | 受 schema 限制的文本、多行文本或数字输入。 | 按字段 ID 返回的结构化值。 |
|
||||
|
||||
最低请求形态:
|
||||
|
||||
```ts
|
||||
type NoticeRequest = {
|
||||
kind: "notice";
|
||||
title: string;
|
||||
message: string;
|
||||
acknowledge_label?: string;
|
||||
};
|
||||
|
||||
type ChoiceRequest = {
|
||||
kind: "choice";
|
||||
title: string;
|
||||
prompt: string;
|
||||
mode: "single-choice" | "multi-choice" | "button";
|
||||
actions: readonly { id: string; label: string; description?: string }[];
|
||||
};
|
||||
|
||||
type ConfirmRequest = {
|
||||
kind: "confirm";
|
||||
title: string;
|
||||
prompt: string;
|
||||
approve_label?: string;
|
||||
cancel_label?: string;
|
||||
};
|
||||
|
||||
type InputRequest = {
|
||||
kind: "input";
|
||||
title: string;
|
||||
prompt: string;
|
||||
fields: readonly {
|
||||
id: string;
|
||||
label: string;
|
||||
type: "text" | "textarea" | "number";
|
||||
required?: boolean;
|
||||
placeholder?: string;
|
||||
min_length?: number;
|
||||
max_length?: number;
|
||||
minimum?: number;
|
||||
maximum?: number;
|
||||
}[];
|
||||
submit_label?: string;
|
||||
cancel_label?: string;
|
||||
};
|
||||
```
|
||||
|
||||
标准交互的 owner 路由与呈现策略如下:
|
||||
|
||||
```text
|
||||
Task Dashboard / Whiteboard 正在处理自身工作
|
||||
→ sdk.ui.request(choice / confirm / input / ..., { parent_call_id? })
|
||||
→ Runtime 从当前 SDK Context 注入不可伪造的 owner,并校验可选 parent_call_id、schema 与 Policy
|
||||
→ Runtime 创建持久化 StandardInteractionRecord
|
||||
→ Runtime / Shell 根据 owner 的有效容器选择受批准的标准 Renderer
|
||||
├── Agent 在 IM 中的提问:由 Interact 在时间线/卡片内呈现
|
||||
└── 前台 MiniApp 的通用事务提示:在该 MiniApp 自己有效的容器/Surface 中呈现标准 modal、sheet 或 card
|
||||
→ 用户选择、确认、输入、取消或超时
|
||||
→ Runtime 持久化结果,仅投递回 owner MiniApp 的 Tool/Inbox
|
||||
→ 原 MiniApp 决定 complete / fail / 继续 progress
|
||||
```
|
||||
|
||||
`presentation` 只是调用偏好,不是强制指令;Runtime / Shell 可基于焦点、Surface、Policy 和可用
|
||||
Renderer 降级或拒绝。Agent 发来的 `lineup.v1.tool.call(choice | confirm | input)` 保持兼容:Runtime
|
||||
创建同一类记录,其 owner 是 Interact 的 IM 上下文(`source = agent_tool`),并由 Interact 作为
|
||||
默认可信 IM Renderer Provider 呈现。它们不需要 MiniApp 提供父 Tool Call。
|
||||
|
||||
这意味着标准交互不会成为 MiniApp 直连用户界面或跨 App 操作的旁路:
|
||||
|
||||
```text
|
||||
MiniApp 不能在 Host DOM 注入任意弹窗、表单或远端 HTML
|
||||
MiniApp 不能伪造 owner、interaction_id,或替其他 owner 查询、提交、取消结果
|
||||
Interact 不能直接把结果发送给 Agent
|
||||
交互结果必须先回到 Runtime,再交给拥有该 owner 的 MiniApp
|
||||
```
|
||||
|
||||
`notice` 是 SDK v1 新增的只读确认原语。Agent IM 与 MiniApp 发起的请求共享一套
|
||||
`StandardInteractionRecord`、状态机、持久化、过期、去重、owner 路由和标准 Renderer 协议,
|
||||
但不要求共享一个 Interact 卡片实例或切换到 Interact。
|
||||
|
||||
`StandardInteractionRecord` 至少包含以下 Runtime 内部字段;其中 `owner` 只可由 Runtime 写入:
|
||||
|
||||
```ts
|
||||
type StandardInteractionOwner = {
|
||||
app_scope: string;
|
||||
instance_id: string;
|
||||
conversation_id: string;
|
||||
parent_call_id?: string;
|
||||
surface_id?: string;
|
||||
source: "agent_tool" | "miniapp_tool" | "runtime_policy";
|
||||
};
|
||||
|
||||
type StandardInteractionRecord = {
|
||||
interaction_id: string;
|
||||
owner: StandardInteractionOwner;
|
||||
kind: "notice" | "choice" | "confirm" | "input";
|
||||
request: StandardInteractionRequest;
|
||||
status: "pending" | "presented" | "submitted" | "completed" | "cancelled" | "expired" | "failed";
|
||||
result?: StandardInteractionResult;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
expires_at?: string;
|
||||
};
|
||||
```
|
||||
|
||||
状态必须有界:
|
||||
|
||||
```text
|
||||
pending → presented → submitted → completed | cancelled | expired | failed
|
||||
```
|
||||
|
||||
终态不可重新操作;刷新、断线和重启后可恢复尚未终态的可信卡片与未提交的 `input` 草稿。
|
||||
|
||||
### 3.5 Surface 与 Capability API
|
||||
|
||||
SDK v1 定义请求语义,不直接授予 Host 权限:
|
||||
|
||||
```ts
|
||||
interface MiniAppSurfaceAPI {
|
||||
requestOpen(request: MiniAppSurfaceRequest): Promise<CommandReceipt>;
|
||||
update(surface_id: string, patch: JsonObject): Promise<CommandReceipt>;
|
||||
requestClose(surface_id: string): Promise<CommandReceipt>;
|
||||
}
|
||||
|
||||
interface MiniAppCapabilityRequestAPI {
|
||||
request(request: {
|
||||
capability: string;
|
||||
reason: string;
|
||||
arguments: JsonObject;
|
||||
}): Promise<CommandReceipt>;
|
||||
}
|
||||
```
|
||||
|
||||
Runtime 必须根据 Manifest、实例状态、Capability Policy、用户确认和 Host 支持情况决定是否
|
||||
执行。SDK v1 不开放:
|
||||
|
||||
```text
|
||||
fetch / 任意网络
|
||||
任意文件系统
|
||||
Tauri invoke
|
||||
直接剪贴板、麦克风、摄像头
|
||||
Host DOM 根节点
|
||||
原始 AppServer / Agent 协议
|
||||
```
|
||||
|
||||
本迭代可定义 Capability Request 的类型、拒绝码、审计和测试,但不必为参考 MiniApp 开放真实
|
||||
麦克风、摄像头或文件选择权限。
|
||||
|
||||
## 4. Manifest、Tool Contract 与 Inventory
|
||||
|
||||
### 4.1 MiniApp Manifest v1
|
||||
|
||||
本迭代冻结最小 Manifest 契约:
|
||||
|
||||
```ts
|
||||
type MiniAppManifest = {
|
||||
app_scope: string;
|
||||
version: string;
|
||||
kind: "system" | "bundled-reference";
|
||||
tools: readonly ToolDescriptor[];
|
||||
subscriptions: readonly MiniAppSubscription[];
|
||||
requested_capabilities: readonly string[];
|
||||
host: {
|
||||
min_version: string;
|
||||
surface_required: boolean;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
Manifest 是 Runtime 的输入,不是 MiniApp 可写状态;MiniApp 不可在运行时扩展 Tool、订阅或
|
||||
权限。动态安装、下载、更新、回滚和移除不属于本迭代。
|
||||
|
||||
### 4.2 Tool Descriptor v1
|
||||
|
||||
```ts
|
||||
type ToolDescriptor = {
|
||||
id: string; // 例如 task-dashboard.open
|
||||
version: 1;
|
||||
handling: "direct" | "interactive" | "launch" | "foreground" | "operation";
|
||||
target: {
|
||||
app_scope: string;
|
||||
requires_foreground: boolean;
|
||||
restore_previous_focus: boolean;
|
||||
};
|
||||
input_schema: JsonSchema;
|
||||
output_schema: JsonSchema;
|
||||
permissions?: readonly string[];
|
||||
timeout_ms?: number;
|
||||
};
|
||||
```
|
||||
|
||||
第一版 JSON Schema 只支持可明确实现和测试的子集:
|
||||
|
||||
```text
|
||||
object / string / number / boolean / array
|
||||
required
|
||||
properties
|
||||
additionalProperties = false
|
||||
enum
|
||||
minLength / maxLength
|
||||
minimum / maximum
|
||||
maxItems
|
||||
```
|
||||
|
||||
禁止接受远端 schema 中的递归引用、正则执行、脚本、URL 加载、函数名或任意扩展关键字。
|
||||
|
||||
### 4.3 Revisioned Inventory
|
||||
|
||||
Runtime 在 MiniApp 的启用状态、Manifest Tool 或可见 Capability 发生变化时,生成最小化且带
|
||||
revision 的 Inventory。Agent Tool Invoke 必须携带该 revision:
|
||||
|
||||
```text
|
||||
Agent Tool Invoke
|
||||
→ Runtime 发现 inventory_revision 不匹配
|
||||
→ 拒绝,不投递给 MiniApp,不执行任何 Host 行为
|
||||
→ 以受控状态提示 Agent 使用最新 Inventory
|
||||
```
|
||||
|
||||
本迭代可复用现有 `lineup.v1.client.inventory` 发送路径;AppServer 只需要像普通会话消息一样
|
||||
透明转发,不需要实现应用目录或下载 API。
|
||||
|
||||
### 4.4 通用 Tool 路由
|
||||
|
||||
```text
|
||||
Agent Tool Invoke
|
||||
→ Runtime 校验 Envelope、Inventory revision、ToolDescriptor、输入 schema、scope、MiniApp 状态和权限
|
||||
→ 创建 RuntimeToolCallRecord 与审计记录
|
||||
→ Tool Router 判定 direct / interactive / launch / foreground / operation
|
||||
→ App Orchestrator 创建或复用 instance,调整 focus
|
||||
→ SDK Tool Inbox 投递
|
||||
→ MiniApp 经 SDK 报告 progress / result / error
|
||||
→ Runtime 校验 output schema,持久化,写 outbox,回传 Agent
|
||||
```
|
||||
|
||||
`notice`、`choice`、`confirm`、`input` 必须映射为 Runtime 统一的 `interactive` Tool Call /
|
||||
`StandardInteractionRecord`。Interact 负责 Agent/IM 情况下的默认可信渲染;其他 MiniApp 可在其
|
||||
有效容器中使用 Runtime 批准的同一标准 Renderer,不能因此保留 Chat 专用旁路或获得 Host 特权。
|
||||
|
||||
建议稳定拒绝码:
|
||||
|
||||
```text
|
||||
inventory_revision_mismatch
|
||||
tool_not_advertised
|
||||
tool_input_invalid
|
||||
tool_output_invalid
|
||||
app_disabled
|
||||
app_instance_not_found
|
||||
app_scope_mismatch
|
||||
lifecycle_denied
|
||||
capability_denied
|
||||
call_already_final
|
||||
```
|
||||
|
||||
## 5. 内置参考 MiniApp 工作定义
|
||||
|
||||
本迭代通过三个内置 MiniApp 覆盖 SDK v1 的不同能力面。它们不是应用市场候选,也不要求完整
|
||||
业务功能;每个 MiniApp 只实现足以验证 SDK 契约的最小真实闭环。
|
||||
|
||||
### 5.1 Interact:系统级 MiniApp 样本
|
||||
|
||||
**身份:** `kind = system`;当前兼容 `app_scope = chat`。
|
||||
**本迭代交付:** IM Mode 适配到 MiniApp SDK v1。
|
||||
|
||||
| 范围 | 工作定义 |
|
||||
|---|---|
|
||||
| Inbox | 使用通用 `sdk.inbox` 订阅、恢复和 ACK;不再依赖 Chat 特有投递语义。 |
|
||||
| 用户消息 | 保留 `conversation.sendText` 这一系统级扩展,但它必须进入 Runtime Action / outbox。 |
|
||||
| 标准原语 | 作为 Agent/IM 请求的默认可信 Renderer Provider,在时间线/卡片内呈现 Runtime 投递的标准交互记录。 |
|
||||
| 交互边界 | 不拥有交互记录,也不直接向 Agent 回传结果;结果必须由 Runtime 按 owner 路由。其他 MiniApp 可在自身有效容器使用 Runtime 批准的标准 Renderer。 |
|
||||
| Tool 结果 | 用户完成、取消或超时后调用 `sdk.tools.complete/fail/cancel`,由 Runtime 回传。 |
|
||||
| Mode | 明确 IM 的 `mode = im` Context;仅定义 Audio/Video 入口和恢复语义,不启用真实媒体。 |
|
||||
| 焦点 | 被参考 MiniApp 覆盖时接受 Runtime 的 background/suspended;不能自行切换回前台。 |
|
||||
|
||||
**不在范围:** 语音录制、视频通话、摄像头、独立 Audio/Video MiniApp、改名 `chat → interact`。
|
||||
|
||||
### 5.2 Task Dashboard:Tool 与生命周期样本
|
||||
|
||||
**身份:** `kind = bundled-reference`,`app_scope = task-dashboard`。
|
||||
**目标:** 验证 MiniApp Tool、progress/result/error、instance、focus 和恢复的最小闭环。
|
||||
|
||||
最小 Tool:
|
||||
|
||||
```text
|
||||
task-dashboard.open
|
||||
handling = launch
|
||||
输入:task_id、title、可选初始状态
|
||||
输出:status = completed | cancelled | failed
|
||||
|
||||
task-dashboard.update
|
||||
handling = operation
|
||||
输入:task_id、进度或状态
|
||||
输出:当前任务摘要
|
||||
```
|
||||
|
||||
最小用户体验:
|
||||
|
||||
```text
|
||||
Agent 调用 task-dashboard.open
|
||||
→ Runtime 创建 task-dashboard instance
|
||||
→ Interact 进入 background
|
||||
→ Shell 挂载 Task Dashboard
|
||||
→ MiniApp 展示任务标题、进度、当前状态和关闭动作
|
||||
→ MiniApp 用 sdk.tools.reportProgress / complete / fail 上报
|
||||
→ Runtime 持久化、回传 Agent、关闭实例并恢复 Interact
|
||||
```
|
||||
|
||||
Task Dashboard 的业务状态必须通过 SDK Tool / Inbox 获得;不得自行访问 AppServer、Store 或
|
||||
Agent。它可以使用随 LineUp 发布的受信 Host adapter,但 adapter 只做渲染装配,不可成为
|
||||
Transport 或 Tool Router 的第二实现。
|
||||
|
||||
Task Dashboard 必须至少使用一次 `sdk.ui.request`:例如在关闭未完成任务前请求 `confirm`,或需要
|
||||
任务说明时请求 `input`。Runtime 必须从该实例注入 owner,并在 Task Dashboard 当前有效容器中使用
|
||||
受批准的标准 modal、sheet 或 card;结果经 Runtime 返回该实例,期间不得强制切换到 Interact。
|
||||
|
||||
### 5.3 Whiteboard:隔离 Surface 样本
|
||||
|
||||
**身份:** `kind = bundled-reference`,`app_scope = whiteboard`。
|
||||
**目标:** 验证 SDK Surface Bridge、隔离执行、状态 patch、Artifact 元数据与恢复。
|
||||
|
||||
最小 Tool:
|
||||
|
||||
```text
|
||||
whiteboard.open
|
||||
handling = launch
|
||||
输入:board_id、title、可选初始画布状态
|
||||
输出:status、artifact_id(可选)
|
||||
|
||||
whiteboard.submit
|
||||
handling = operation
|
||||
输入:board_id、提交请求
|
||||
输出:artifact_id 或结构化画布摘要
|
||||
```
|
||||
|
||||
最小用户体验:
|
||||
|
||||
```text
|
||||
Agent 调用 whiteboard.open
|
||||
→ Runtime 校验已注册 bundled-reference Manifest
|
||||
→ Runtime 创建 whiteboard instance 并请求受限 Surface
|
||||
→ Host 挂载 opaque-origin iframe / Surface Bridge
|
||||
→ Whiteboard 仅通过 Bridge SDK 请求状态更新和提交结果
|
||||
→ Runtime 校验 patch / Artifact 元数据并持久化
|
||||
→ App 完成或失败,Runtime 关闭 Surface、恢复 Interact
|
||||
```
|
||||
|
||||
Whiteboard 不需要在本迭代实现多人协作、任意网络同步或完整绘图工具;重点是证明隔离 Surface
|
||||
不能读取 Host DOM、Tauri、认证状态或其他 MiniApp 数据。
|
||||
|
||||
Whiteboard 如需要低复杂度的事务提示(例如“确认提交白板?”),可通过 `sdk.ui` 请求标准交互。
|
||||
但画板内的文字编辑、画笔与颜色选择、拖放、工具栏、上下文菜单等高频或私有业务 UI 必须保留在
|
||||
Whiteboard 自己的 Surface 中,不能被错误抽象为 Runtime 标准交互。
|
||||
|
||||
## 6. Runtime 与 Host 的实现模块
|
||||
|
||||
本迭代预计在现有目录中演进,不重建并行 Runtime:
|
||||
|
||||
```text
|
||||
tauri/src/runtime/
|
||||
├── app-management/
|
||||
│ ├── miniapp-manifest.ts # Manifest v1、bundled-reference 注册
|
||||
│ ├── miniapp-sdk.ts # SDK v1 公共类型与受限视图
|
||||
│ ├── miniapp-tool-call-store.ts # 通用 Tool Call 持久化/恢复
|
||||
│ └── runtime-app-host.ts # 按 foreground instance 挂载/卸载 Host
|
||||
│
|
||||
├── coordination/
|
||||
│ ├── tool-router.ts # revision、schema、路由决策
|
||||
│ ├── miniapp-tool-orchestrator.ts # Tool → instance → SDK Inbox
|
||||
│ └── standard-interaction-service.ts # owner 注入、记录、路由、恢复与呈现 Policy
|
||||
│
|
||||
├── inventory/
|
||||
│ └── client-inventory.ts # revisioned Tool Inventory
|
||||
│
|
||||
└── persistence/
|
||||
└── conversation-store.ts # Tool Call、Inbox、workspace 有界恢复
|
||||
|
||||
tauri/src/
|
||||
├── core-apps/chat/ # Interact IM 的兼容实现
|
||||
│ └── standard-interaction-im-renderer.ts # Agent/IM 的默认标准交互 Renderer
|
||||
├── core-apps/task-dashboard/ # bundled-reference Tool/lifecycle 样本
|
||||
└── core-apps/whiteboard/ # bundled-reference Surface/Bridge 样本
|
||||
```
|
||||
|
||||
若目录名称最终改为 `miniapps/`,应单独进行机械迁移;本迭代优先保证 Runtime 边界和 SDK
|
||||
兼容,不能让命名迁移扩大风险。
|
||||
|
||||
## 7. 不在本迭代范围
|
||||
|
||||
以下内容必须明确排除:
|
||||
|
||||
```text
|
||||
服务端 App Catalog 或应用清单 API
|
||||
远程 Manifest / Bundle 下载
|
||||
安装、更新、回滚、卸载 UI
|
||||
第三方开发者发布、账号、审核、评分、支付或搜索
|
||||
任意网络 API
|
||||
真实麦克风、摄像头、文件选择或系统通知授权
|
||||
多人白板、实时游戏、完整语音/视频通话
|
||||
chat / interaction 命名和协议 scope 迁移
|
||||
```
|
||||
|
||||
这些能力将在 MiniApp SDK 与参考 MiniApp 完成验证后,作为独立的应用分发和市场阶段推进。
|
||||
|
||||
## 8. 实施步骤
|
||||
|
||||
1. **冻结契约与 golden fixtures**
|
||||
- 定义 `MiniAppManifest v1`、`ToolDescriptor v1`、`MiniAppContext`、通用 Tool Call、
|
||||
Result/Progress/Error、Standard Interaction、SDK 稳定错误码;
|
||||
- 为合法、重复、过期 revision、非法 schema、scope 不匹配和终态重复建立 fixture;
|
||||
- 明确旧 `lineup.v1.tool.call` 的 `choice/confirm/input` 到 `interactive` Tool 的兼容映射,
|
||||
并为 `notice`、owner 自动注入、MiniApp 发起的 choice/confirm/input、取消、超时和重启恢复建立 fixture。
|
||||
|
||||
2. **实现 Runtime 通用 Tool 闭环**
|
||||
- 将 Inventory revision、输入/输出 schema、Tool Call Record、审计和 outbox 接入 Runtime;
|
||||
- 让 `ToolRouter` 和 `AppOrchestrator` 根据 ToolDescriptor 创建/复用实例并投递 SDK Tool Call;
|
||||
- 完成 Tool、Inbox、workspace 的断线与重启恢复。
|
||||
|
||||
3. **适配 Interact IM**
|
||||
- 以 `sdk.inbox` 和 `sdk.tools` 替换 Chat SDK 中的专用交互旁路;
|
||||
- 实现 Agent/IM 标准交互的默认 Renderer Provider,保持 Markdown、消息、notice、choice、confirm、input、Task 和现有回归行为;
|
||||
- 固化 IM Mode Context 与被覆盖/恢复的生命周期语义。
|
||||
|
||||
4. **实现 Task Dashboard 参考 MiniApp**
|
||||
- 注册 bundled-reference Manifest 和两个最小 Tool;
|
||||
- 实现启动、进度、结果、错误、关闭、回焦和重启恢复;
|
||||
- 使用真实 SDK,不测试用 Runtime 内部对象直连。
|
||||
|
||||
5. **实现 Whiteboard 参考 MiniApp**
|
||||
- 注册 bundled-reference Manifest、最小 Tool 和受限 Surface;
|
||||
- 验证 Bridge、patch、Artifact 元数据、关闭、失败和恢复;
|
||||
- 验证隔离拒绝路径与 Capability Request 拒绝路径。
|
||||
|
||||
6. **端到端验收与文档回填**
|
||||
- 运行完整单元测试和生产构建;
|
||||
- 通过 Tauri/Web Reference Host 完成代表性浏览器验收;
|
||||
- 将最终 SDK 形态与参考 MiniApp 结果回填 [APP架构设计.md](../APP架构设计.md)。
|
||||
|
||||
## 9. 验收目标
|
||||
|
||||
```text
|
||||
1. Runtime 向每个 MiniApp instance 注入不可伪造、范围受限的 MiniAppContext。
|
||||
2. Interact、Task Dashboard、Whiteboard 均通过 SDK 获取 Inbox、Tool 和生命周期能力;
|
||||
不直接访问 Transport、Store、Agent 或 Host 特权。
|
||||
3. Manifest Tool 具有稳定 ID、输入/输出 schema、handling、目标 scope 和版本。
|
||||
4. Runtime 只接受当前 Inventory revision 中、输入 schema 合法的 Tool Invoke。
|
||||
5. Runtime 拒绝未知 Tool、过期 revision、非法输入/输出、scope 不匹配、禁用 MiniApp、
|
||||
错误 instance 和重复终态;拒绝请求不得到达 MiniApp 或 Host。
|
||||
6. Interact 的 notice / choice / confirm / input 通过统一 Standard Interaction 在 IM 中完成、恢复和回声,
|
||||
不退化。
|
||||
7. Runtime 从 SDK-bound MiniAppContext 自动注入不可伪造的 interaction owner;可选 parent Tool
|
||||
引用必须归属于当前实例且通过验证。结果只能经 Runtime 返回 owner,不能直接发给 Agent 或其他 MiniApp。
|
||||
8. Task Dashboard 可验证 launch → foreground → progress → 标准交互 → result/error → close →
|
||||
Interact 恢复;标准交互在其有效容器呈现且不触发焦点切换。
|
||||
9. Whiteboard 可验证隔离 Surface open → patch → submit/close,并不能访问 Host DOM/Tauri/token;
|
||||
画板内的文字编辑等私有高频 UI 不通过 `sdk.ui` 路由。
|
||||
10. MiniApp 的 progress/result/error 经 Runtime schema 校验、持久化、审计和 outbox 后才回传 Agent。
|
||||
11. 断线或重启后,pending Tool、Standard Interaction、MiniApp Inbox、实例、焦点和 Surface 以有界方式恢复;中断操作
|
||||
不得伪装为完成。
|
||||
12. 不新增 AppServer Catalog、下载或市场接口;现有服务端只透明转发会话/Inventory 消息。
|
||||
13. 00.base 和 01.kernel 中的登录、同步、本地回显、Markdown、安全 fallback、Tool Call、
|
||||
Task、Surface、Capability、App Inbox、outbox 和焦点恢复测试不退化。
|
||||
14. `npm test -- --run`、`npm run build`、`git diff --check` 通过;浏览器验收无未处理错误。
|
||||
```
|
||||
|
||||
## 10. 完成定义
|
||||
|
||||
本迭代完成不是“已经有应用市场”,也不是“完成全部 MiniApp 业务功能”。完成的判断是:
|
||||
|
||||
```text
|
||||
LineUp Runtime 已提供经过类型、schema、scope、Inventory revision、生命周期、权限、持久化和
|
||||
审计约束的 MiniApp SDK v1;
|
||||
|
||||
Interact、Task Dashboard、Whiteboard 已以不同信任和 UI 形式使用同一套 SDK 语义,证明
|
||||
LineUp 可在不增加旁路通信或 Host 特权泄漏的前提下承载系统级与受限 MiniApp。
|
||||
```
|
||||
Reference in New Issue
Block a user