super-agent-sdk 1.0.7 → 1.0.8
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/README.md +79 -18
- package/dist/index.cjs +3 -3
- package/dist/index.d.ts +7 -2
- package/dist/index.mjs +90 -85
- package/dist/widget.cjs +51 -8
- package/dist/widget.d.ts +11 -4
- package/dist/widget.mjs +1256 -1065
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -131,6 +131,7 @@ ready
|
|
|
131
131
|
|
|
132
132
|
```ts
|
|
133
133
|
export interface SuperAgentSDK {
|
|
134
|
+
readonly botId: number; // 当前 Bot ID
|
|
134
135
|
createSession(): Promise<string>;
|
|
135
136
|
chat(options: ChatOptions): AbortController;
|
|
136
137
|
listConversations(
|
|
@@ -143,7 +144,7 @@ export interface SuperAgentSDK {
|
|
|
143
144
|
setToken(token: string): void;
|
|
144
145
|
feedback(messageId: string, type: "like" | "dislike", options?: { reason?: number; remark?: string }): Promise<void>;
|
|
145
146
|
cancelFeedback(messageId: string): Promise<void>;
|
|
146
|
-
respondInterrupt(interruptId: string, sessionId: string, response: InterruptResponse): Promise<void>;
|
|
147
|
+
respondInterrupt(interruptId: string, sessionId: string, response: InterruptResponse, onMessage?: (event: ChatEvent) => void, onError?: (error: Error) => void): Promise<void>;
|
|
147
148
|
listSkills(): Promise<SkillInfo[]>;
|
|
148
149
|
stopGeneration(sessionId: string): Promise<void>;
|
|
149
150
|
}
|
|
@@ -175,7 +176,7 @@ export interface ChatOptions {
|
|
|
175
176
|
stream?: boolean; // 默认 true
|
|
176
177
|
onMessage?: (event: ChatEvent) => void;
|
|
177
178
|
onError?: (error: Error) => void;
|
|
178
|
-
onDone?: (result: { sessionId: string; content: string }) => void;
|
|
179
|
+
onDone?: (result: { sessionId: string; content: string; messageId?: string }) => void; // messageId:后端在 done 事件返回的消息标识(存在时 SDK Widget 用其启用消息反馈,若返回可据此判断该消息可 feedback)
|
|
179
180
|
signal?: AbortSignal;
|
|
180
181
|
}
|
|
181
182
|
```
|
|
@@ -303,26 +304,57 @@ sdk.setToken("<TOKEN>");
|
|
|
303
304
|
|
|
304
305
|
消息反馈(赞/踩)。调用 `sdk.feedback()` 发送 `POST /chat/messages/{messageId}/feedback`;调用 `sdk.cancelFeedback()` 发送 `DELETE` 取消反馈。
|
|
305
306
|
|
|
307
|
+
> **messageId 说明**:即消息历史返回的表主键 `id`(数字),不是 `messageId`(UUID)。纯 API 模式从 `getMessages()` 结果取 `UIMessage.id`。
|
|
308
|
+
|
|
306
309
|
```ts
|
|
310
|
+
const messages = await sdk.getMessages(sessionId);
|
|
311
|
+
const aiMsg = messages.findLast((m) => m.role === "assistant");
|
|
312
|
+
|
|
307
313
|
// 点赞
|
|
308
|
-
await sdk.feedback(
|
|
314
|
+
await sdk.feedback(aiMsg.id, "like");
|
|
309
315
|
|
|
310
316
|
// 踩(可附原因 + 备注)
|
|
311
|
-
await sdk.feedback(
|
|
317
|
+
await sdk.feedback(aiMsg.id, "dislike", {
|
|
312
318
|
reason: 1, // 1=事实错误 2=逻辑问题 3=不相关 4=信息过时 5=冗长啰嗦 6=难以理解
|
|
313
319
|
remark: "时间描述有误",
|
|
314
320
|
});
|
|
315
321
|
|
|
316
322
|
// 取消反馈
|
|
317
|
-
await sdk.cancelFeedback(
|
|
323
|
+
await sdk.cancelFeedback(aiMsg.id);
|
|
318
324
|
```
|
|
319
325
|
|
|
320
326
|
组件内置的点赞/踩按钮已自动调用 `feedback()`/`cancelFeedback()`:
|
|
321
327
|
- 点击已选中的按钮 → 取消(DELETE)
|
|
322
328
|
- 点击另一个按钮 → 切换(POST)
|
|
323
329
|
- 点踩时弹出原因选择面板(可选填原因 + 备注后提交)
|
|
330
|
+
- 流式渲染期间消息尚无后端 ID(临时占位),此时点击反馈 SDK 会自动拉取一次历史消息解析真实 ID 再发送,业务方无感知
|
|
331
|
+
|
|
332
|
+
### 5.10 respondInterrupt()
|
|
333
|
+
|
|
334
|
+
响应中断事件(Human-in-the-Loop),后端继续推送后续 SSE 事件:
|
|
335
|
+
|
|
336
|
+
```ts
|
|
337
|
+
sdk.respondInterrupt(
|
|
338
|
+
interruptId: string,
|
|
339
|
+
sessionId: string,
|
|
340
|
+
response: InterruptResponse,
|
|
341
|
+
onMessage?: (event: ChatEvent) => void,
|
|
342
|
+
onError?: (error: Error) => void
|
|
343
|
+
): Promise<void>
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
Widget 内置中断卡片会自动调用此方法,纯 API 模式需手动处理(详见 [12. Human-in-the-Loop](#12-human-in-the-loop))。
|
|
347
|
+
|
|
348
|
+
### 5.11 listSkills()
|
|
324
349
|
|
|
325
|
-
|
|
350
|
+
获取当前 Bot 绑定的技能列表(用于 `/` 斜杠命令选择技能):
|
|
351
|
+
|
|
352
|
+
```ts
|
|
353
|
+
const skills: SkillInfo[] = await sdk.listSkills();
|
|
354
|
+
// [{ code: "web-searcher", name: "web-searcher", displayName: "网页搜索", description: "..." }]
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### 5.12 后端接口对照
|
|
326
358
|
|
|
327
359
|
SDK 方法 → 后端接口的完整映射:
|
|
328
360
|
|
|
@@ -336,6 +368,7 @@ SDK 方法 → 后端接口的完整映射:
|
|
|
336
368
|
| `listConversations()` | `GET /chat/conversations` | 查询参数 `botId`、`page`、`size` | `{ items: [{ sessionId, botId, ... }], total }` |
|
|
337
369
|
| `feedback()` | `POST /chat/messages/{messageId}/feedback` | `{ type, reason?, remark? }` | `null` |
|
|
338
370
|
| `cancelFeedback()` | `DELETE /chat/messages/{messageId}/feedback` | 无 body | `null` |
|
|
371
|
+
| `respondInterrupt()` | `POST /chat/interrupt/{interruptId}/respond` | `{ sessionId, action, value? }` | SSE 流(后续事件) |
|
|
339
372
|
| `stopGeneration()` | `POST /chat/stop` | `{ sessionId }` | `{ stopped: "pending", sessionId }` |
|
|
340
373
|
| `listSkills()` | `GET /chat/bots/{botId}/skills` | — | `[{ code, name, displayName, description }]` |
|
|
341
374
|
|
|
@@ -364,6 +397,7 @@ export interface MountOptions {
|
|
|
364
397
|
title?: string; // 标题,默认 "AI Assistant"
|
|
365
398
|
sidebarDefaultOpen?: boolean; // fullpage 模式:侧边栏初始展开(默认 true)
|
|
366
399
|
avatar?: AvatarConfig; // 自定义头像
|
|
400
|
+
artifactPreview?: boolean; // 产物预览总开关(html/pdf/docx 预览 + 下载 + 全屏),默认 false
|
|
367
401
|
}
|
|
368
402
|
|
|
369
403
|
export interface WidgetInstance {
|
|
@@ -504,6 +538,7 @@ export interface Slots {
|
|
|
504
538
|
ToolCallPart?: ComponentType<ToolCallPartProps>;
|
|
505
539
|
ToolResultPart?: ComponentType<ToolResultPartProps>;
|
|
506
540
|
ErrorPart?: ComponentType<ErrorPartProps>;
|
|
541
|
+
InterruptCard?: ComponentType<InterruptCardProps>;
|
|
507
542
|
WelcomeScreen?: ComponentType<WelcomeScreenProps>;
|
|
508
543
|
}
|
|
509
544
|
```
|
|
@@ -518,8 +553,8 @@ export interface Slots {
|
|
|
518
553
|
| `ThreadList` | `ThreadListProps` | 会话列表(浮窗模式覆盖层 / 全屏模式侧边栏) |
|
|
519
554
|
| `ThinkingPart` | `ThinkingPartProps` | 思考过程块 |
|
|
520
555
|
| `TextPart` | `TextPartProps` | 文本块 |
|
|
521
|
-
| `ToolCallPart` | `ToolCallPartProps` |
|
|
522
|
-
| `ToolResultPart` | `ToolResultPartProps` |
|
|
556
|
+
| `ToolCallPart` | `ToolCallPartProps` | 工具调用卡片(可折叠 + 展开后复制参数) |
|
|
557
|
+
| `ToolResultPart` | `ToolResultPartProps` | 工具返回卡片(pre 滚动 + 复制;`renderMode==="html"` 时 DOMPurify 清洗后直接渲染,最高 60vh 滚动) |
|
|
523
558
|
| `ErrorPart` | `ErrorPartProps` | 错误提示块 |
|
|
524
559
|
| `WelcomeScreen` | `WelcomeScreenProps` | 空会话欢迎页 |
|
|
525
560
|
|
|
@@ -697,8 +732,8 @@ function MyComposer({ status, onSend, onStop }: ComposerProps) {
|
|
|
697
732
|
export interface ActionBarProps {
|
|
698
733
|
message: UIMessage;
|
|
699
734
|
onCopy: () => void;
|
|
700
|
-
onRegenerate
|
|
701
|
-
onFeedback?: (messageId: string, feedback: "like" | "dislike") => void;
|
|
735
|
+
onRegenerate?: () => void;
|
|
736
|
+
onFeedback?: (messageId: string, feedback: "like" | "dislike", options?: { reason?: number; remark?: string }) => void;
|
|
702
737
|
}
|
|
703
738
|
```
|
|
704
739
|
|
|
@@ -797,6 +832,10 @@ export interface ToolResultPartProps {
|
|
|
797
832
|
toolName: string;
|
|
798
833
|
toolCallId: string;
|
|
799
834
|
content: string;
|
|
835
|
+
artifacts?: Artifact[];
|
|
836
|
+
renderMode?: string;
|
|
837
|
+
html?: string;
|
|
838
|
+
artifactPreview?: boolean;
|
|
800
839
|
}
|
|
801
840
|
export interface ErrorPartProps {
|
|
802
841
|
content: string;
|
|
@@ -1113,7 +1152,7 @@ await sdk.deleteConversation(items[0].sessionId);
|
|
|
1113
1152
|
- **新建**:点击「新会话」清空当前消息,下次发送时自动调用 `createSession()` 创建新会话。
|
|
1114
1153
|
- **重命名**:`fullpage` 侧边栏或自定义 `ThreadList` 中调用 `renameConversation`。
|
|
1115
1154
|
- **删除**:悬停会话项后点击删除按钮。
|
|
1116
|
-
- **本地持久化**:最近一次活跃会话写入 `localStorage`,键为 `
|
|
1155
|
+
- **本地持久化**:最近一次活跃会话写入 `localStorage`,键为 `sa_active_conversation_{botId}`(按 Bot 隔离,切换 Bot 后互不串扰)。
|
|
1117
1156
|
|
|
1118
1157
|
---
|
|
1119
1158
|
|
|
@@ -1185,7 +1224,7 @@ ac.abort();
|
|
|
1185
1224
|
|
|
1186
1225
|
页面刷新或组件重新挂载时,会话状态自动恢复:
|
|
1187
1226
|
|
|
1188
|
-
1. 挂载时从 `localStorage` 读取上次活跃会话 ID(键 `
|
|
1227
|
+
1. 挂载时从 `localStorage` 读取上次活跃会话 ID(键 `sa_active_conversation_{botId}`)。
|
|
1189
1228
|
2. 若该会话仍在列表中,自动调用 `getMessages` 拉取历史消息并渲染。
|
|
1190
1229
|
3. 若存储的会话已不存在(被删除),则自动清空并回退到「新会话」。
|
|
1191
1230
|
|
|
@@ -1218,8 +1257,17 @@ export type MessagePart =
|
|
|
1218
1257
|
toolName: string;
|
|
1219
1258
|
toolCallId: string;
|
|
1220
1259
|
content: string;
|
|
1260
|
+
artifacts?: Artifact[];
|
|
1261
|
+
renderMode?: string;
|
|
1262
|
+
html?: string;
|
|
1221
1263
|
}
|
|
1222
|
-
| { type: "error"; content: string }
|
|
1264
|
+
| { type: "error"; content: string }
|
|
1265
|
+
| {
|
|
1266
|
+
type: "interrupt";
|
|
1267
|
+
interrupt: InterruptEvent;
|
|
1268
|
+
resolved?: boolean;
|
|
1269
|
+
response?: InterruptResponse;
|
|
1270
|
+
};
|
|
1223
1271
|
```
|
|
1224
1272
|
|
|
1225
1273
|
| type | 字段 | 说明 |
|
|
@@ -1227,8 +1275,9 @@ export type MessagePart =
|
|
|
1227
1275
|
| `text` | `content` | 文本 / Markdown 内容 |
|
|
1228
1276
|
| `thinking` | `content` | 思考过程(reasoning) |
|
|
1229
1277
|
| `tool_call` | `toolName`, `toolCallId`, `args` | 工具调用,`args` 为 JSON 字符串 |
|
|
1230
|
-
| `tool_result` | `toolName`, `toolCallId`, `content` | 工具返回结果
|
|
1278
|
+
| `tool_result` | `toolName`, `toolCallId`, `content`, `artifacts?`, `renderMode?`, `html?` | 工具返回结果 |
|
|
1231
1279
|
| `error` | `content` | 错误信息 |
|
|
1280
|
+
| `interrupt` | `interrupt`, `resolved?`, `response?` | 中断交互卡片(HITL) |
|
|
1232
1281
|
|
|
1233
1282
|
### 11.3 ChatEvent(流式事件)
|
|
1234
1283
|
|
|
@@ -1242,12 +1291,18 @@ export interface ChatEvent {
|
|
|
1242
1291
|
| "tool_result"
|
|
1243
1292
|
| "done"
|
|
1244
1293
|
| "stop"
|
|
1245
|
-
| "error"
|
|
1294
|
+
| "error"
|
|
1295
|
+
| "interrupt";
|
|
1246
1296
|
content: string;
|
|
1247
1297
|
toolName?: string;
|
|
1248
1298
|
toolCallId?: string;
|
|
1249
1299
|
args?: string; // JSON.stringify 后的字符串
|
|
1250
1300
|
sessionId?: string;
|
|
1301
|
+
messageId?: string; // done 事件携带后端消息标识(后端返回时该消息可反馈/feedback)
|
|
1302
|
+
interrupt?: InterruptEvent; // interrupt 事件携带中断详情
|
|
1303
|
+
artifacts?: Artifact[]; // tool_result 事件携带的结构化产物
|
|
1304
|
+
renderMode?: string; // "html" 时工具结果为富文本
|
|
1305
|
+
html?: string; // renderMode==="html" 时的 HTML 内容
|
|
1251
1306
|
}
|
|
1252
1307
|
```
|
|
1253
1308
|
|
|
@@ -1283,7 +1338,7 @@ Agent 执行中
|
|
|
1283
1338
|
### 12.3 响应中断
|
|
1284
1339
|
|
|
1285
1340
|
```ts
|
|
1286
|
-
await sdk.respondInterrupt(interruptId, {
|
|
1341
|
+
await sdk.respondInterrupt(interruptId, sessionId, {
|
|
1287
1342
|
action: "confirm",
|
|
1288
1343
|
});
|
|
1289
1344
|
```
|
|
@@ -1318,7 +1373,7 @@ sdk.chat({
|
|
|
1318
1373
|
if (e.type === "interrupt" && e.interrupt) {
|
|
1319
1374
|
// 自定义 UI 处理
|
|
1320
1375
|
const ok = window.confirm(e.interrupt.content);
|
|
1321
|
-
sdk.respondInterrupt(e.interrupt.interruptId, {
|
|
1376
|
+
sdk.respondInterrupt(e.interrupt.interruptId, sessionId, {
|
|
1322
1377
|
action: ok ? "confirm" : "cancel",
|
|
1323
1378
|
});
|
|
1324
1379
|
}
|
|
@@ -1346,6 +1401,8 @@ sdk.chat({
|
|
|
1346
1401
|
| `date` | 日期选择 | `submit` | `"2026-08-21T14:00:00"` |
|
|
1347
1402
|
| `location` | 位置选择 | `submit` | `{ address, lat, lng }` |
|
|
1348
1403
|
|
|
1404
|
+
> `form` 的字段定义见 `FormField`(`types.ts`):`type` 支持 `text` / `number` / `password` / `textarea` / `select` / `multiSelect` / `date`;`options` 支持字符串数组或 `{ value, label }` 数组。已回答的历史 interrupt 以禁用态回显用户答案。
|
|
1405
|
+
|
|
1349
1406
|
> 每个 `interruptType` 的完整字段定义见 [API 文档](./API.md) 与 [HITL 设计文档](../docs/superpowers/specs/2026-08-18-human-in-the-loop-design.md)。
|
|
1350
1407
|
|
|
1351
1408
|
---
|
|
@@ -1404,6 +1461,7 @@ interface UseChatReturn {
|
|
|
1404
1461
|
stop: () => void;
|
|
1405
1462
|
regenerate: () => void;
|
|
1406
1463
|
setMessages: (messages: UIMessage[]) => void;
|
|
1464
|
+
respondToInterrupt: (interruptId: string, response: InterruptResponse) => void;
|
|
1407
1465
|
}
|
|
1408
1466
|
```
|
|
1409
1467
|
|
|
@@ -1415,15 +1473,18 @@ export function useConversations(
|
|
|
1415
1473
|
interface UseConversationsOptions {
|
|
1416
1474
|
sdk: SuperAgentSDK;
|
|
1417
1475
|
onConversationChange?: (sessionId: string) => void;
|
|
1476
|
+
enabled?: boolean; // 默认 true,false 时不自动加载
|
|
1418
1477
|
}
|
|
1419
1478
|
|
|
1420
1479
|
interface UseConversationsReturn {
|
|
1421
1480
|
conversations: Conversation[];
|
|
1422
1481
|
activeConversationId: string | null;
|
|
1423
1482
|
loading: boolean;
|
|
1483
|
+
hasMore: boolean;
|
|
1424
1484
|
loadConversations: () => Promise<void>;
|
|
1485
|
+
loadMore: () => Promise<void>;
|
|
1425
1486
|
switchConversation: (sessionId: string) => Promise<UIMessage[]>;
|
|
1426
|
-
newConversation: () => void
|
|
1487
|
+
newConversation: () => Promise<void>;
|
|
1427
1488
|
deleteConversation: (sessionId: string) => Promise<void>;
|
|
1428
1489
|
renameConversation: (sessionId: string, title: string) => Promise<void>;
|
|
1429
1490
|
setActiveConversationId: (id: string | null) => void;
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function u(r){if(Array.isArray(r))return r.map(e=>u(e));if(r&&typeof r=="object"&&r.constructor===Object){const e={};for(const[t,s]of Object.entries(r)){const o=t.replace(/_([a-z])/g,(n
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function u(r){if(Array.isArray(r))return r.map(e=>u(e));if(r&&typeof r=="object"&&r.constructor===Object){const e={};for(const[t,s]of Object.entries(r)){const o=t.replace(/_([a-z])/g,(a,n)=>n.toUpperCase());e[o]=u(s)}return e}return r}const I="/api/agent/runtime/v1";class w{constructor(e){this.refreshing=null;const t=e.baseUrl??I;this.baseUrl=t.replace(/\/$/,""),this.tokenGateway=e.tokenGateway.replace(/\/$/,""),this.appId=e.appId??"",this.token=e.token??"",this.botId=e.botId,this.isAbsoluteUrl=/^https?:\/\//.test(this.baseUrl),this.isAbsoluteGateway=/^https?:\/\//.test(this.tokenGateway)}getBotId(){return this.botId}getAppKey(){return this.appId}setToken(e){this.token=e}getOrigin(){return typeof window<"u"?window.location.origin:""}async fetchToken(){const t=`${this.isAbsoluteGateway?this.tokenGateway:`${this.getOrigin()}${this.tokenGateway}`}/v1/token`,s=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({botId:this.botId})});if(!s.ok)throw new Error(`HTTP ${s.status}: ${s.statusText}`);const o=await s.json();if(o.code!=="200")throw new Error(o.message||`API error: ${o.code}`);const a=u(o.data);return this.token=a.token,a.appId&&!this.appId&&(this.appId=a.appId),a.token}headers(e){return{"Content-Type":"application/json","X-App-Id":this.appId,"X-Token":this.token,...e}}async handleTokenRefresh(){if(this.refreshing)return await this.refreshing,!0;try{return this.refreshing=(async()=>{await this.fetchToken()})(),await this.refreshing,!0}catch{return!1}finally{this.refreshing=null}}async request(e,t,s){if(!this.token&&!await this.handleTokenRefresh())throw new Error("SDK token not available: POST /token failed");let o=this.isAbsoluteUrl?`${this.baseUrl}${t}`:`${this.getOrigin()}${this.baseUrl}${t}`;if(s!=null&&s.params){const i=new URLSearchParams;for(const[d,l]of Object.entries(s.params))l!=null&&i.set(d,String(l));const c=i.toString();c&&(o+=`?${c}`)}const a=await fetch(o,{method:e,headers:this.headers(),body:s!=null&&s.body?JSON.stringify(s.body):void 0});if(a.status===401&&!(s!=null&&s.retry)&&await this.handleTokenRefresh())return this.request(e,t,{...s,retry:!0});if(!a.ok)throw new Error(`HTTP ${a.status}: ${a.statusText}`);const n=await a.json();if(n.code!=="200")throw new Error(n.message||`API error: ${n.code}`);return u(n.data)}get(e,t){return this.request("GET",e,{params:t})}post(e,t){return this.request("POST",e,{body:t})}patch(e,t){return this.request("PATCH",e,{body:t})}del(e){return this.request("DELETE",e)}async streamPost(e,t,s){if(!this.token&&!await this.handleTokenRefresh())throw new Error("SDK token not available: POST /token failed");const o=this.isAbsoluteUrl?`${this.baseUrl}${e}`:`${this.getOrigin()}${this.baseUrl}${e}`,a=await fetch(o,{method:"POST",headers:this.headers(),body:JSON.stringify(t),signal:s});return a.status===401&&await this.handleTokenRefresh()?fetch(o,{method:"POST",headers:this.headers(),body:JSON.stringify(t),signal:s}):a}}function y(r){const e=r.split(`
|
|
2
2
|
`).map(s=>s.trim()).filter(s=>s.startsWith("data:")).map(s=>s.slice(5).trim());if(!e.length)return null;let t;try{t=JSON.parse(e.join(`
|
|
3
|
-
`))}catch{return null}switch(t.type){case"user":return{type:"user",content:t.content??""};case"thinking":return{type:"thinking",content:t.content??""};case"ai":return{type:"ai",content:t.content??""};case"tool_call":return{type:"tool_call",content:t.name??"",toolName:t.name,toolCallId:t.id,args:typeof t.args=="string"?t.args:JSON.stringify(t.args??{})};case"tool_result":return{type:"tool_result",content:t.output??"",toolName:t.name,toolCallId:t.id,artifacts:Array.isArray(t.artifacts)?t.artifacts:void 0,renderMode:t.render_mode??t.renderMode,html:t.html};case"done":return{type:"done",content:t.content??"",sessionId:t.sessionId??t.session_id??"",messageId:t.messageId??t.message_id};case"stop":return{type:"stop",content:t.content??"",sessionId:t.sessionId??t.session_id??""};case"error":return{type:"error",content:t.message??"Unknown error"};case"interrupt":return{type:"interrupt",content:t.content??"",interrupt:{interruptId:t.interruptId??t.interrupt_id??"",interruptType:t.interruptType??t.interrupt_type??"confirm",content:t.content??"",options:t.options,placeholder:t.placeholder,inputType:t.inputType??t.input_type,maxLength:t.maxLength??t.max_length,required:t.required,fields:t.fields,metadata:t.metadata}};default:return null}}async function m(r,e,t){if(!r.body){t(new Error("Response body is null"));return}const s=r.body.getReader(),o=new TextDecoder;let
|
|
3
|
+
`))}catch{return null}switch(t.type){case"user":return{type:"user",content:t.content??""};case"thinking":return{type:"thinking",content:t.content??""};case"ai":return{type:"ai",content:t.content??""};case"tool_call":return{type:"tool_call",content:t.name??"",toolName:t.name,toolCallId:t.id,args:typeof t.args=="string"?t.args:JSON.stringify(t.args??{})};case"tool_result":return{type:"tool_result",content:t.output??"",toolName:t.name,toolCallId:t.id,artifacts:Array.isArray(t.artifacts)?t.artifacts:void 0,renderMode:t.render_mode??t.renderMode,html:t.html};case"done":return{type:"done",content:t.content??"",sessionId:t.sessionId??t.session_id??"",messageId:t.messageId??t.message_id};case"stop":return{type:"stop",content:t.content??"",sessionId:t.sessionId??t.session_id??"",messageId:t.messageId??t.message_id};case"error":return{type:"error",content:t.message??"Unknown error"};case"interrupt":return{type:"interrupt",content:t.content??"",interrupt:{interruptId:t.interruptId??t.interrupt_id??"",interruptType:t.interruptType??t.interrupt_type??"confirm",content:t.content??"",options:t.options,placeholder:t.placeholder,inputType:t.inputType??t.input_type,maxLength:t.maxLength??t.max_length,required:t.required,fields:t.fields,metadata:t.metadata}};default:return null}}async function m(r,e,t){if(!r.body){t(new Error("Response body is null"));return}const s=r.body.getReader(),o=new TextDecoder;let a="";try{for(;;){const{value:n,done:i}=await s.read();if(i)break;a+=o.decode(n,{stream:!0});let c;for(;(c=a.indexOf(`
|
|
4
4
|
|
|
5
|
-
`))!==-1;){const d=
|
|
5
|
+
`))!==-1;){const d=a.slice(0,c);a=a.slice(c+2);const l=y(d);l&&e(l)}}if(a.trim()){const n=y(a);n&&e(n)}}catch(n){(n==null?void 0:n.name)!=="AbortError"&&t(n instanceof Error?n:new Error(String(n)))}finally{try{s.releaseLock()}catch{}}}function b(r,e){const t=new AbortController,s=e.signal?p(e.signal,t.signal):t.signal,o={botId:r.getBotId(),message:e.message,sessionId:e.sessionId,stream:e.stream!==!1};return o.stream?r.streamPost("/chat",o,s).then(a=>{var n;if(!a.ok){(n=e.onError)==null||n.call(e,new Error(`HTTP ${a.status}`));return}return m(a,i=>{var c,d,l,h,f,g;i.type==="done"&&i.sessionId?(c=e.onDone)==null||c.call(e,{sessionId:i.sessionId,content:i.content,messageId:i.messageId}):i.type==="done"?(d=e.onDone)==null||d.call(e,{sessionId:"",content:i.content,messageId:i.messageId}):i.type==="stop"?((l=e.onMessage)==null||l.call(e,i),(h=e.onDone)==null||h.call(e,{sessionId:i.sessionId??"",content:i.content,messageId:i.messageId})):i.type==="error"?(f=e.onError)==null||f.call(e,new Error(i.content)):(g=e.onMessage)==null||g.call(e,i)},i=>{var c;return(c=e.onError)==null?void 0:c.call(e,i)})}).catch(a=>{var n;(a==null?void 0:a.name)!=="AbortError"&&((n=e.onError)==null||n.call(e,a instanceof Error?a:new Error(String(a))))}):r.post("/chat",o).then(a=>{var n;(n=e.onDone)==null||n.call(e,{sessionId:a.sessionId,content:a.content??"",messageId:a.messageId})}).catch(a=>{var n;(n=e.onError)==null||n.call(e,a instanceof Error?a:new Error(String(a)))}),t}function p(r,e){const t=new AbortController,s=()=>t.abort();return r.addEventListener("abort",s,{once:!0}),e.addEventListener("abort",s,{once:!0}),(r.aborted||e.aborted)&&t.abort(),t.signal}async function T(r){return(await r.post("/chat/sessions",{botId:r.getBotId()})).sessionId}function k(r){return{sessionId:r.threadId??r.sessionId,botId:r.botId,title:r.title,createTime:r.createTime,updateTime:r.updateTime}}async function S(r,e){const t=await r.get("/chat/conversations",{botId:r.getBotId(),page:(e==null?void 0:e.page)??1,size:(e==null?void 0:e.size)??20});return{...t,items:t.items.map(k)}}async function $(r,e,t){await r.patch(`/chat/conversations/${e}`,{title:t})}async function A(r,e){await r.del(`/chat/conversations/${e}`)}async function C(r,e){const t=await r.get(`/chat/conversations/${e}/messages`);return O(t)}function O(r){const e=[...r].sort((n,i)=>{const c=new Date(n.createTime??0).getTime()||0,d=new Date(i.createTime??0).getTime()||0;return c!==d?c-d:(n.seq??0)-(i.seq??0)}),t=new Map;for(const n of e)n.role==="tool"&&n.toolCallId&&t.set(n.toolCallId,n.content||"");const s=new Set,o=[],a=(n,i,c)=>{const d=o[o.length-1];(d==null?void 0:d.role)==="assistant"?(d.parts.push(...n),d.id=i):o.push({id:i,role:"assistant",parts:[...n],timestamp:c})};for(const n of e){if(n.role==="system")continue;const i=String(n.id??n.messageId??`msg_${Date.now()}`),c=new Date(n.createTime??"").getTime()||Date.now();if(n.role==="human"){o.push({id:i,role:"user",parts:[{type:"text",content:n.content??""}],timestamp:c});continue}if(n.role==="ai"){const d=P(n,t,s);d.length>0&&a(d,i,c);continue}if(n.role==="tool"){if(n.toolCallId&&s.has(n.toolCallId))continue;a([v(n)],i,c)}}return o}function P(r,e,t){const s=[];r.reasoning&&s.push({type:"thinking",content:r.reasoning}),r.content&&s.push({type:"text",content:r.content});for(const o of r.toolCalls??[])o.is_interrupt?(t.add(o.id),s.push(_(o,e))):s.push(E(o));return s}function _(r,e){const t=e.has(r.id),s=typeof r.args=="object"?r.args:{};return{type:"interrupt",interrupt:{interruptId:r.id??"",interruptType:s.interruptType??"input",content:s.content??"",options:s.options,placeholder:s.placeholder,inputType:s.inputType,maxLength:s.maxLength,required:s.required,fields:s.fields,metadata:s.metadata},resolved:t,response:t?{action:"submit",value:U(e.get(r.id))}:void 0}}function E(r){let e;try{e=typeof r.args=="string"?r.args:JSON.stringify(r.args??{})}catch{e=String(r.args??"{}")}return{type:"tool_call",toolName:r.name??"",toolCallId:r.id??"",args:e}}function v(r){var t,s,o;const e=Array.isArray(r.artifacts)?r.artifacts:void 0;return{type:"tool_result",toolName:r.toolName??"",toolCallId:r.toolCallId??"",content:r.content??"",artifacts:e,renderMode:((t=r.metadata)==null?void 0:t.renderMode)??((s=r.metadata)==null?void 0:s.render_mode),html:(o=r.metadata)==null?void 0:o.html}}function U(r){if(r!=null)try{return JSON.parse(r)}catch{return r}}async function x(r,e,t,s,o,a){const n=await r.streamPost(`/chat/interrupt/${e}/respond`,{sessionId:t,action:s.action,value:s.value});if(!n.ok){const i=new Error(`HTTP ${n.status}`);throw a==null||a(i),i}o&&await m(n,i=>{i.type==="error"?a==null||a(new Error(i.content)):o(i)},i=>a==null?void 0:a(i))}async function D(r){return r.get(`/chat/bots/${r.getBotId()}/skills`)}async function q(r,e){await r.post("/chat/stop",{sessionId:e})}function N(r){const e=new w(r);return{botId:e.getBotId(),getToken:()=>e.fetchToken(),createSession:()=>T(e),chat:s=>b(e,s),listConversations:s=>S(e,s),renameConversation:(s,o)=>$(e,s,o),deleteConversation:s=>A(e,s),getMessages:s=>C(e,s),respondInterrupt:(s,o,a,n,i)=>x(e,s,o,a,n,i),setToken:s=>e.setToken(s),feedback:async(s,o,a)=>{const n={type:o};o==="dislike"&&((a==null?void 0:a.reason)!=null&&(n.reason=a.reason),a!=null&&a.remark&&(n.remark=a.remark)),await e.post(`/chat/messages/${s}/feedback`,n)},cancelFeedback:async s=>{await e.del(`/chat/messages/${s}/feedback`)},listSkills:()=>D(e),stopGeneration:s=>q(e,s)}}exports.createSuperAgent=N;
|
package/dist/index.d.ts
CHANGED
|
@@ -55,11 +55,14 @@ export declare function createSuperAgent(config: SDKConfig): SuperAgentSDK;
|
|
|
55
55
|
export declare interface FormField {
|
|
56
56
|
name: string;
|
|
57
57
|
label: string;
|
|
58
|
-
type: 'text' | 'number' | 'password' | 'textarea' | 'select' | 'date';
|
|
58
|
+
type: 'text' | 'number' | 'password' | 'textarea' | 'select' | 'multiSelect' | 'date';
|
|
59
59
|
required?: boolean;
|
|
60
60
|
placeholder?: string;
|
|
61
61
|
defaultValue?: any;
|
|
62
|
-
options?: string
|
|
62
|
+
options?: (string | {
|
|
63
|
+
value: string;
|
|
64
|
+
label: string;
|
|
65
|
+
})[];
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
export declare interface InterruptEvent {
|
|
@@ -145,6 +148,8 @@ declare interface SkillInfo {
|
|
|
145
148
|
}
|
|
146
149
|
|
|
147
150
|
export declare interface SuperAgentSDK {
|
|
151
|
+
/** 当前 Bot ID(只读) */
|
|
152
|
+
readonly botId: number;
|
|
148
153
|
/** 获取 token(调用 POST {tokenGateway}/v1/token),自动设置内部凭证 */
|
|
149
154
|
getToken(): Promise<string>;
|
|
150
155
|
/** 创建新会话,返回 sessionId */
|