super-agent-sdk 1.0.16 → 1.0.18

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 CHANGED
@@ -86,7 +86,7 @@ function createSuperAgent(config: SDKConfig): SuperAgentSDK;
86
86
  ```ts
87
87
  export interface SDKConfig {
88
88
  botId: number; // Bot ID(必填)
89
- tokenGateway: string; // Token 网关前缀(必填,不带 host),如 "/api/gateway";token URL = {origin}{tokenGateway}/v1/token
89
+ tokenGateway: string; // Token 网关前缀(必填,不带 host),如 "/api/gateway";token URL = {origin}{tokenGateway}/v2/token/generate
90
90
  baseUrl?: string; // 业务接口前缀(可选,默认 "/api/agent/runtime/v1"),不带 host
91
91
  appId?: string; // 可选,不传则从 token 接口响应自动获取
92
92
  token?: string; // 可选,不传则自动调 token 接口获取
@@ -109,7 +109,7 @@ createSuperAgent({ botId, tokenGateway })
109
109
  ↓
110
110
  Widget 挂载时自动调用 sdk.getToken()
111
111
  ↓
112
- POST {origin}{tokenGateway}/v1/token(body: { botId })
112
+ POST {origin}{tokenGateway}/v2/token/generate(body: { botId })
113
113
  ↓
114
114
  后端返回 { token, appId }
115
115
  ↓
@@ -194,6 +194,8 @@ export interface ChatOptions {
194
194
  sessionId: string;
195
195
  content: string;
196
196
  messageId?: string;
197
+ roundId?: string; // 本轮对话 id(session.start/session.done 携带)
198
+ artifacts?: Artifact[]; // done 汇总的本轮文件产物(generate_file 等交付产物)
197
199
  }) => void; // messageId:后端在 done 事件返回的消息标识(存在时 SDK Widget 用其启用消息反馈,若返回可据此判断该消息可 feedback)
198
200
  signal?: AbortSignal;
199
201
  }
@@ -302,6 +304,10 @@ const { items, total } = await sdk.listConversations({ page: 1, size: 20 });
302
304
  const messages: UIMessage[] = await sdk.getMessages(sessionId);
303
305
  ```
304
306
 
307
+ 后端历史接口按轮次聚合返回 `[{ roundId, artifacts, data: MessageItem[] }]`,SDK 自动摊平为
308
+ `UIMessage[]`:每组的轮级 `artifacts`(与 SSE `done` 同构)挂到该组最后一条 assistant 消息的
309
+ `artifacts`;`roundId` 为 null(存量旧数据)时 SDK 随机生成,业务方无需处理。
310
+
305
311
  ### 5.6 renameConversation() / deleteConversation()
306
312
 
307
313
  ```ts
@@ -317,7 +323,7 @@ sdk.getToken(): Promise<string>
317
323
 
318
324
  自动获取并保存访问 token:
319
325
 
320
- - SDK 调用 `POST {origin}{tokenGateway}/v1/token`,请求体 `{ botId }`
326
+ - SDK 调用 `POST {origin}{tokenGateway}/v2/token/generate`,请求体 `{ botId }`
321
327
  - 后端返回 `{ token, appId }`
322
328
  - SDK 自动将 token + appId 保存在内部
323
329
  - Widget 在挂载时自动调用此方法 —— 通常无需手动调用
@@ -427,7 +433,7 @@ SDK 方法 → 后端接口的完整映射:
427
433
 
428
434
  | SDK 方法 | HTTP 请求 | 请求体 | 后端返回 |
429
435
  | --------------------- | -------------------------------------------- | --------------------------------------- | ----------------------------------------------- |
430
- | `getToken()` | `POST {gateway}/v1/token` | `{ botId }` | `{ token, appId }` |
436
+ | `getToken()` | `POST {gateway}/v2/token/generate` | `{ botId }` | `{ token, appId }` |
431
437
  | `createSession()` | `POST /chat/sessions` | `{ botId }` | `{ sessionId }` |
432
438
  | `chat()` | `POST /chat` | `{ botId, sessionId, message, stream, attachments? }` | SSE 流,`done`/`stop` 事件含 `sessionId` |
433
439
  | `listConversations()` | `GET /chat/conversations` | 查询参数 `botId`、`page`、`size` | `{ items: [{ sessionId, botId, ... }], total }` |
@@ -462,7 +468,7 @@ export interface MountOptions {
462
468
  title?: string; // 标题,默认 "AI Assistant"
463
469
  sidebarDefaultOpen?: boolean; // fullpage 模式:侧边栏初始展开(默认 true)
464
470
  avatar?: AvatarConfig; // 自定义头像(AI 消息始终有内置默认头像;用户头像未配置则不显示)
465
- artifactPreview?: boolean; // 产物预览总开关(html/pdf/docx 预览 + 下载 + 全屏),默认 false
471
+ artifactPreview?: boolean; // 产物预览总开关(html/markdown/pdf/docx 预览 + 下载 + 全屏),默认 false
466
472
  capabilities?: CapabilityItem[]; // floating 首页:能力清单(icon + 标签 + 描述)
467
473
  quickLinks?: QuickLinkItem[]; // floating 首页:快速入口
468
474
  logo?: string; // floating 首页居中 Logo(URL),默认 SDK 内置 Logo
@@ -717,7 +723,7 @@ export interface Slots {
717
723
  | `ThinkingPart` | `ThinkingPartProps` | 思考过程块 |
718
724
  | `TextPart` | `TextPartProps` | 文本块 |
719
725
  | `ToolCallPart` | `ToolCallPartProps` | 工具调用卡片(可折叠 + 展开后复制参数) |
720
- | `ToolResultPart` | `ToolResultPartProps` | 工具返回卡片(pre 滚动 + 复制;`renderMode==="html"` 时 DOMPurify 清洗后直接渲染,最高 60vh 滚动) |
726
+ | `ToolResultPart` | `ToolResultPartProps` | 工具返回卡片(pre 滚动 + 复制,JSON 自动格式化;`renderMode==="html"` 时 DOMPurify 清洗后直接渲染,最高 60vh 滚动。文件产物卡片已上移至消息级渲染,本组件不再内联展示) |
721
727
  | `ErrorPart` | `ErrorPartProps` | 错误提示块 |
722
728
  | `WelcomeScreen` | `WelcomeScreenProps` | 空会话欢迎页 |
723
729
  | `AppendContainer`| `AppendContainerProps`| 首屏底部业务定制区,`openPanel(action)` 开整屏容器或外链(见下) |
@@ -751,7 +757,7 @@ function MyTrigger({ isOpen, onClick, unreadCount }: TriggerProps) {
751
757
 
752
758
  floating 与 fullpage 模式均支持替换;`onToggleThreadList` 在 floating 下切换内嵌会话侧边栏、在 fullpage 下切换左侧边栏;开启 `artifactPreview` 后额外提供产物入口字段。
753
759
 
754
- > 注:fullpage 内置 Header 只有标题与产物入口(无关闭按钮);需要关闭入口时通过自定义 Header 的 `onClose` 自行渲染。floating 内置 Header 含历史/回首页/大窗/关闭按钮。
760
+ > 注:fullpage 内置 Header 有标题与产物入口(无关闭按钮);整屏容器态标题换成面板 `title`、并出现 home 返回入口,需要关闭入口时通过自定义 Header 的 `onClose` 自行渲染。floating 内置 Header 含历史/回首页/大窗/关闭按钮。
755
761
 
756
762
  ```ts
757
763
  export interface HeaderProps {
@@ -760,10 +766,11 @@ export interface HeaderProps {
760
766
  onToggleThreadList: () => void;
761
767
  isMaximized?: boolean; // floating:大窗状态
762
768
  onToggleMaximize?: () => void; // floating:大窗/小窗切换
763
- showHome?: boolean; // floating:聊天态显示回到首页
764
- onHome?: () => void; // floating:回到首页(新会话)
769
+ showHome?: boolean; // floating:聊天态显示回到首页;整屏容器态显示「返回聊天」
770
+ onHome?: () => void; // 回到首页(新会话);整屏容器态为 closePanel 返回聊天
765
771
  artifactCount?: number; // 会话产物数量(artifactPreview 开启时提供)
766
772
  onToggleArtifactDrawer?: () => void; // 打开/关闭产物预览抽屉
773
+ panelTitle?: string; // 整屏容器态:面板标题(内置 Header 居中显示;自定义 Header 据此自行渲染)
767
774
  }
768
775
  ```
769
776
 
@@ -1011,7 +1018,7 @@ export interface ToolResultPartProps {
1011
1018
  toolName: string;
1012
1019
  toolCallId: string;
1013
1020
  content: string;
1014
- artifacts?: Artifact[];
1021
+ artifacts?: Artifact[]; // 仅供自定义 slot 取用;内置组件不再内联渲染文件卡片(已上移至消息级)
1015
1022
  renderMode?: string;
1016
1023
  html?: string;
1017
1024
  artifactPreview?: boolean;
@@ -1132,9 +1139,9 @@ mount("#app", {
1132
1139
  | 项 | 表现 |
1133
1140
  | --- | --- |
1134
1141
  | 呈现 | 替换「内容区 + 输入区」,Header 保留(小窗仍可拖拽);`link` 走 `window.open`,不占状态 |
1135
- | 标题栏 | 返回箭头 + `title`(可选);`Esc` 等价返回 |
1142
+ | 标题 | 无独立标题栏(纯白背景);`title` 传入时显示在 **Header 居中**(floating 内置 Header / fullpage 均适用,自定义 `slots.Header` 收 `panelTitle` 自行渲染) |
1143
+ | 退出 | Header 的 home 图标(tooltip「返回聊天」)/ 业务组件 `close()` / `Esc`;关闭聊天面板时一并清掉 |
1136
1144
  | 窗口几何 | 保持打开前窗态,小窗不自动升大窗;内容在容器内滚动(业务页不写滚动容器) |
1137
- | 关闭 | 返回 / `close()` / `Esc`;关闭聊天面板时一并清掉 |
1138
1145
  | 栈 | 单层不叠栈,容器内部导航由业务组件自己管 |
1139
1146
 
1140
1147
  注意:浮层组件渲染在 SDK 自己的 `createRoot` 树内,拿不到宿主的 React Context / Router。组件引用直接给,不需要注册表——类型即校验。
@@ -1501,9 +1508,15 @@ export interface UIMessage {
1501
1508
  role: "user" | "assistant";
1502
1509
  parts: MessagePart[];
1503
1510
  timestamp: number;
1511
+ roundId?: string; // 本轮对话 id(历史分组 roundId;后端为 null 时 SDK 随机生成)
1512
+ artifacts?: Artifact[]; // done 汇总的本轮文件产物(历史取分组 artifacts),消息末尾渲染文件卡片
1504
1513
  }
1505
1514
  ```
1506
1515
 
1516
+ > **产物渲染**:文件产物(`generate_file` 交付的 html/md/pdf/docx)统一挂在 assistant 消息的
1517
+ > `artifacts` 上,渲染在该消息末尾为文件卡片(点击开预览抽屉)。流式来自 `done` 事件,历史来自
1518
+ > 分组接口的组级 `artifacts`(与 `done` 同构)。`tool_result` part 不再内联渲染文件卡片。
1519
+
1507
1520
  ### 11.2 MessagePart
1508
1521
 
1509
1522
  ```ts
@@ -1519,6 +1532,7 @@ export type MessagePart =
1519
1532
  artifacts?: Artifact[];
1520
1533
  renderMode?: string;
1521
1534
  html?: string;
1535
+ markdown?: string;
1522
1536
  }
1523
1537
  | { type: "error"; content: string }
1524
1538
  | { type: "attachment"; attachment: ChatAttachment } // 用户消息携带的附件 chip
@@ -1535,7 +1549,7 @@ export type MessagePart =
1535
1549
  | `text` | `content` | 文本 / Markdown 内容 |
1536
1550
  | `thinking` | `content` | 思考过程(reasoning) |
1537
1551
  | `tool_call` | `toolName`, `toolCallId`, `args` | 工具调用,`args` 为 JSON 字符串 |
1538
- | `tool_result` | `toolName`, `toolCallId`, `content`, `artifacts?`, `renderMode?`, `html?` | 工具返回结果 |
1552
+ | `tool_result` | `toolName`, `toolCallId`, `content`, `artifacts?`, `renderMode?`, `html?`, `markdown?` | 工具返回结果(文件产物已上移至消息级 `UIMessage.artifacts`,part 级 `artifacts` 仅供自定义 slot 取用) |
1539
1553
  | `error` | `content` | 错误信息 |
1540
1554
  | `attachment` | `attachment` | 用户消息附件 chip(发送时本地构造 / 历史加载由后端映射,有 `url` 时可下载) |
1541
1555
  | `interrupt` | `interrupt`, `resolved?`, `response?` | 中断交互卡片(HITL) |
@@ -1561,9 +1575,11 @@ export interface ChatEvent {
1561
1575
  sessionId?: string;
1562
1576
  messageId?: string; // done 事件携带后端消息标识(后端返回时该消息可反馈/feedback)
1563
1577
  interrupt?: InterruptEvent; // interrupt 事件携带中断详情
1564
- artifacts?: Artifact[]; // tool_result 事件携带的结构化产物
1578
+ artifacts?: Artifact[]; // tool_result 顶层产物;done 事件汇总本轮产物(Widget 挂到消息级渲染文件卡片)
1565
1579
  renderMode?: string; // "html" 时工具结果为富文本
1566
1580
  html?: string; // renderMode==="html" 时的 HTML 内容
1581
+ markdown?: string; // renderMode==="markdown" 时的 markdown 内容
1582
+ roundId?: string; // session.start/done 携带,本轮对话 id
1567
1583
  }
1568
1584
  ```
1569
1585
 
@@ -1780,7 +1796,7 @@ function MyChat({ sdk }: { sdk: SuperAgentSDK }) {
1780
1796
 
1781
1797
  ### 13.3 Token 续期
1782
1798
 
1783
- 请求返回 `401` 时,SDK 自动重新调用 `POST {tokenGateway}/v1/token` 获取新 token。
1799
+ 请求返回 `401` 时,SDK 自动重新调用 `POST {tokenGateway}/v2/token/generate` 获取新 token。
1784
1800
 
1785
1801
  ### 13.4 停止与取消请求
1786
1802
 
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("./nosUploader-CgVOa1Lz.cjs");function h(r){if(Array.isArray(r))return r.map(e=>h(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]=h(s)}return e}return r}const k="/api/agent/runtime/v1";class T{constructor(e){this.refreshing=null;const t=e.baseUrl??k;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),this.loginUrl=e.loginUrl,this.onAuthExpired=e.onAuthExpired}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=h(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 c=new URLSearchParams;for(const[d,l]of Object.entries(s.params))l!=null&&c.set(d,String(l));const i=c.toString();i&&(o+=`?${i}`)}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 h(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});if(a.status===401){const n=await f.peekCookieExpired(a.clone());if(n.isCookieExpired&&typeof(t==null?void 0:t.message)=="string"){f.stashPendingChat({botId:this.botId,message:t.message,sessionId:t.sessionId??""});const i=n.loginUrl??this.loginUrl;return this.onAuthExpired?this.onAuthExpired({loginUrl:i,sessionId:n.sessionId,botId:this.botId}):i&&window.location.replace(i),a}if(await this.handleTokenRefresh())return fetch(o,{method:"POST",headers:this.headers(),body:JSON.stringify(t),signal:s})}return a}}function u(r){return typeof r=="string"?r:Array.isArray(r)?r.map(e=>{if(typeof e=="string")return e;if(e&&typeof e=="object"){if(typeof e.text=="string")return e.text;if(e.type)return`[${e.type}${e.mime_type?": "+e.mime_type:""}]`}return""}).join(""):r==null?"":String(r)}function p(r){const e=r.split(`
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:u(t.content)};case"thinking":return{type:"thinking",content:u(t.content)};case"ai":return{type:"ai",content:u(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:u(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:u(t.content),sessionId:t.sessionId??t.session_id??"",messageId:t.messageId??t.message_id};case"stop":return{type:"stop",content:u(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 w(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:c}=await s.read();if(c)break;a+=o.decode(n,{stream:!0});let i;for(;(i=a.indexOf(`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("./nosUploader-CgVOa1Lz.cjs");function f(r){if(Array.isArray(r))return r.map(e=>f(e));if(r&&typeof r=="object"&&r.constructor===Object){const e={};for(const[i,n]of Object.entries(r)){const d=i.replace(/_([a-z])/g,(t,s)=>s.toUpperCase());e[d]=f(n)}return e}return r}const S="/api/agent/runtime/v1";class A{constructor(e){this.refreshing=null;const i=e.baseUrl??S;this.baseUrl=i.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),this.loginUrl=e.loginUrl,this.onAuthExpired=e.onAuthExpired}getBotId(){return this.botId}getAppKey(){return this.appId}setToken(e){this.token=e}getOrigin(){return typeof window<"u"?window.location.origin:""}async fetchToken(){const i=`${this.isAbsoluteGateway?this.tokenGateway:`${this.getOrigin()}${this.tokenGateway}`}/v2/token/generate`,n=await fetch(i,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({botId:this.botId})});if(!n.ok)throw new Error(`HTTP ${n.status}: ${n.statusText}`);const d=await n.json();if(d.code!=="200")throw new Error(d.message||`API error: ${d.code}`);const t=f(d.data);return this.token=t.token,t.appId&&!this.appId&&(this.appId=t.appId),t.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,i,n){if(!this.token&&!await this.handleTokenRefresh())throw new Error("SDK token not available: POST /token failed");let d=this.isAbsoluteUrl?`${this.baseUrl}${i}`:`${this.getOrigin()}${this.baseUrl}${i}`;if(n!=null&&n.params){const o=new URLSearchParams;for(const[c,l]of Object.entries(n.params))l!=null&&o.set(c,String(l));const a=o.toString();a&&(d+=`?${a}`)}const t=await fetch(d,{method:e,headers:this.headers(),body:n!=null&&n.body?JSON.stringify(n.body):void 0});if(t.status===401&&!(n!=null&&n.retry)&&await this.handleTokenRefresh())return this.request(e,i,{...n,retry:!0});if(!t.ok){let o=`HTTP ${t.status}: ${t.statusText}`;try{const a=await t.json();a!=null&&a.message&&(o=a.message)}catch{}throw new Error(o)}const s=await t.json();if(s.code!=="200")throw new Error(s.message||`API error: ${s.code}`);return f(s.data)}get(e,i){return this.request("GET",e,{params:i})}post(e,i){return this.request("POST",e,{body:i})}patch(e,i){return this.request("PATCH",e,{body:i})}del(e){return this.request("DELETE",e)}async streamPost(e,i,n){if(!this.token&&!await this.handleTokenRefresh())throw new Error("SDK token not available: POST /token failed");const d=this.isAbsoluteUrl?`${this.baseUrl}${e}`:`${this.getOrigin()}${this.baseUrl}${e}`,t=await fetch(d,{method:"POST",headers:this.headers(),body:JSON.stringify(i),signal:n});if(t.status===401){const s=await h.peekCookieExpired(t.clone());if(s.isCookieExpired&&typeof(i==null?void 0:i.message)=="string"){h.stashPendingChat({botId:this.botId,message:i.message,sessionId:i.sessionId??""});const a=s.loginUrl??this.loginUrl;return this.onAuthExpired?this.onAuthExpired({loginUrl:a,sessionId:s.sessionId,botId:this.botId}):a&&window.location.replace(a),t}if(await this.handleTokenRefresh())return fetch(d,{method:"POST",headers:this.headers(),body:JSON.stringify(i),signal:n})}return t}}function u(r){return typeof r=="string"?r:Array.isArray(r)?r.map(e=>{if(typeof e=="string")return e;if(e&&typeof e=="object"){if(typeof e.text=="string")return e.text;if(e.type)return`[${e.type}${e.mime_type?": "+e.mime_type:""}]`}return""}).join(""):r==null?"":String(r)}function k(r){const e=r.split(`
2
+ `).map(o=>o.trim()).filter(o=>o.length>0);let i,n,d;for(const o of e)if(o.startsWith("id:"))i=o.slice(3).trim();else if(o.startsWith("event:"))n=o.slice(6).trim();else if(o.startsWith("data:")){const a=o.slice(5).trim();d=d?`${d}
3
+ ${a}`:a}if(d===void 0)return null;let t;try{t=JSON.parse(d)}catch{return null}const s=t.type==="tool_result"&&typeof t.content=="object"&&t.content?t.content:void 0;switch(t.type){case"session.start":return{type:"session.start",content:"",sessionId:t.sessionId??t.session_id??"",roundId:t.roundId??t.round_id,event:n,id:i};case"user":return{type:"user",content:u(t.content),event:n,id:i};case"thinking":return{type:"thinking",content:u(t.content),event:n,id:i};case"ai":return{type:"ai",content:u(t.content),event:n,id:i};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??{}),event:n,id:i};case"tool_result":{const o=s==null?void 0:s.result;let a;return typeof o=="string"?a=o:o!=null&&typeof o=="object"?a=JSON.stringify(o):s&&typeof s=="object"&&Object.keys(s).length>0?a=JSON.stringify(s):a=u(t.output??""),{type:"tool_result",content:a,toolName:t.name,toolCallId:t.id,artifacts:Array.isArray(t.artifacts)?t.artifacts:void 0,renderMode:(s==null?void 0:s.render_mode)??t.render_mode??t.renderMode,html:(s==null?void 0:s.html)??t.html,markdown:(s==null?void 0:s.markdown)??t.markdown,event:n,id:i}}case"done":return{type:"done",content:u(t.content),sessionId:t.sessionId??t.session_id??"",messageId:t.messageId??t.message_id,roundId:t.roundId??t.round_id,artifacts:Array.isArray(t.artifacts)?t.artifacts:void 0,event:n,id:i};case"stop":return{type:"stop",content:u(t.content),sessionId:t.sessionId??t.session_id??"",messageId:t.messageId??t.message_id,roundId:t.roundId??t.round_id,event:n,id:i};case"error":return{type:"error",content:t.message??"Unknown error",event:n,id:i};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},event:n,id:i};default:return null}}async function b(r,e,i){if(!r.body){i(new Error("Response body is null"));return}const n=r.body.getReader(),d=new TextDecoder;let t="";try{for(;;){const{value:s,done:o}=await n.read();if(o)break;t+=d.decode(s,{stream:!0});let a;for(;(a=t.indexOf(`
4
4
 
5
- `))!==-1;){const d=a.slice(0,i);a=a.slice(i+2);const l=p(d);l&&e(l)}}if(a.trim()){const n=p(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){var a;const t=new AbortController,s=e.signal?S(e.signal,t.signal):t.signal,o={botId:r.getBotId(),message:e.message,sessionId:e.sessionId,stream:e.stream!==!1,...(a=e.attachments)!=null&&a.length?{attachments:e.attachments.map(({url:n,...c})=>c)}:{}};return o.stream?r.streamPost("/chat",o,s).then(n=>{var c;if(!n.ok){(c=e.onError)==null||c.call(e,new Error(`HTTP ${n.status}`));return}return w(n,i=>{var d,l,g,m,y,I;i.type==="done"&&i.sessionId?(d=e.onDone)==null||d.call(e,{sessionId:i.sessionId,content:i.content,messageId:i.messageId}):i.type==="done"?(l=e.onDone)==null||l.call(e,{sessionId:"",content:i.content,messageId:i.messageId}):i.type==="stop"?((g=e.onMessage)==null||g.call(e,i),(m=e.onDone)==null||m.call(e,{sessionId:i.sessionId??"",content:i.content,messageId:i.messageId})):i.type==="error"?(y=e.onError)==null||y.call(e,new Error(i.content)):(I=e.onMessage)==null||I.call(e,i)},i=>{var d;return(d=e.onError)==null?void 0:d.call(e,i)})}).catch(n=>{var c;(n==null?void 0:n.name)!=="AbortError"&&((c=e.onError)==null||c.call(e,n instanceof Error?n:new Error(String(n))))}):r.post("/chat",o).then(n=>{var c;(c=e.onDone)==null||c.call(e,{sessionId:n.sessionId,content:n.content??"",messageId:n.messageId})}).catch(n=>{var c;(c=e.onError)==null||c.call(e,n instanceof Error?n:new Error(String(n)))}),t}function S(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 $(r){return(await r.post("/chat/sessions",{botId:r.getBotId()})).sessionId}function A(r){return{sessionId:r.threadId??r.sessionId,botId:r.botId,title:r.title,createTime:r.createTime,updateTime:r.updateTime}}async function C(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(A)}}async function _(r,e,t){await r.patch(`/chat/conversations/${e}`,{title:t})}async function x(r,e){await r.del(`/chat/conversations/${e}`)}async function E(r,e){const t=await r.get(`/chat/conversations/${e}/messages`);return P(t)}function P(r){const e=[...r].sort((n,c)=>{const i=new Date(n.createTime??0).getTime()||0,d=new Date(c.createTime??0).getTime()||0;return i!==d?i-d:(n.seq??0)-(c.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,c,i)=>{const d=o[o.length-1];(d==null?void 0:d.role)==="assistant"?(d.parts.push(...n),d.id=c):o.push({id:c,role:"assistant",parts:[...n],timestamp:i})};for(const n of e){if(n.role==="system")continue;const c=String(n.id??n.messageId??`msg_${Date.now()}`),i=new Date(n.createTime??"").getTime()||Date.now();if(n.role==="human"){const d=(n.attachments??[]).map(l=>({type:"attachment",attachment:{nosKey:l.nosKey??l.attachmentId??"",filename:l.filename??"file",size:l.size??void 0,mime:l.mime??void 0,url:l.url??void 0}}));o.push({id:c,role:"user",parts:[...d,{type:"text",content:u(n.content)}],timestamp:i});continue}if(n.role==="ai"){const d=O(n,t,s);d.length>0&&a(d,c,i);continue}if(n.role==="tool"){if(n.toolCallId&&s.has(n.toolCallId))continue;a([N(n)],c,i)}}return o}function O(r,e,t){const s=[];r.reasoning&&s.push({type:"thinking",content:r.reasoning}),r.content&&s.push({type:"text",content:u(r.content)});for(const o of r.toolCalls??[])o.is_interrupt?(t.add(o.id),s.push(U(o,e))):s.push(v(o));return s}function U(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:q(e.get(r.id))}:void 0}}function v(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 N(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:u(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 q(r){if(r!=null)try{return JSON.parse(r)}catch{return r}}async function D(r,e,t,s,o,a,n){const c=await r.streamPost(`/chat/interrupt/${e}/respond`,{sessionId:t,action:s.action,value:s.value},n);if(!c.ok){const i=new Error(`HTTP ${c.status}`);throw a==null||a(i),i}o&&await w(c,i=>{i.type==="error"?a==null||a(new Error(i.content)):o(i)},i=>a==null?void 0:a(i))}async function L(r){return r.get(`/chat/bots/${r.getBotId()}/skills`)}async function G(r,e){await r.post("/chat/stop",{sessionId:e})}function M(r){const e=new T(r);return{botId:e.getBotId(),getToken:()=>e.fetchToken(),createSession:()=>$(e),chat:s=>b(e,s),listConversations:s=>C(e,s),renameConversation:(s,o)=>_(e,s,o),deleteConversation:s=>x(e,s),getMessages:s=>E(e,s),respondInterrupt:(s,o,a,n,c,i)=>D(e,s,o,a,n,c,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:()=>L(e),stopGeneration:s=>G(e,s)}}exports.createNosUploader=f.createNosUploader;exports.createSuperAgent=M;
5
+ `))!==-1;){const c=t.slice(0,a);t=t.slice(a+2);const l=k(c);l&&e(l)}}if(t.trim()){const s=k(t);s&&e(s)}}catch(s){(s==null?void 0:s.name)!=="AbortError"&&i(s instanceof Error?s:new Error(String(s)))}finally{try{n.releaseLock()}catch{}}}function $(r,e){var t;const i=new AbortController,n=e.signal?_(e.signal,i.signal):i.signal,d={botId:r.getBotId(),message:e.message,sessionId:e.sessionId,stream:e.stream!==!1,...(t=e.attachments)!=null&&t.length?{attachments:e.attachments.map(({url:s,...o})=>o)}:{}};return d.stream?r.streamPost("/chat",d,n).then(async s=>{var o;if(!s.ok){let a=`HTTP ${s.status}`;try{const c=await s.json();c!=null&&c.message&&(a=c.message)}catch{}(o=e.onError)==null||o.call(e,new Error(a));return}return b(s,a=>{var c,l,g,m,y,I,p,w;a.type==="done"&&a.sessionId?((c=e.onMessage)==null||c.call(e,a),(l=e.onDone)==null||l.call(e,{sessionId:a.sessionId,content:a.content,messageId:a.messageId,roundId:a.roundId,artifacts:a.artifacts})):a.type==="done"?((g=e.onMessage)==null||g.call(e,a),(m=e.onDone)==null||m.call(e,{sessionId:"",content:a.content,messageId:a.messageId,roundId:a.roundId,artifacts:a.artifacts})):a.type==="stop"?((y=e.onMessage)==null||y.call(e,a),(I=e.onDone)==null||I.call(e,{sessionId:a.sessionId??"",content:a.content,messageId:a.messageId,roundId:a.roundId})):a.type==="error"?(p=e.onError)==null||p.call(e,new Error(a.content)):(w=e.onMessage)==null||w.call(e,a)},a=>{var c;return(c=e.onError)==null?void 0:c.call(e,a)})}).catch(s=>{var o;(s==null?void 0:s.name)!=="AbortError"&&((o=e.onError)==null||o.call(e,s instanceof Error?s:new Error(String(s))))}):r.post("/chat",d).then(s=>{var o;(o=e.onDone)==null||o.call(e,{sessionId:s.sessionId,content:s.content??"",messageId:s.messageId})}).catch(s=>{var o;(o=e.onError)==null||o.call(e,s instanceof Error?s:new Error(String(s)))}),i}function _(r,e){const i=new AbortController,n=()=>i.abort();return r.addEventListener("abort",n,{once:!0}),e.addEventListener("abort",n,{once:!0}),(r.aborted||e.aborted)&&i.abort(),i.signal}async function E(r){return(await r.post("/chat/sessions",{botId:r.getBotId()})).sessionId}function O(r){return{sessionId:r.threadId??r.sessionId,botId:r.botId,title:r.title,createTime:r.createTime,updateTime:r.updateTime}}async function v(r,e){const i=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{...i,items:i.items.map(O)}}async function x(r,e,i){await r.patch(`/chat/conversations/${e}`,{title:i})}async function P(r,e){await r.del(`/chat/conversations/${e}`)}async function C(r,e){const i=await r.get(`/chat/conversations/${e}/messages`);return U(i)}function T(){return`r_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,10)}`}function U(r){var d;const e=r.length>0&&Array.isArray((d=r[0])==null?void 0:d.data),i=[];if(e)for(const t of r)i.push({roundId:t.roundId??T(),artifacts:Array.isArray(t.artifacts)&&t.artifacts.length?t.artifacts:void 0,items:Array.isArray(t.data)?t.data:[]});else i.push({roundId:T(),items:r});const n=[];for(const t of i){const s=N(t.items);for(const o of s)o.roundId=t.roundId;if(t.artifacts){const o=s.findLast(a=>a.role==="assistant");o&&(o.artifacts=t.artifacts)}n.push(...s)}return n}function N(r){const e=[...r].sort((s,o)=>{const a=new Date(s.createTime??0).getTime()||0,c=new Date(o.createTime??0).getTime()||0;return a!==c?a-c:(s.seq??0)-(o.seq??0)}),i=new Map;for(const s of e)s.role==="tool"&&s.toolCallId&&i.set(s.toolCallId,s.content||"");const n=new Set,d=[],t=(s,o,a)=>{const c=d[d.length-1];(c==null?void 0:c.role)==="assistant"?(c.parts.push(...s),c.id=o):d.push({id:o,role:"assistant",parts:[...s],timestamp:a})};for(const s of e){if(s.role==="system")continue;const o=String(s.id??s.messageId??`msg_${Date.now()}`),a=new Date(s.createTime??"").getTime()||Date.now();if(s.role==="human"){const c=(s.attachments??[]).map(l=>({type:"attachment",attachment:{nosKey:l.nosKey??l.attachmentId??"",filename:l.filename??"file",size:l.size??void 0,mime:l.mime??void 0,url:l.url??void 0}}));d.push({id:o,role:"user",parts:[...c,{type:"text",content:u(s.content)}],timestamp:a});continue}if(s.role==="ai"){const c=M(s,i,n);c.length>0&&t(c,o,a);continue}if(s.role==="tool"){if(s.toolCallId&&n.has(s.toolCallId))continue;t([j(s)],o,a)}}return d}function M(r,e,i){const n=[];r.reasoning&&n.push({type:"thinking",content:r.reasoning}),r.content&&n.push({type:"text",content:u(r.content)});for(const d of r.toolCalls??[])d.is_interrupt??d.isInterrupt?(i.add(d.id),n.push(D(d,e))):n.push(q(d));return n}function D(r,e){const i=e.has(r.id),n=typeof r.args=="object"?r.args:{};return{type:"interrupt",interrupt:{interruptId:r.id??"",interruptType:n.interruptType??"input",content:n.content??"",options:n.options,placeholder:n.placeholder,inputType:n.inputType,maxLength:n.maxLength,required:n.required,fields:n.fields,metadata:n.metadata},resolved:i,response:i?{action:"submit",value:J(e.get(r.id))}:void 0}}function q(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 j(r){var i,n,d,t;const e=Array.isArray(r.artifacts)?r.artifacts:void 0;return{type:"tool_result",toolName:r.toolName??"",toolCallId:r.toolCallId??"",content:u(r.content),artifacts:e,renderMode:r.renderMode??((i=r.metadata)==null?void 0:i.renderMode)??((n=r.metadata)==null?void 0:n.render_mode),html:r.html??((d=r.metadata)==null?void 0:d.html),markdown:r.markdown??((t=r.metadata)==null?void 0:t.markdown)}}function J(r){if(r!=null)try{return JSON.parse(r)}catch{return r}}async function L(r,e,i,n,d,t,s){const o=await r.streamPost(`/chat/interrupt/${e}/respond`,{sessionId:i,action:n.action,value:n.value},s);if(!o.ok){const a=new Error(`HTTP ${o.status}`);throw t==null||t(a),a}d&&await b(o,a=>{a.type==="error"?t==null||t(new Error(a.content)):d(a)},a=>t==null?void 0:t(a))}async function G(r){return r.get(`/chat/bots/${r.getBotId()}/skills`)}async function R(r,e){await r.post("/chat/stop",{sessionId:e})}function B(r){const e=new A(r);return{botId:e.getBotId(),getToken:()=>e.fetchToken(),createSession:()=>E(e),chat:n=>$(e,n),listConversations:n=>v(e,n),renameConversation:(n,d)=>x(e,n,d),deleteConversation:n=>P(e,n),getMessages:n=>C(e,n),respondInterrupt:(n,d,t,s,o,a)=>L(e,n,d,t,s,o,a),setToken:n=>e.setToken(n),feedback:async(n,d,t)=>{const s={type:d};d==="dislike"&&((t==null?void 0:t.reason)!=null&&(s.reason=t.reason),t!=null&&t.remark&&(s.remark=t.remark)),await e.post(`/chat/messages/${n}/feedback`,s)},cancelFeedback:async n=>{await e.del(`/chat/messages/${n}/feedback`)},listSkills:()=>G(e),stopGeneration:n=>R(e,n)}}exports.createNosUploader=h.createNosUploader;exports.createSuperAgent=B;
package/dist/index.d.ts CHANGED
@@ -24,7 +24,7 @@ export declare interface ChatAttachment {
24
24
  }
25
25
 
26
26
  export declare interface ChatEvent {
27
- type: "user" | "thinking" | "ai" | "tool_call" | "tool_result" | "done" | "stop" | "error" | "interrupt";
27
+ type: "session.start" | "user" | "thinking" | "ai" | "tool_call" | "tool_result" | "done" | "stop" | "error" | "interrupt";
28
28
  content: string;
29
29
  toolName?: string;
30
30
  toolCallId?: string;
@@ -35,6 +35,10 @@ export declare interface ChatEvent {
35
35
  artifacts?: Artifact[];
36
36
  renderMode?: string;
37
37
  html?: string;
38
+ markdown?: string;
39
+ roundId?: string;
40
+ event?: string;
41
+ id?: string;
38
42
  }
39
43
 
40
44
  export declare interface ChatOptions {
@@ -49,6 +53,8 @@ export declare interface ChatOptions {
49
53
  sessionId: string;
50
54
  content: string;
51
55
  messageId?: string;
56
+ roundId?: string;
57
+ artifacts?: Artifact[];
52
58
  }) => void;
53
59
  signal?: AbortSignal;
54
60
  }
@@ -142,6 +148,7 @@ export declare type MessagePart = {
142
148
  artifacts?: Artifact[];
143
149
  renderMode?: string;
144
150
  html?: string;
151
+ markdown?: string;
145
152
  } | {
146
153
  type: "error";
147
154
  content: string;
@@ -196,7 +203,7 @@ declare interface SkillInfo {
196
203
  export declare interface SuperAgentSDK {
197
204
  /** 当前 Bot ID(只读) */
198
205
  readonly botId: number;
199
- /** 获取 token(调用 POST {tokenGateway}/v1/token),自动设置内部凭证 */
206
+ /** 获取 token(调用 POST {tokenGateway}/v2/token/generate),自动设置内部凭证 */
200
207
  getToken(): Promise<string>;
201
208
  /** 创建新会话,返回 sessionId */
202
209
  createSession(): Promise<string>;
@@ -226,6 +233,8 @@ export declare interface UIMessage {
226
233
  role: "user" | "assistant";
227
234
  parts: MessagePart[];
228
235
  timestamp: number;
236
+ roundId?: string;
237
+ artifacts?: Artifact[];
229
238
  }
230
239
 
231
240
  export { }