@qfei-design/make-ai-assistant 0.2.12 → 0.2.14
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.
- package/PUBLIC_API.md +20 -20
- package/README.md +19 -13
- package/capabilities.json +2 -1
- package/dist/client-protocol.d.ts +24 -0
- package/dist/client-types.d.ts +420 -0
- package/dist/client.cjs +2 -0
- package/dist/client.d.ts +18 -0
- package/dist/client.mjs +1154 -0
- package/dist/conversation-BpmWa2VL.cjs +1 -0
- package/dist/conversation-DuqMadaQ.js +888 -0
- package/dist/conversation-management-DZROhXyK.js +229 -0
- package/dist/conversation-management-f1y0yRvt.cjs +1 -0
- package/dist/core/conversation-management.d.ts +15 -5
- package/dist/core/conversation.d.ts +6 -5
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +4 -4
- package/dist/make-app.cjs +1 -1
- package/dist/make-app.d.ts +8 -69
- package/dist/make-app.mjs +236 -703
- package/dist/make-console.cjs +1 -1
- package/dist/make-console.mjs +1 -1
- package/dist/react/conversation-controls.d.ts +1 -1
- package/dist/react/make-ai-assistant.d.ts +1 -2
- package/dist/react/use-attachments.d.ts +3 -1
- package/dist/react/use-conversation-manager.d.ts +3 -2
- package/dist/react.cjs +62 -4
- package/dist/react.mjs +3268 -1794
- package/dist/sse.cjs +1 -1
- package/dist/sse.mjs +1 -1
- package/dist/styles.css +625 -137
- package/docs/backend-contract.md +3 -7
- package/docs/make-app-integration.md +23 -68
- package/examples/make-app/main.tsx +1 -1
- package/examples/make-app/transport.ts +36 -146
- package/package.ai.json +9 -6
- package/package.json +11 -3
- package/recipes.json +4 -3
- package/dist/conversation-CZfbgCXd.js +0 -1111
- package/dist/conversation-Cvh-IVRV.cjs +0 -1
- package/dist/make-app/protocol.d.ts +0 -27
- package/dist/make-app/stream.d.ts +0 -20
package/PUBLIC_API.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
- `@qfei-design/make-ai-assistant`:headless Artifact、会话、模板注册和 transport 合同。
|
|
6
6
|
- `@qfei-design/make-ai-assistant/react`:React 助手壳、ArtifactRenderer 和平台模板。
|
|
7
7
|
- `@qfei-design/make-ai-assistant/sse`:基于 Fetch、ReadableStream 的浏览器/现代 Node SSE transport;公开声明不要求 TypeScript `DOM` lib。
|
|
8
|
-
- `@qfei-design/make-ai-assistant/make-app`:Make App
|
|
8
|
+
- `@qfei-design/make-ai-assistant/make-app`:Make App v1 UI adapter;使用标准 Client,异步读取能力后返回 AssistantTransport。
|
|
9
9
|
- `@qfei-design/make-ai-assistant/make-console`:Make Console Agent/Session/Run 语义协议 adapter;认证请求和 EventSource 创建由 Console 宿主注入。
|
|
10
10
|
- `@qfei-design/make-ai-assistant/testing`:Mock transport 和通用 fixtures,仅用于开发、测试与 Gallery。
|
|
11
11
|
- `@qfei-design/make-ai-assistant/styles.css`:助手壳与默认模板样式。
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
|
|
14
14
|
禁止宿主从 `src`、`dist` 或包内部路径导入。
|
|
15
15
|
|
|
16
|
+
- `@qfei-design/make-ai-assistant/client`:无 React/DOM 类型依赖的 v1 HTTP/字节流客户端与 ApiError。
|
|
17
|
+
|
|
16
18
|
## Headless exports
|
|
17
19
|
|
|
18
20
|
- `validateArtifact` / `parseArtifact`
|
|
@@ -40,18 +42,17 @@ Fetch SSE 实现时,从 `/sse` 入口导入 `createSseAssistantTransport`。
|
|
|
40
42
|
- `MakeAiAssistant`:默认右下角浮动入口与右侧抽屉;支持受控开关、自定义 launcher,以及
|
|
41
43
|
`brandName` 对默认“{品牌名} AI 助手”标题的覆盖。`title` 可覆盖完整标题;`assistantName` /
|
|
42
44
|
`userName` / `userAvatarUrl` 可显示当前登录人的名称和头像;未传入时用户侧不显示身份信息。
|
|
43
|
-
`subtitle`
|
|
44
|
-
|
|
45
|
+
`subtitle` 与 `privacyNotice` 仅继续接受旧调用传入的值以保持类型兼容,不会参与渲染或发送到
|
|
46
|
+
transport;新宿主不应传入。头栏默认高度为 50px,可通过 `headerHeight` 或
|
|
45
47
|
`--make-ai-header-height` 覆盖。内置浮动入口可通过 `launcherPosition` 设置为 `bottom-left`、
|
|
46
48
|
`bottom-right`、`top-left`、`top-right`、`left-center` 或 `right-center`;默认值为 `bottom-right`。
|
|
47
49
|
自定义 `launcher` 自行负责位置。标准位置只读取对应锚点的
|
|
48
50
|
`--make-ai-launcher-left`、`--make-ai-launcher-right`、`--make-ai-launcher-top` 或
|
|
49
51
|
`--make-ai-launcher-bottom` 变量;窄屏使用对应的 `--make-ai-launcher-mobile-*` 变量,另一侧始终为
|
|
50
52
|
`auto`。
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
不提供宽度调整。
|
|
53
|
+
桌面端抽屉默认 560px,宿主可通过 `--make-ai-drawer-width` 覆盖固定宽度;包内最大宽度规则为
|
|
54
|
+
`min(1024px, 72vw)`,但不会压缩固定宽度,可通过 `maxDrawerWidth` 传入像素值设置明确上限。抽屉不提供左侧拖拽或键盘宽度调整;
|
|
55
|
+
标题栏右侧“新建对话”左侧提供全屏/退出全屏按钮,全屏只作用于组件抽屉布局。不大于 560px 的视口保持全宽。
|
|
55
56
|
面板按自身容器宽度适配:达到 560px 时扩展内容区间距和阅读宽度,达到 760px 时 Markdown 表格
|
|
56
57
|
优先按可用宽度分列并换行;宿主可使用 `--make-ai-panel-gutter-wide` 覆盖扩展状态内边距。
|
|
57
58
|
首次打开后关闭抽屉只隐藏 Drawer,不卸载 `AssistantPanel`,不会中断正在进行的生成。
|
|
@@ -59,8 +60,8 @@ Fetch SSE 实现时,从 `/sse` 入口导入 `createSseAssistantTransport`。
|
|
|
59
60
|
省略 `suggestions` 时显示包内默认推荐问题,传入 `[]` 时隐藏推荐问题。
|
|
60
61
|
- `AssistantPanel`:不带 Drawer 的嵌入式会话面板;支持 `brandName`、`title`、`assistantName` /
|
|
61
62
|
`subtitle` / `userName` / `userAvatarUrl` / `privacyNotice` / `headerHeight`。默认品牌为“Make”,
|
|
62
|
-
默认显示“AI
|
|
63
|
-
渲染,不会进入 transport
|
|
63
|
+
默认显示“AI 助手”;用户侧默认不展示名称或头像。`subtitle` 与 `privacyNotice` 不参与渲染;
|
|
64
|
+
其余展示字段只参与本地 React 渲染,不会进入 transport 请求。嵌入式面板包含图标化复制、喜欢/不喜欢、可选安全重新生成、图标化回到最新消息、
|
|
64
65
|
仅在生成中显示的处理步骤、错误重试、键盘提交与 reduced-motion 处理。
|
|
65
66
|
- `ArtifactRenderer`:注册表驱动的单 Artifact 渲染器。
|
|
66
67
|
- `createPlatformArtifactRegistry`
|
|
@@ -84,7 +85,8 @@ Promise rejection。`onActionError` 自身同步抛错或返回 rejected Promise
|
|
|
84
85
|
不会污染宿主的全局未处理异常。
|
|
85
86
|
|
|
86
87
|
成功回答的复制操作以图标按钮展示,悬浮或聚焦时显示“复制”提示,保留“复制回答”的无障碍名称,
|
|
87
|
-
只复制该 assistant message
|
|
88
|
+
只复制该 assistant message 的文本内容;持久 assistant message 的反馈操作同样使用图标按钮,悬浮或聚焦时显示
|
|
89
|
+
“喜欢”或“不喜欢”提示,并保留可读的无障碍名称。复制失败只在本地 UI 反馈并记录不含回答正文的错误类型。AI 回答正文会按标题、
|
|
88
90
|
段落、列表、强调、反引号代码片段和 Markdown 表格行做轻量结构化展示;该渲染不执行 HTML、JSX、
|
|
89
91
|
CSS 或 JavaScript。对话排版默认分为四级:标题和用户问题为 14px、AI 正文与结构化结果数据为
|
|
90
92
|
13px、身份/状态/操作等辅助信息为 12px、来源/时间/复制反馈等非关键注释为 11px。宿主可通过
|
|
@@ -173,19 +175,13 @@ UI 会拒绝孤立、迟到、重复或跨 run 混入的事件,避免静默丢
|
|
|
173
175
|
|
|
174
176
|
## Make App transport
|
|
175
177
|
|
|
176
|
-
`/
|
|
177
|
-
|
|
178
|
-
宿主注入 resolveScope、会话/SSE/上传语义回调及可选的 readContent:listAgents、createChat、listChats、getChat、updateChat、deleteChat、loadHistory、sendMessage、getResponse、cancelResponse、setFeedback、startUpload、getUpload、uploadPart、completeUpload、eventSourceFactory。JSON 回调返回裸对象,204 返回 void;宿主能够无损读取二进制时再提供 readContent,并返回 Uint8Array。
|
|
179
|
-
|
|
180
|
-
`resolveScope(context)` 返回 appKey、agentId 和随登录身份变化的 identityKey。包只用于作用域绑定与缓存失效,服务器仍独立鉴权。每个异步回调接受 AbortSignal;包不提供部署 URL、不读 Cookie、不导入认证 SDK。
|
|
178
|
+
`/client` 导出 createMakeAgentClient、ApiError、Client 与 AuthenticatedTransport 等平台中立类型。固定 apiVersion=v1,basePath 默认 /api/make/app/ai。详细方法、错误、预算和幂等责任见 [稳定客户端合同](docs/make-app-integration.md)。
|
|
181
179
|
|
|
182
|
-
`
|
|
180
|
+
`/make-app` 导出异步 createMakeAppAssistantTransport({ client, agentId, historyLimit?, signal? }),通过能力发现后返回 AssistantTransport。宿主只注入一个正式认证 HTTP 传输、App/身份和 Agent;身份变化时调用 client.dispose() 并重建实例。
|
|
183
181
|
|
|
184
|
-
|
|
182
|
+
标准 SDK 将新增响应元数据安全投影;未知事件保留名称/游标,未知内容块保留 originalKind/textFallback,不执行未知动作。输入仍严格验证。v1 的 cursor 为不透明字符串,ResponseSnapshot 必含 terminal 和 snapshotRevision。框架中立的 AssistantTransport 仍允许 Console/测试适配器的本地序号,但 Make App v1 不接受数字 cursor。
|
|
185
183
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
根入口导出 AssistantContentPart、AssistantMedia、AssistantChat、AssistantChatPage、AssistantAgent、AssistantFeedback、AssistantUpload、AssistantResponseSnapshot、AssistantResponseEvent 等类型,仍无 React/DOM File 依赖。文件读取与 Object URL 留在 React/宿主边界。
|
|
184
|
+
Chat.titlePending 缺失按 false;摘要完成通过同一 Client 的详情刷新立即反映到会话列表。SSE 只更新响应视图,反馈使用历史中真正的 messageId,关闭订阅不会远程取消运行。
|
|
189
185
|
|
|
190
186
|
## Make Console transport
|
|
191
187
|
|
|
@@ -233,3 +229,7 @@ Artifact 的 `action.target` 只是 JSON 意图。宿主必须根据当前权限
|
|
|
233
229
|
- 未注册模板安全降级;
|
|
234
230
|
- `presentation.template` 不会触发代码加载;
|
|
235
231
|
- 新模板不得复用已有 id。
|
|
232
|
+
|
|
233
|
+
## 自动标题更新
|
|
234
|
+
|
|
235
|
+
AssistantChat 必须包含 titlePending: boolean。首条长消息摘要排队或生成时为 true,完成、失败或手工命名后为 false。消息受理后读取一次会话详情;列表或当前会话存在待摘要状态时,每秒通过已认证 getConversation 回调刷新对应详情,按 revision 合并。正文终态不停止标题检查;摘要完成即停止,作用域切换、删除或卸载会取消请求。迟到的较低 revision 详情或列表不会覆盖新标题。
|
package/README.md
CHANGED
|
@@ -5,9 +5,11 @@
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
pnpm add @qfei-design/make-ai-assistant
|
|
8
|
+
pnpm add --save-exact @qfei-design/make-ai-assistant@VERSION
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
VERSION 替换为完成本地验收的发布版本,提交 lockfile 固定制品。
|
|
12
|
+
|
|
11
13
|
## Quick start
|
|
12
14
|
|
|
13
15
|
```tsx
|
|
@@ -93,12 +95,12 @@ const hostTheme: MakeAiTheme = {
|
|
|
93
95
|
宿主 `--make-color-primary` > 包内默认值。`background` 会控制内容区基础背景;`surface`、`text` 等其余中性色字段为兼容保留,
|
|
94
96
|
不会改变内置默认样式;它们仍会写入 `renderContext.themeStyle`,供自定义 Artifact 模板自行使用。
|
|
95
97
|
|
|
96
|
-
桌面端抽屉默认宽度为
|
|
98
|
+
桌面端抽屉默认宽度为 560px,宿主仍可通过 `--make-ai-drawer-width` 覆盖固定宽度。包内最大宽度规则为 `min(1024px, 72vw)`,但不会压缩默认或宿主指定的固定宽度;宿主可通过 `maxDrawerWidth` 传入像素值设置明确上限。抽屉不再提供左侧拖拽或键盘调整宽度;标题栏右侧“新建对话”左侧提供全屏/退出全屏按钮,全屏只作用于本组件的抽屉布局,不调用浏览器原生全屏。不大于 560px 的视口保持全宽展示。
|
|
97
99
|
|
|
98
100
|
面板使用容器查询而非页面视口响应宽度:回答区、结构化结果、代码块和 Markdown 表格会随抽屉可用宽度扩展;达到 760px 时,表格优先按可用宽度分列并换行,长段落和列表仍限制在 96ch 内以保障阅读性。窄容器中的 Markdown 表格保留横向滚动保护,并使用细窄的中性灰滚动条。宿主可通过 `--make-ai-panel-gutter-wide` 覆盖扩展抽屉的内边距。
|
|
99
101
|
|
|
100
102
|
成功的 AI 回答会显示仅含图标的复制按钮,鼠标悬浮或键盘聚焦时显示“复制”提示,按钮保留
|
|
101
|
-
|
|
103
|
+
“复制回答”的无障碍名称;持久回答的喜欢/不喜欢也使用同样的图标交互,并分别显示“喜欢”与“不喜欢”提示。复制只处理该回答的文本内容,失败时会在本地 UI 内提示,不会把回答正文写入日志。AI 回答正文会按标题、
|
|
102
104
|
段落、列表、强调、代码片段和 Markdown 表格行做轻量结构化展示,不执行 HTML,也不引入 Markdown
|
|
103
105
|
运行时依赖。对话排版默认分为四级:标题和用户问题为 14px、AI 正文与结构化结果数据为 13px、身份/状态/操作等辅助信息为
|
|
104
106
|
12px、来源/时间/复制反馈等非关键注释为 11px。宿主可通过
|
|
@@ -192,23 +194,23 @@ const assistantTransport = createSseAssistantTransport({
|
|
|
192
194
|
});
|
|
193
195
|
```
|
|
194
196
|
|
|
195
|
-
|
|
197
|
+
客户端入口为 `@qfei-design/make-ai-assistant/client`。App 宿主提供正式认证 HTTP 传输,标准客户端统一管理 18 项接口、固定 `/v1` 路径、响应解码、分页、重试、字节上传与 SSE。`/make-app` 把客户端结果映射到已有助手 UI 状态机。
|
|
196
198
|
|
|
197
199
|
```ts
|
|
200
|
+
import { createMakeAgentClient } from "@qfei-design/make-ai-assistant/client";
|
|
198
201
|
import { createMakeAppAssistantTransport } from "@qfei-design/make-ai-assistant/make-app";
|
|
199
202
|
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
203
|
+
const client = createMakeAgentClient({
|
|
204
|
+
apiVersion: "v1",
|
|
205
|
+
scope: { appKey, identityKey },
|
|
206
|
+
transport: authenticatedTransport,
|
|
204
207
|
});
|
|
208
|
+
const assistantTransport = await createMakeAppAssistantTransport({ client, agentId });
|
|
209
|
+
// 将 assistantTransport 传入 AssistantPanel / MakeAiAssistant。
|
|
210
|
+
// App、用户或租户改变时,取消旧连接并 client.dispose(),重新创建实例。
|
|
205
211
|
```
|
|
206
212
|
|
|
207
|
-
`
|
|
208
|
-
|
|
209
|
-
内置面板支持持久会话列表、新建、改名、置顶/删除、反馈与附件队列。历史 cursor=-1 从最早事件正向分页,空可见页仍可能存在后续事件。首次加载不隐式建会话,用户新建或主动发送才创建。item/part 增量、完整文本覆盖、快照恢复和持久 messageId 对账由包统一处理。
|
|
210
|
-
|
|
211
|
-
停止显示“停止中”,直到服务端确认终态;中断订阅不取消后台 Run。当前 Make App 不提供重新生成语义,也不传 context/capabilities 或伪造 Artifact。附件入口固定为“上传文件或图片”;modelInputKinds 仅描述宿主模型能力,服务端根据消息 parts 决定是否接受媒体类型。单条消息文本最多 8 KiB UTF-8,最多 32 个 parts。
|
|
213
|
+
`AuthenticatedTransport.request` 只执行一次已认证 I/O,返回 status、headers 和 AsyncIterable<Uint8Array>。`retryOwner: "sdk"` 由 SDK 按幂等语义做有限重试;`retryOwner: "transport"` 不叠加 SDK 重试。宿主沿正式 auth.api 处理登录、401/403 和 Cookie,SSE/二进制成功体不经过 JSON 或 text() 缓冲。SDK 不读取 Token、Cookie、LocalStorage 或 Provider key。
|
|
212
214
|
|
|
213
215
|
Make Console 可以使用独立 adapter:
|
|
214
216
|
|
|
@@ -259,3 +261,7 @@ pnpm build
|
|
|
259
261
|
```
|
|
260
262
|
|
|
261
263
|
发布统一走 GitLab CI;不要从功能分支本地执行 npm publish。
|
|
264
|
+
|
|
265
|
+
### 会话自动标题
|
|
266
|
+
|
|
267
|
+
Make App 的 Chat 包含 titlePending。首条长消息的摘要完成后,助手通过每秒一次的待摘要会话详情刷新自动更新列表,独立于正文流式完成时间;短标题和手工命名结束等待,旧 revision 不覆盖当前状态。详情刷新经过标准 client.chats.get 和正式认证传输,不增加登录或直连模型逻辑。
|
package/capabilities.json
CHANGED
|
@@ -70,9 +70,10 @@
|
|
|
70
70
|
"name": "Make App AI transport",
|
|
71
71
|
"category": "integration",
|
|
72
72
|
"status": "experimental",
|
|
73
|
-
"summary": "
|
|
73
|
+
"summary": "标准 v1 Client 支撑多会话、反馈、附件、SSE、单调快照与显式取消;宿主注入正式认证 HTTP 传输。",
|
|
74
74
|
"docPath": "PUBLIC_API.md",
|
|
75
75
|
"relatedExports": [
|
|
76
|
+
"@qfei-design/make-ai-assistant/client:createMakeAgentClient",
|
|
76
77
|
"@qfei-design/make-ai-assistant/make-app:createMakeAppAssistantTransport",
|
|
77
78
|
"AssistantTransport"
|
|
78
79
|
]
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AgentPage, Capabilities, Chat, ChatPage, Feedback, HistoryPage, Media, OutputPart, ResponseSnapshot, Upload } from "./client-types.js";
|
|
2
|
+
export declare const record: (value: unknown) => Record<string, unknown>;
|
|
3
|
+
export declare const id: (value: unknown) => string;
|
|
4
|
+
export declare const text: (value: unknown, maximum?: number, empty?: boolean) => string;
|
|
5
|
+
export declare const number: (value: unknown, minimum?: number, maximum?: number) => number;
|
|
6
|
+
export declare const boolean: (value: unknown) => boolean;
|
|
7
|
+
export declare const array: (value: unknown, maximum: number) => unknown[];
|
|
8
|
+
export declare function requestKeys(value: object, keys: readonly string[]): void;
|
|
9
|
+
export declare function uuid(value: unknown): string;
|
|
10
|
+
export declare function cursor(value: unknown, empty?: boolean): string;
|
|
11
|
+
export declare function pageFields(value: Record<string, unknown>): {
|
|
12
|
+
nextCursor: string;
|
|
13
|
+
hasMore: boolean;
|
|
14
|
+
};
|
|
15
|
+
export declare function readChat(raw: unknown, appKey: string, agentId?: string, chatId?: string): Chat;
|
|
16
|
+
export declare function readChatPage(raw: unknown, appKey: string, agentId: string): ChatPage;
|
|
17
|
+
export declare function readAgents(raw: unknown, appKey: string): AgentPage;
|
|
18
|
+
export declare function readMedia(raw: unknown): Media;
|
|
19
|
+
export declare function readParts(raw: unknown): OutputPart[];
|
|
20
|
+
export declare function readFeedback(raw: unknown): Feedback;
|
|
21
|
+
export declare function readHistory(raw: unknown): HistoryPage;
|
|
22
|
+
export declare function readSnapshot(raw: unknown, chatId: string, responseId: string): ResponseSnapshot;
|
|
23
|
+
export declare function readUpload(raw: unknown, expectedId?: string): Upload;
|
|
24
|
+
export declare function readCapabilities(raw: unknown, appKey: string, agentId: string): Capabilities;
|
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
/** v1 公共客户端类型;网络通过宿主认证传输,React 与业务动作留在上层。 */
|
|
2
|
+
export type ApiVersion = "v1";
|
|
3
|
+
export type Id = string;
|
|
4
|
+
export type Cursor = string;
|
|
5
|
+
export type OpenString<Known extends string> = Known | (string & {});
|
|
6
|
+
export interface AbortSignalLike {
|
|
7
|
+
readonly aborted: boolean;
|
|
8
|
+
readonly reason?: unknown;
|
|
9
|
+
addEventListener(type: "abort", listener: () => void, options?: {
|
|
10
|
+
once?: boolean;
|
|
11
|
+
}): void;
|
|
12
|
+
removeEventListener(type: "abort", listener: () => void): void;
|
|
13
|
+
}
|
|
14
|
+
export interface RetryOptions {
|
|
15
|
+
readonly maxAttempts?: number;
|
|
16
|
+
readonly maxDelayMs?: number;
|
|
17
|
+
}
|
|
18
|
+
export interface StreamOptions {
|
|
19
|
+
readonly connectTimeoutMs?: number;
|
|
20
|
+
readonly idleTimeoutMs?: number;
|
|
21
|
+
readonly maxDurationMs?: number;
|
|
22
|
+
}
|
|
23
|
+
export interface CallOptions {
|
|
24
|
+
readonly signal?: AbortSignalLike;
|
|
25
|
+
readonly timeoutMs?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface Scope {
|
|
28
|
+
readonly appKey: Id;
|
|
29
|
+
readonly identityKey: string;
|
|
30
|
+
}
|
|
31
|
+
export interface HttpRequest {
|
|
32
|
+
readonly method: "GET" | "POST" | "PATCH" | "DELETE" | "PUT";
|
|
33
|
+
readonly path: string;
|
|
34
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
35
|
+
readonly body?: Uint8Array;
|
|
36
|
+
}
|
|
37
|
+
export interface HttpResponse {
|
|
38
|
+
readonly status: number;
|
|
39
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
40
|
+
readonly body?: AsyncIterable<Uint8Array>;
|
|
41
|
+
}
|
|
42
|
+
/** 由宿主正式认证适配器实现;不允许在浏览器 SDK 内读取 Token/Cookie。 */
|
|
43
|
+
export interface AuthenticatedTransport {
|
|
44
|
+
readonly retryOwner: "sdk" | "transport";
|
|
45
|
+
request(request: HttpRequest, options?: CallOptions): Promise<HttpResponse>;
|
|
46
|
+
}
|
|
47
|
+
export interface ClientOptions {
|
|
48
|
+
readonly apiVersion?: ApiVersion;
|
|
49
|
+
readonly basePath?: string;
|
|
50
|
+
readonly scope: Scope;
|
|
51
|
+
readonly transport: AuthenticatedTransport;
|
|
52
|
+
readonly retry?: RetryOptions;
|
|
53
|
+
readonly stream?: StreamOptions;
|
|
54
|
+
readonly timeoutMs?: number;
|
|
55
|
+
readonly maxJsonBytes?: number;
|
|
56
|
+
readonly maxEventBytes?: number;
|
|
57
|
+
readonly onDiagnostic?: (event: {
|
|
58
|
+
operation: string;
|
|
59
|
+
code?: string;
|
|
60
|
+
requestId?: string;
|
|
61
|
+
attempts?: number;
|
|
62
|
+
}) => void;
|
|
63
|
+
}
|
|
64
|
+
export interface PageOptions {
|
|
65
|
+
readonly cursor?: Cursor;
|
|
66
|
+
readonly limit?: number;
|
|
67
|
+
}
|
|
68
|
+
export interface IterateOptions extends CallOptions {
|
|
69
|
+
readonly maxPages: number;
|
|
70
|
+
readonly maxItems: number;
|
|
71
|
+
}
|
|
72
|
+
export interface Agent {
|
|
73
|
+
readonly agentId: Id;
|
|
74
|
+
readonly appKey: Id;
|
|
75
|
+
readonly name: string;
|
|
76
|
+
}
|
|
77
|
+
export interface AgentPage {
|
|
78
|
+
readonly agents: readonly Agent[];
|
|
79
|
+
readonly nextCursor: Cursor;
|
|
80
|
+
readonly hasMore: boolean;
|
|
81
|
+
}
|
|
82
|
+
export interface Chat {
|
|
83
|
+
readonly chatId: Id;
|
|
84
|
+
readonly appKey: Id;
|
|
85
|
+
readonly agentId: Id;
|
|
86
|
+
readonly title: string;
|
|
87
|
+
readonly status: "active" | "deleted";
|
|
88
|
+
readonly revision: number;
|
|
89
|
+
readonly pinned: boolean;
|
|
90
|
+
readonly pinnedAt?: string | null;
|
|
91
|
+
readonly createdAt: string;
|
|
92
|
+
readonly lastActivityAt: string;
|
|
93
|
+
readonly titlePending?: boolean;
|
|
94
|
+
}
|
|
95
|
+
export interface ChatPage {
|
|
96
|
+
readonly chats: readonly Chat[];
|
|
97
|
+
readonly nextCursor: Cursor;
|
|
98
|
+
readonly hasMore: boolean;
|
|
99
|
+
}
|
|
100
|
+
export interface CreateChatInput {
|
|
101
|
+
readonly agentId: Id;
|
|
102
|
+
readonly requestId: string;
|
|
103
|
+
readonly title?: string;
|
|
104
|
+
}
|
|
105
|
+
export type UpdateChatInput = {
|
|
106
|
+
readonly chatId: Id;
|
|
107
|
+
readonly expectedRevision: number;
|
|
108
|
+
} & ({
|
|
109
|
+
readonly title: string;
|
|
110
|
+
readonly pinned?: boolean;
|
|
111
|
+
} | {
|
|
112
|
+
readonly pinned: boolean;
|
|
113
|
+
readonly title?: string;
|
|
114
|
+
});
|
|
115
|
+
export interface Media {
|
|
116
|
+
readonly contentRef: Id;
|
|
117
|
+
readonly contentType: string;
|
|
118
|
+
readonly sizeBytes: number;
|
|
119
|
+
readonly digestSha256: string;
|
|
120
|
+
}
|
|
121
|
+
export type KnownMediaKind = "image" | "file" | "audio" | "video";
|
|
122
|
+
export type InputPart = {
|
|
123
|
+
readonly id: string;
|
|
124
|
+
readonly kind: "text";
|
|
125
|
+
readonly text: string;
|
|
126
|
+
} | {
|
|
127
|
+
readonly id: string;
|
|
128
|
+
readonly kind: KnownMediaKind;
|
|
129
|
+
readonly name?: string;
|
|
130
|
+
readonly media: Media;
|
|
131
|
+
};
|
|
132
|
+
export type OutputPart = {
|
|
133
|
+
readonly id?: Id;
|
|
134
|
+
readonly kind: "text";
|
|
135
|
+
readonly text: string;
|
|
136
|
+
} | {
|
|
137
|
+
readonly id?: Id;
|
|
138
|
+
readonly kind: KnownMediaKind;
|
|
139
|
+
readonly name?: string;
|
|
140
|
+
readonly media: Media;
|
|
141
|
+
} | {
|
|
142
|
+
readonly id?: Id;
|
|
143
|
+
readonly kind: "unknown";
|
|
144
|
+
readonly originalKind: string;
|
|
145
|
+
readonly textFallback?: string;
|
|
146
|
+
};
|
|
147
|
+
export type SendMessageInput = {
|
|
148
|
+
readonly chatId: Id;
|
|
149
|
+
readonly messageId: string;
|
|
150
|
+
} & ({
|
|
151
|
+
readonly text: string;
|
|
152
|
+
readonly parts?: never;
|
|
153
|
+
} | {
|
|
154
|
+
readonly parts: readonly InputPart[];
|
|
155
|
+
readonly text?: never;
|
|
156
|
+
});
|
|
157
|
+
export interface Accepted {
|
|
158
|
+
readonly chatId: Id;
|
|
159
|
+
readonly messageId: Id;
|
|
160
|
+
readonly responseId: Id;
|
|
161
|
+
readonly acceptedCursor?: Cursor;
|
|
162
|
+
}
|
|
163
|
+
export interface Feedback {
|
|
164
|
+
readonly id: Id;
|
|
165
|
+
readonly rating: "like" | "dislike" | "none";
|
|
166
|
+
readonly revision: number;
|
|
167
|
+
readonly reason?: string;
|
|
168
|
+
readonly comment?: string;
|
|
169
|
+
}
|
|
170
|
+
export interface FeedbackInput {
|
|
171
|
+
readonly chatId: Id;
|
|
172
|
+
readonly messageId: Id;
|
|
173
|
+
readonly requestId: string;
|
|
174
|
+
readonly rating: "like" | "dislike" | "none";
|
|
175
|
+
readonly reason?: string;
|
|
176
|
+
readonly comment?: string;
|
|
177
|
+
}
|
|
178
|
+
export interface StoredMessage {
|
|
179
|
+
readonly messageId: Id;
|
|
180
|
+
readonly role: "user" | "assistant";
|
|
181
|
+
readonly cursor: Cursor;
|
|
182
|
+
readonly createdAt: string;
|
|
183
|
+
readonly text: string;
|
|
184
|
+
readonly parts?: readonly OutputPart[];
|
|
185
|
+
readonly responseId?: Id;
|
|
186
|
+
readonly feedback?: Feedback;
|
|
187
|
+
}
|
|
188
|
+
export interface HistoryPage {
|
|
189
|
+
readonly messages: readonly StoredMessage[];
|
|
190
|
+
readonly nextCursor: Cursor;
|
|
191
|
+
readonly hasMore: boolean;
|
|
192
|
+
}
|
|
193
|
+
export interface OutputItem {
|
|
194
|
+
readonly itemId: Id;
|
|
195
|
+
readonly partId: Id;
|
|
196
|
+
readonly text: string;
|
|
197
|
+
readonly final: boolean;
|
|
198
|
+
readonly revision: number;
|
|
199
|
+
readonly parts?: readonly OutputPart[];
|
|
200
|
+
}
|
|
201
|
+
export type ResponseStatus = OpenString<"queued" | "dispatched" | "running" | "completed" | "failed" | "cancelled">;
|
|
202
|
+
export interface PublicError {
|
|
203
|
+
readonly code: string;
|
|
204
|
+
readonly message: string;
|
|
205
|
+
readonly requestId?: string;
|
|
206
|
+
readonly details?: readonly {
|
|
207
|
+
readonly code?: string;
|
|
208
|
+
readonly target?: string;
|
|
209
|
+
readonly message?: string;
|
|
210
|
+
}[];
|
|
211
|
+
}
|
|
212
|
+
export interface ResponseRef {
|
|
213
|
+
readonly chatId: Id;
|
|
214
|
+
readonly responseId: Id;
|
|
215
|
+
}
|
|
216
|
+
export interface ResponseSnapshot extends ResponseRef {
|
|
217
|
+
readonly status: ResponseStatus;
|
|
218
|
+
readonly terminal: boolean;
|
|
219
|
+
readonly snapshotRevision: number;
|
|
220
|
+
readonly items: readonly OutputItem[];
|
|
221
|
+
readonly cancelRequested?: boolean;
|
|
222
|
+
readonly error?: PublicError;
|
|
223
|
+
}
|
|
224
|
+
export type ResponseEvent = {
|
|
225
|
+
readonly kind: "subscribed";
|
|
226
|
+
readonly responseId: Id;
|
|
227
|
+
readonly cursor?: Cursor;
|
|
228
|
+
} | {
|
|
229
|
+
readonly kind: "state";
|
|
230
|
+
readonly responseId: Id;
|
|
231
|
+
readonly status: ResponseStatus;
|
|
232
|
+
readonly cursor?: Cursor;
|
|
233
|
+
} | {
|
|
234
|
+
readonly kind: "itemAdded";
|
|
235
|
+
readonly responseId: Id;
|
|
236
|
+
readonly itemId: Id;
|
|
237
|
+
readonly partId: Id;
|
|
238
|
+
readonly sequence: number;
|
|
239
|
+
readonly cursor?: Cursor;
|
|
240
|
+
} | {
|
|
241
|
+
readonly kind: "textDelta";
|
|
242
|
+
readonly responseId: Id;
|
|
243
|
+
readonly itemId: Id;
|
|
244
|
+
readonly partId: Id;
|
|
245
|
+
readonly sequence: number;
|
|
246
|
+
readonly delta: string;
|
|
247
|
+
readonly cursor?: Cursor;
|
|
248
|
+
} | {
|
|
249
|
+
readonly kind: "itemDone";
|
|
250
|
+
readonly responseId: Id;
|
|
251
|
+
readonly itemId: Id;
|
|
252
|
+
readonly partId: Id;
|
|
253
|
+
readonly sequence: number;
|
|
254
|
+
readonly text: string;
|
|
255
|
+
readonly final: boolean;
|
|
256
|
+
readonly cursor?: Cursor;
|
|
257
|
+
} | {
|
|
258
|
+
readonly kind: "reset";
|
|
259
|
+
readonly responseId: Id;
|
|
260
|
+
readonly reason: string;
|
|
261
|
+
readonly cursor?: Cursor;
|
|
262
|
+
} | {
|
|
263
|
+
readonly kind: "snapshot";
|
|
264
|
+
readonly snapshot: ResponseSnapshot;
|
|
265
|
+
readonly cursor?: Cursor;
|
|
266
|
+
} | {
|
|
267
|
+
readonly kind: "completed" | "failed" | "cancelled";
|
|
268
|
+
readonly responseId: Id;
|
|
269
|
+
readonly code?: string;
|
|
270
|
+
readonly cursor?: Cursor;
|
|
271
|
+
} | {
|
|
272
|
+
readonly kind: "unknown";
|
|
273
|
+
readonly responseId: Id;
|
|
274
|
+
readonly name: string;
|
|
275
|
+
readonly cursor?: Cursor;
|
|
276
|
+
};
|
|
277
|
+
export interface StartUploadInput {
|
|
278
|
+
readonly chatId: Id;
|
|
279
|
+
readonly fileId: string;
|
|
280
|
+
readonly name: string;
|
|
281
|
+
readonly contentType: string;
|
|
282
|
+
readonly sizeBytes: number;
|
|
283
|
+
readonly digestSha256?: string;
|
|
284
|
+
}
|
|
285
|
+
export interface ContentReference {
|
|
286
|
+
readonly kind: "reference";
|
|
287
|
+
readonly contentRef: Id;
|
|
288
|
+
readonly sizeBytes: number;
|
|
289
|
+
readonly digestSha256: string;
|
|
290
|
+
}
|
|
291
|
+
export interface Upload {
|
|
292
|
+
readonly id: Id;
|
|
293
|
+
readonly status: OpenString<"uploading" | "ready" | "expired" | "cancelled">;
|
|
294
|
+
readonly name: string;
|
|
295
|
+
readonly contentType: string;
|
|
296
|
+
readonly sizeBytes: number;
|
|
297
|
+
readonly partSize: number;
|
|
298
|
+
readonly completedParts: readonly number[];
|
|
299
|
+
readonly expiresAt?: string;
|
|
300
|
+
readonly content?: ContentReference;
|
|
301
|
+
}
|
|
302
|
+
export interface ReplayableBytes {
|
|
303
|
+
readonly sizeBytes: number;
|
|
304
|
+
read(offset: number, length: number, options?: CallOptions): Promise<Uint8Array>;
|
|
305
|
+
}
|
|
306
|
+
export interface ContentDownload {
|
|
307
|
+
readonly contentType?: string;
|
|
308
|
+
readonly contentLength?: number;
|
|
309
|
+
readonly body: AsyncIterable<Uint8Array>;
|
|
310
|
+
}
|
|
311
|
+
export interface Limits {
|
|
312
|
+
readonly maxInputTextBytes: number;
|
|
313
|
+
readonly maxMessageBytes: number;
|
|
314
|
+
readonly maxInputParts: number;
|
|
315
|
+
readonly maxUploadBytes: number;
|
|
316
|
+
readonly uploadPartBytes: number;
|
|
317
|
+
readonly maxConcurrentUploads: number;
|
|
318
|
+
readonly maxSseEventBytes: number;
|
|
319
|
+
}
|
|
320
|
+
export interface Capabilities {
|
|
321
|
+
readonly apiVersion: ApiVersion;
|
|
322
|
+
readonly appKey: Id;
|
|
323
|
+
readonly agentId: Id;
|
|
324
|
+
readonly features: readonly string[];
|
|
325
|
+
readonly modelInputKinds: readonly string[];
|
|
326
|
+
readonly limits: Limits;
|
|
327
|
+
readonly revision?: string;
|
|
328
|
+
}
|
|
329
|
+
export interface Client {
|
|
330
|
+
readonly scope: Scope;
|
|
331
|
+
readonly apiVersion: ApiVersion;
|
|
332
|
+
readonly capabilities: {
|
|
333
|
+
get(input: {
|
|
334
|
+
agentId: Id;
|
|
335
|
+
}, options?: CallOptions): Promise<Capabilities>;
|
|
336
|
+
};
|
|
337
|
+
readonly agents: {
|
|
338
|
+
list(page?: PageOptions, options?: CallOptions): Promise<AgentPage>;
|
|
339
|
+
};
|
|
340
|
+
readonly chats: {
|
|
341
|
+
create(input: CreateChatInput, options?: CallOptions): Promise<Chat>;
|
|
342
|
+
list(input: {
|
|
343
|
+
agentId: Id;
|
|
344
|
+
} & PageOptions, options?: CallOptions): Promise<ChatPage>;
|
|
345
|
+
get(input: {
|
|
346
|
+
chatId: Id;
|
|
347
|
+
}, options?: CallOptions): Promise<Chat>;
|
|
348
|
+
update(input: UpdateChatInput, options?: CallOptions): Promise<Chat>;
|
|
349
|
+
delete(input: {
|
|
350
|
+
chatId: Id;
|
|
351
|
+
expectedRevision: number;
|
|
352
|
+
}, options?: CallOptions): Promise<void>;
|
|
353
|
+
iterate(input: {
|
|
354
|
+
agentId: Id;
|
|
355
|
+
} & PageOptions, options: IterateOptions): AsyncIterable<Chat>;
|
|
356
|
+
};
|
|
357
|
+
readonly messages: {
|
|
358
|
+
send(input: SendMessageInput, options?: CallOptions): Promise<Accepted>;
|
|
359
|
+
list(input: {
|
|
360
|
+
chatId: Id;
|
|
361
|
+
} & PageOptions, options?: CallOptions): Promise<HistoryPage>;
|
|
362
|
+
iterate(input: {
|
|
363
|
+
chatId: Id;
|
|
364
|
+
} & PageOptions, options: IterateOptions): AsyncIterable<StoredMessage>;
|
|
365
|
+
sendAndWatch(input: SendMessageInput, options?: CallOptions): Promise<{
|
|
366
|
+
readonly accepted: Accepted;
|
|
367
|
+
readonly events: AsyncIterable<ResponseEvent>;
|
|
368
|
+
}>;
|
|
369
|
+
};
|
|
370
|
+
readonly responses: {
|
|
371
|
+
get(input: ResponseRef, options?: CallOptions): Promise<ResponseSnapshot>;
|
|
372
|
+
subscribe(input: ResponseRef & {
|
|
373
|
+
cursor?: Cursor;
|
|
374
|
+
}, options?: CallOptions): AsyncIterable<ResponseEvent>;
|
|
375
|
+
cancel(input: ResponseRef, options?: CallOptions): Promise<ResponseSnapshot>;
|
|
376
|
+
waitForTerminal(input: ResponseRef, options: CallOptions & {
|
|
377
|
+
timeoutMs: number;
|
|
378
|
+
pollIntervalMs?: number;
|
|
379
|
+
}): Promise<ResponseSnapshot>;
|
|
380
|
+
};
|
|
381
|
+
readonly feedback: {
|
|
382
|
+
set(input: FeedbackInput, options?: CallOptions): Promise<Feedback>;
|
|
383
|
+
};
|
|
384
|
+
readonly uploads: {
|
|
385
|
+
start(input: StartUploadInput, options?: CallOptions): Promise<Upload>;
|
|
386
|
+
get(input: {
|
|
387
|
+
chatId: Id;
|
|
388
|
+
uploadId: Id;
|
|
389
|
+
}, options?: CallOptions): Promise<Upload>;
|
|
390
|
+
putPart(input: {
|
|
391
|
+
chatId: Id;
|
|
392
|
+
uploadId: Id;
|
|
393
|
+
part: number;
|
|
394
|
+
bytes: Uint8Array;
|
|
395
|
+
}, options?: CallOptions): Promise<void>;
|
|
396
|
+
complete(input: {
|
|
397
|
+
chatId: Id;
|
|
398
|
+
uploadId: Id;
|
|
399
|
+
}, options?: CallOptions): Promise<Upload>;
|
|
400
|
+
uploadFile(input: Omit<StartUploadInput, "sizeBytes"> & {
|
|
401
|
+
source: ReplayableBytes;
|
|
402
|
+
}, options?: CallOptions & {
|
|
403
|
+
concurrency?: number;
|
|
404
|
+
onProgress?: (confirmedBytes: number) => void;
|
|
405
|
+
}): Promise<Upload>;
|
|
406
|
+
};
|
|
407
|
+
readonly content: {
|
|
408
|
+
read(input: {
|
|
409
|
+
chatId: Id;
|
|
410
|
+
contentRef: Id;
|
|
411
|
+
maxBytes: number;
|
|
412
|
+
}, options?: CallOptions): Promise<ContentDownload>;
|
|
413
|
+
};
|
|
414
|
+
/** 释放本地资源,不退出登录、不远程取消 Response。 */
|
|
415
|
+
dispose(): void;
|
|
416
|
+
}
|
|
417
|
+
/** 消费者可实现的小接口;扩展全量 Client 不应扩大这些接口的必需方法集。 */
|
|
418
|
+
export type ChatReader = Pick<Client["chats"], "list" | "get">;
|
|
419
|
+
export type MessageSender = Pick<Client["messages"], "send">;
|
|
420
|
+
export type ResponseReader = Pick<Client["responses"], "get" | "subscribe">;
|