super-agent-sdk 1.0.4 → 1.0.6

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
@@ -63,9 +63,8 @@ import { createSuperAgent } from "super-agent-sdk";
63
63
  import { mount } from "super-agent-sdk/widget";
64
64
 
65
65
  const sdk = createSuperAgent({
66
- baseUrl: "/api/v1",
67
66
  botId: 1,
68
- appId: "your_app_id",
67
+ tokenGateway: "/api/gateway",
69
68
  });
70
69
  // Token 自动获取,无需手动设置
71
70
  const widget = mount("#chat", { sdk });
@@ -84,39 +83,40 @@ function createSuperAgent(config: SDKConfig): SuperAgentSDK;
84
83
 
85
84
  ```ts
86
85
  export interface SDKConfig {
87
- baseUrl: string; // e.g. "https://agent.example.com/api/v1"
88
- botId: number; // bot ID
89
- appId: string; // 应用密钥,用于换取 token
86
+ botId: number; // Bot ID(必填)
87
+ tokenGateway: string; // Token 网关前缀(必填,不带 host),如 "/api/gateway";token URL = {origin}{tokenGateway}/v1/token
88
+ baseUrl?: string; // 业务接口前缀(可选,默认 "/api/agent/runtime/v1"),不带 host
89
+ appId?: string; // 可选,不传则从 token 接口响应自动获取
90
+ token?: string; // 可选,不传则自动调 token 接口获取
90
91
  }
91
92
  ```
92
93
 
93
- 只需提供 `baseUrl`、`botId` 与 `appId` 即可。SDK 不要求在创建时传入 `token`——组件挂载后会自动调用 `sdk.getToken()` 获取 token 并内部保存,无需手动设置。
94
+ 只需提供 `botId` 与 `tokenGateway` 即可。`baseUrl` 默认为 `/api/agent/runtime/v1`,`appId` 从 token 接口响应中自动获取。SDK 不要求在创建时传入 `token`——组件挂载后会自动调用 `sdk.getToken()` 获取 token 并内部保存,无需手动设置。
94
95
 
95
96
  ```ts
96
97
  const sdk = createSuperAgent({
97
- baseUrl: "https://agent.example.com/api/v1",
98
98
  botId: 1,
99
- appId: "your_app_id",
99
+ tokenGateway: "/api/gateway",
100
100
  });
101
101
  ```
102
102
 
103
103
  凭证获取流程:
104
104
 
105
105
  ```
106
- createSuperAgent({ baseUrl, botId, appId })
106
+ createSuperAgent({ botId, tokenGateway })
107
107
 
108
108
  Widget 挂载时自动调用 sdk.getToken()
109
109
 
110
- POST /api/token(无参数)
110
+ POST {origin}{tokenGateway}/v1/token(body: { botId })
111
111
 
112
- 后端返回 { token }
112
+ 后端返回 { token, appId }
113
113
 
114
- SDK 内部自动保存 token
114
+ SDK 内部自动保存 token + appId
115
115
 
116
116
  ready
117
117
  ```
118
118
 
119
- `appId` 用于换取访问 token,浏览器端后续请求只持有短时有效的 token。
119
+ `tokenGateway` 用于拼接 token 接口路径,`appId` 自动从 token 响应获取(也可手动传入覆盖)。
120
120
 
121
121
  ---
122
122
 
@@ -141,8 +141,9 @@ export interface SuperAgentSDK {
141
141
  getMessages(sessionId: string): Promise<UIMessage[]>;
142
142
  getToken(): Promise<string>;
143
143
  setToken(token: string): void;
144
- feedback(messageId: string, type: "like" | "dislike"): void;
145
- onFeedback?: (messageId: string, type: "like" | "dislike") => void;
144
+ feedback(messageId: string, type: "like" | "dislike", options?: { reason?: number; remark?: string }): Promise<void>;
145
+ cancelFeedback(messageId: string): Promise<void>;
146
+ respondInterrupt(interruptId: string, sessionId: string, response: InterruptResponse): Promise<void>;
146
147
  }
147
148
  ```
148
149
 
@@ -275,9 +276,9 @@ sdk.getToken(): Promise<string>
275
276
 
276
277
  自动获取并保存访问 token:
277
278
 
278
- - SDK 调用 `POST /api/token`(固定路径,不拼接 `baseUrl`),无需请求参数
279
- - 后端返回 `{ token }`
280
- - SDK 自动将 token 保存在内部
279
+ - SDK 调用 `POST {origin}{tokenGateway}/v1/token`,请求体 `{ botId }`
280
+ - 后端返回 `{ token, appId }`
281
+ - SDK 自动将 token + appId 保存在内部
281
282
  - Widget 在挂载时自动调用此方法 —— 通常无需手动调用
282
283
 
283
284
  ```ts
@@ -296,21 +297,28 @@ sdk.setToken(token: string): void
296
297
  sdk.setToken("<TOKEN>");
297
298
  ```
298
299
 
299
- ### 5.9 feedback() / onFeedback
300
+ ### 5.9 feedback() / cancelFeedback()
300
301
 
301
- 点赞 / 踩:调用 `sdk.feedback()`,SDK 会回调你注册的 `sdk.onFeedback`。
302
+ 消息反馈(赞/踩)。调用 `sdk.feedback()` 发送 `POST /chat/messages/{messageId}/feedback`;调用 `sdk.cancelFeedback()` 发送 `DELETE` 取消反馈。
302
303
 
303
304
  ```ts
304
- sdk.onFeedback = (messageId, type) => {
305
- // type: 'like' | 'dislike'
306
- console.log(`Feedback: ${type} on message ${messageId}`);
307
- // 上报到自己的业务后端
308
- };
305
+ // 点赞
306
+ await sdk.feedback("msg_123", "like");
309
307
 
310
- sdk.feedback("msg_123", "like");
308
+ // 踩(可附原因 + 备注)
309
+ await sdk.feedback("msg_123", "dislike", {
310
+ reason: 1, // 1=事实错误 2=逻辑问题 3=不相关 4=信息过时 5=冗长啰嗦 6=难以理解
311
+ remark: "时间描述有误",
312
+ });
313
+
314
+ // 取消反馈
315
+ await sdk.cancelFeedback("msg_123");
311
316
  ```
312
317
 
313
- 组件内置的点赞 / 踩按钮也会经过 `sdk.feedback()`,因此只需注册一次 `onFeedback` 即可统一接收所有反馈。
318
+ 组件内置的点赞/踩按钮已自动调用 `feedback()`/`cancelFeedback()`:
319
+ - 点击已选中的按钮 → 取消(DELETE)
320
+ - 点击另一个按钮 → 切换(POST)
321
+ - 点踩时弹出原因选择面板(可选填原因 + 备注后提交)
314
322
 
315
323
  ### 5.10 后端接口对照
316
324
 
@@ -320,10 +328,12 @@ SDK 方法 → 后端接口的完整映射:
320
328
 
321
329
  | SDK 方法 | HTTP 请求 | 请求体 | 后端返回 |
322
330
  | --------------------- | ------------------------- | --------------------------------------- | ----------------------------------------------- |
323
- | `getToken()` | `POST /api/token` | 无参数 | `{ token }` |
331
+ | `getToken()` | `POST {gateway}/v1/token` | `{ botId }` | `{ token, appId }` |
324
332
  | `createSession()` | `POST /chat/sessions` | `{ botId }` | `{ sessionId }` |
325
333
  | `chat()` | `POST /chat` | `{ botId, sessionId, message, stream }` | SSE 流,`done` 事件含 `sessionId` |
326
334
  | `listConversations()` | `GET /chat/conversations` | 查询参数 `botId`、`page`、`size` | `{ items: [{ sessionId, botId, ... }], total }` |
335
+ | `feedback()` | `POST /chat/messages/{messageId}/feedback` | `{ type, reason?, remark? }` | `null` |
336
+ | `cancelFeedback()` | `DELETE /chat/messages/{messageId}/feedback` | 无 body | `null` |
327
337
 
328
338
  ---
329
339
 
@@ -364,9 +374,8 @@ import { createSuperAgent } from "super-agent-sdk";
364
374
  import { mount } from "super-agent-sdk/widget";
365
375
 
366
376
  const sdk = createSuperAgent({
367
- baseUrl: "/api/v1",
368
377
  botId: 1,
369
- appId: "your_app_id",
378
+ tokenGateway: "/api/gateway",
370
379
  });
371
380
 
372
381
  const widget = mount("#chat-root", {
@@ -858,7 +867,7 @@ mount("#chat-root", {
858
867
  });
859
868
  ```
860
869
 
861
- > 点赞 / 踩的反馈回调不在 `hooks` 中,而是在 `sdk.onFeedback`(见 [5.9](#59-feedback--onfeedback))。
870
+ > 点赞 / 踩由内置 `ActionBar` 组件通过 `ChatState.feedback()` / `cancelFeedback()` 自动处理,无需额外配置(见 [5.9](#59-feedback--cancelfeedback))。
862
871
 
863
872
  ### 8.5 定制示例
864
873
 
@@ -876,9 +885,8 @@ import type {
876
885
  } from "super-agent-sdk/widget";
877
886
 
878
887
  const sdk = createSuperAgent({
879
- baseUrl: "/api/v1",
880
888
  botId: 1,
881
- appId: "your_app_id",
889
+ tokenGateway: "/api/gateway",
882
890
  });
883
891
  sdk.setToken("demo_token");
884
892
 
@@ -1304,9 +1312,8 @@ sdk.chat({
1304
1312
  import { createSuperAgent } from "super-agent-sdk";
1305
1313
 
1306
1314
  const sdk = createSuperAgent({
1307
- baseUrl: "/api/v1",
1308
1315
  botId: 1,
1309
- appId: "your_app_id",
1316
+ tokenGateway: "/api/gateway",
1310
1317
  });
1311
1318
  sdk.setToken("<TOKEN>");
1312
1319
 
@@ -1398,7 +1405,7 @@ function MyChat({ sdk }: { sdk: SuperAgentSDK }) {
1398
1405
 
1399
1406
  ### 13.3 Token 续期
1400
1407
 
1401
- 请求返回 `401` 时,SDK 自动重新调用 `POST /api/token` 获取新 token。
1408
+ 请求返回 `401` 时,SDK 自动重新调用 `POST {tokenGateway}/v1/token` 获取新 token。
1402
1409
 
1403
1410
  ### 13.4 取消请求
1404
1411
 
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function u(n){if(Array.isArray(n))return n.map(e=>u(e));if(n&&typeof n=="object"&&n.constructor===Object){const e={};for(const[t,r]of Object.entries(n)){const o=t.replace(/_([a-z])/g,(s,a)=>a.toUpperCase());e[o]=u(r)}return e}return n}class g{constructor(e){this.refreshing=null,this.baseUrl=e.baseUrl.replace(/\/$/,""),this.appId=e.appId,this.token=e.token??"",this.botId=e.botId}getBotId(){return this.botId}getAppKey(){return this.appId}setToken(e){this.token=e}getOrigin(){try{return new URL(this.baseUrl).origin}catch{return""}}async fetchToken(){const e=`${this.getOrigin()}/api/token`,t=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:this.appId,botId:this.botId})});if(!t.ok)throw new Error(`HTTP ${t.status}: ${t.statusText}`);const r=await t.json();if(r.code!=="200")throw new Error(r.message||`API error: ${r.code}`);const o=u(r.data);return this.token=o.token,o.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,r){if(!this.token&&!await this.handleTokenRefresh())throw new Error("SDK token not available: POST /token failed");let o=`${this.baseUrl}${t}`;if(r!=null&&r.params){const i=new URLSearchParams;for(const[l,d]of Object.entries(r.params))d!=null&&i.set(l,String(d));const c=i.toString();c&&(o+=`?${c}`)}const s=await fetch(o,{method:e,headers:this.headers(),body:r!=null&&r.body?JSON.stringify(r.body):void 0});if(s.status===401&&!(r!=null&&r.retry)&&await this.handleTokenRefresh())return this.request(e,t,{...r,retry:!0});if(!s.ok)throw new Error(`HTTP ${s.status}: ${s.statusText}`);const a=await s.json();if(a.code!=="200")throw new Error(a.message||`API error: ${a.code}`);return u(a.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,r){if(!this.token&&!await this.handleTokenRefresh())throw new Error("SDK token not available: POST /token failed");const o=`${this.baseUrl}${e}`,s=await fetch(o,{method:"POST",headers:this.headers(),body:JSON.stringify(t),signal:r});return s.status===401&&await this.handleTokenRefresh()?fetch(o,{method:"POST",headers:this.headers(),body:JSON.stringify(t),signal:r}):s}}function f(n){const e=n.split(`
2
- `).map(r=>r.trim()).filter(r=>r.startsWith("data:")).map(r=>r.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};case"done":return{type:"done",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 y(n,e,t){if(!n.body){t(new Error("Response body is null"));return}const r=n.body.getReader(),o=new TextDecoder;let s="";try{for(;;){const{value:a,done:i}=await r.read();if(i)break;s+=o.decode(a,{stream:!0});let c;for(;(c=s.indexOf(`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function f(a){if(Array.isArray(a))return a.map(e=>f(e));if(a&&typeof a=="object"&&a.constructor===Object){const e={};for(const[t,n]of Object.entries(a)){const o=t.replace(/_([a-z])/g,(r,s)=>s.toUpperCase());e[o]=f(n)}return e}return a}const w="/api/agent/runtime/v1";class I{constructor(e){this.refreshing=null;const t=e.baseUrl??w;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`,n=await fetch(t,{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 o=await n.json();if(o.code!=="200")throw new Error(o.message||`API error: ${o.code}`);const r=f(o.data);return this.token=r.token,r.appId&&!this.appId&&(this.appId=r.appId),r.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,n){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(n!=null&&n.params){const i=new URLSearchParams;for(const[l,d]of Object.entries(n.params))d!=null&&i.set(l,String(d));const c=i.toString();c&&(o+=`?${c}`)}const r=await fetch(o,{method:e,headers:this.headers(),body:n!=null&&n.body?JSON.stringify(n.body):void 0});if(r.status===401&&!(n!=null&&n.retry)&&await this.handleTokenRefresh())return this.request(e,t,{...n,retry:!0});if(!r.ok)throw new Error(`HTTP ${r.status}: ${r.statusText}`);const s=await r.json();if(s.code!=="200")throw new Error(s.message||`API error: ${s.code}`);return f(s.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,n){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}`,r=await fetch(o,{method:"POST",headers:this.headers(),body:JSON.stringify(t),signal:n});return r.status===401&&await this.handleTokenRefresh()?fetch(o,{method:"POST",headers:this.headers(),body:JSON.stringify(t),signal:n}):r}}function y(a){const e=a.split(`
2
+ `).map(n=>n.trim()).filter(n=>n.startsWith("data:")).map(n=>n.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"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(a,e,t){if(!a.body){t(new Error("Response body is null"));return}const n=a.body.getReader(),o=new TextDecoder;let r="";try{for(;;){const{value:s,done:i}=await n.read();if(i)break;r+=o.decode(s,{stream:!0});let c;for(;(c=r.indexOf(`
4
4
 
5
- `))!==-1;){const l=s.slice(0,c);s=s.slice(c+2);const d=f(l);d&&e(d)}}if(s.trim()){const a=f(s);a&&e(a)}}catch(a){(a==null?void 0:a.name)!=="AbortError"&&t(a instanceof Error?a:new Error(String(a)))}finally{try{r.releaseLock()}catch{}}}function m(n,e){const t=new AbortController,r=e.signal?I(e.signal,t.signal):t.signal,o={botId:n.getBotId(),message:e.message,sessionId:e.sessionId,stream:e.stream!==!1};return o.stream?n.streamPost("/chat",o,r).then(s=>{var a;if(!s.ok){(a=e.onError)==null||a.call(e,new Error(`HTTP ${s.status}`));return}return y(s,i=>{var c,l,d,h;i.type==="done"&&i.sessionId?(c=e.onDone)==null||c.call(e,{sessionId:i.sessionId,content:i.content}):i.type==="done"?(l=e.onDone)==null||l.call(e,{sessionId:"",content:i.content}):i.type==="error"?(d=e.onError)==null||d.call(e,new Error(i.content)):(h=e.onMessage)==null||h.call(e,i)},i=>{var c;return(c=e.onError)==null?void 0:c.call(e,i)})}).catch(s=>{var a;(s==null?void 0:s.name)!=="AbortError"&&((a=e.onError)==null||a.call(e,s instanceof Error?s:new Error(String(s))))}):n.post("/chat",o).then(s=>{var a;(a=e.onDone)==null||a.call(e,{sessionId:s.sessionId,content:s.content??""})}).catch(s=>{var a;(a=e.onError)==null||a.call(e,s instanceof Error?s:new Error(String(s)))}),t}function I(n,e){const t=new AbortController,r=()=>t.abort();return n.addEventListener("abort",r,{once:!0}),e.addEventListener("abort",r,{once:!0}),(n.aborted||e.aborted)&&t.abort(),t.signal}async function w(n){return(await n.post("/chat/sessions",{botId:n.getBotId()})).sessionId}function T(n){return{sessionId:n.threadId??n.sessionId,botId:n.botId,title:n.title,createTime:n.createTime,updateTime:n.updateTime}}async function b(n,e){const t=await n.get("/chat/conversations",{botId:n.getBotId(),page:(e==null?void 0:e.page)??1,size:(e==null?void 0:e.size)??20});return{...t,items:t.items.map(T)}}async function k(n,e,t){await n.patch(`/chat/conversations/${e}`,{title:t})}async function S(n,e){await n.del(`/chat/conversations/${e}`)}async function p(n,e){const t=await n.get(`/chat/conversations/${e}/messages`);return E(t)}function E(n){const e=[],t=[...n].sort((r,o)=>(r.seq??0)-(o.seq??0));for(const r of t){const o=r.role;if(o==="system")continue;const s=r.messageId??`msg_${r.id}`,a=new Date(r.createTime??"").getTime()||Date.now();if(o==="human")e.push({id:s,role:"user",parts:[{type:"text",content:r.content??""}],timestamp:a});else if(o==="ai"){const i=[];r.reasoning&&i.push({type:"thinking",content:r.reasoning}),r.content&&i.push({type:"text",content:r.content});const c=r.toolCalls;if(c&&Array.isArray(c))for(const l of c){let d;try{d=typeof l.args=="string"?l.args:JSON.stringify(l.args??{})}catch{d=String(l.args??"{}")}i.push({type:"tool_call",toolName:l.name??"",toolCallId:l.id??"",args:d})}e.push({id:s,role:"assistant",parts:i,timestamp:a})}else o==="tool"&&e.push({id:s,role:"assistant",parts:[{type:"tool_result",toolName:r.toolName??"",toolCallId:r.toolCallId??"",content:r.content??""}],timestamp:a})}return e}async function C(n,e,t,r){await n.post(`/chat/interrupt/${e}/respond`,{sessionId:t,action:r.action,value:r.value})}function O(n){const e=new g(n),t={getToken:()=>e.fetchToken(),createSession:()=>w(e),chat:r=>m(e,r),listConversations:r=>b(e,r),renameConversation:(r,o)=>k(e,r,o),deleteConversation:r=>S(e,r),getMessages:r=>p(e,r),respondInterrupt:(r,o,s)=>C(e,r,o,s),setToken:r=>e.setToken(r),feedback:(r,o)=>{var s;(s=t.onFeedback)==null||s.call(t,r,o)}};return t}exports.createSuperAgent=O;
5
+ `))!==-1;){const l=r.slice(0,c);r=r.slice(c+2);const d=y(l);d&&e(d)}}if(r.trim()){const s=y(r);s&&e(s)}}catch(s){(s==null?void 0:s.name)!=="AbortError"&&t(s instanceof Error?s:new Error(String(s)))}finally{try{n.releaseLock()}catch{}}}function k(a,e){const t=new AbortController,n=e.signal?b(e.signal,t.signal):t.signal,o={botId:a.getBotId(),message:e.message,sessionId:e.sessionId,stream:e.stream!==!1};return o.stream?a.streamPost("/chat",o,n).then(r=>{var s;if(!r.ok){(s=e.onError)==null||s.call(e,new Error(`HTTP ${r.status}`));return}return m(r,i=>{var c,l,d,h;i.type==="done"&&i.sessionId?(c=e.onDone)==null||c.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==="error"?(d=e.onError)==null||d.call(e,new Error(i.content)):(h=e.onMessage)==null||h.call(e,i)},i=>{var c;return(c=e.onError)==null?void 0:c.call(e,i)})}).catch(r=>{var s;(r==null?void 0:r.name)!=="AbortError"&&((s=e.onError)==null||s.call(e,r instanceof Error?r:new Error(String(r))))}):a.post("/chat",o).then(r=>{var s;(s=e.onDone)==null||s.call(e,{sessionId:r.sessionId,content:r.content??"",messageId:r.messageId})}).catch(r=>{var s;(s=e.onError)==null||s.call(e,r instanceof Error?r:new Error(String(r)))}),t}function b(a,e){const t=new AbortController,n=()=>t.abort();return a.addEventListener("abort",n,{once:!0}),e.addEventListener("abort",n,{once:!0}),(a.aborted||e.aborted)&&t.abort(),t.signal}async function T(a){return(await a.post("/chat/sessions",{botId:a.getBotId()})).sessionId}function S(a){return{sessionId:a.threadId??a.sessionId,botId:a.botId,title:a.title,createTime:a.createTime,updateTime:a.updateTime}}async function p(a,e){const t=await a.get("/chat/conversations",{botId:a.getBotId(),page:(e==null?void 0:e.page)??1,size:(e==null?void 0:e.size)??20});return{...t,items:t.items.map(S)}}async function $(a,e,t){await a.patch(`/chat/conversations/${e}`,{title:t})}async function A(a,e){await a.del(`/chat/conversations/${e}`)}async function C(a,e){const t=await a.get(`/chat/conversations/${e}/messages`);return O(t)}function O(a){var n,o,r;const e=[],t=[...a].sort((s,i)=>(s.seq??0)-(i.seq??0));for(const s of t){const i=s.role;if(i==="system")continue;const c=s.messageId??`msg_${s.id}`,l=new Date(s.createTime??"").getTime()||Date.now();if(i==="human")e.push({id:c,role:"user",parts:[{type:"text",content:s.content??""}],timestamp:l});else if(i==="ai"){const d=[];s.reasoning&&d.push({type:"thinking",content:s.reasoning}),s.content&&d.push({type:"text",content:s.content});const h=s.toolCalls;if(h&&Array.isArray(h))for(const u of h){let g;try{g=typeof u.args=="string"?u.args:JSON.stringify(u.args??{})}catch{g=String(u.args??"{}")}d.push({type:"tool_call",toolName:u.name??"",toolCallId:u.id??"",args:g})}e.push({id:c,role:"assistant",parts:d,timestamp:l})}else if(i==="tool"){const d=Array.isArray(s.artifacts)?s.artifacts:void 0;e.push({id:c,role:"assistant",parts:[{type:"tool_result",toolName:s.toolName??"",toolCallId:s.toolCallId??"",content:s.content??"",artifacts:d,renderMode:((n=s.metadata)==null?void 0:n.renderMode)??((o=s.metadata)==null?void 0:o.render_mode),html:(r=s.metadata)==null?void 0:r.html}],timestamp:l})}}return e}async function _(a,e,t,n,o,r){const s=await a.streamPost(`/chat/interrupt/${e}/respond`,{sessionId:t,action:n.action,value:n.value});if(!s.ok){const i=new Error(`HTTP ${s.status}`);throw r==null||r(i),i}o&&await m(s,i=>{i.type==="error"?r==null||r(new Error(i.content)):o(i)},i=>r==null?void 0:r(i))}function v(a){const e=new I(a);return{getToken:()=>e.fetchToken(),createSession:()=>T(e),chat:n=>k(e,n),listConversations:n=>p(e,n),renameConversation:(n,o)=>$(e,n,o),deleteConversation:n=>A(e,n),getMessages:n=>C(e,n),respondInterrupt:(n,o,r,s,i)=>_(e,n,o,r,s,i),setToken:n=>e.setToken(n),feedback:async(n,o,r)=>{const s={type:o};o==="dislike"&&((r==null?void 0:r.reason)!=null&&(s.reason=r.reason),r!=null&&r.remark&&(s.remark=r.remark)),await e.post(`/chat/messages/${n}/feedback`,s)},cancelFeedback:async n=>{await e.del(`/chat/messages/${n}/feedback`)}}}exports.createSuperAgent=v;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,19 @@
1
+ /** 通用产物(INTERFACE 约定:type + data,适配 table/chart/file/text/image/html/custom) */
2
+ export declare interface Artifact {
3
+ type: string;
4
+ data: Record<string, any>;
5
+ }
6
+
7
+ export declare interface ArtifactFile {
8
+ id: string;
9
+ type: "html" | "pdf" | "docx" | string;
10
+ filename: string;
11
+ url: string;
12
+ mime?: string;
13
+ size?: number;
14
+ summary?: string;
15
+ }
16
+
1
17
  export declare interface ChatEvent {
2
18
  type: "user" | "thinking" | "ai" | "tool_call" | "tool_result" | "done" | "error" | "interrupt";
3
19
  content: string;
@@ -5,7 +21,11 @@ export declare interface ChatEvent {
5
21
  toolCallId?: string;
6
22
  args?: string;
7
23
  sessionId?: string;
24
+ messageId?: string;
8
25
  interrupt?: InterruptEvent;
26
+ artifacts?: Artifact[];
27
+ renderMode?: string;
28
+ html?: string;
9
29
  }
10
30
 
11
31
  export declare interface ChatOptions {
@@ -17,6 +37,7 @@ export declare interface ChatOptions {
17
37
  onDone?: (result: {
18
38
  sessionId: string;
19
39
  content: string;
40
+ messageId?: string;
20
41
  }) => void;
21
42
  signal?: AbortSignal;
22
43
  }
@@ -67,7 +88,7 @@ export declare interface InterruptResponse {
67
88
  value?: any;
68
89
  }
69
90
 
70
- export declare type InterruptType = 'confirm' | 'select' | 'multiSelect' | 'input' | 'form';
91
+ export declare type InterruptType = 'confirm' | 'select' | 'multiSelect' | 'input' | 'form' | 'approve';
71
92
 
72
93
  export declare interface ListConversationsParams {
73
94
  page?: number;
@@ -95,6 +116,9 @@ export declare type MessagePart = {
95
116
  toolName: string;
96
117
  toolCallId: string;
97
118
  content: string;
119
+ artifacts?: Artifact[];
120
+ renderMode?: string;
121
+ html?: string;
98
122
  } | {
99
123
  type: "error";
100
124
  content: string;
@@ -106,14 +130,15 @@ export declare type MessagePart = {
106
130
  };
107
131
 
108
132
  export declare interface SDKConfig {
109
- baseUrl: string;
110
133
  botId: number;
111
- appId: string;
134
+ tokenGateway: string;
135
+ baseUrl?: string;
136
+ appId?: string;
112
137
  token?: string;
113
138
  }
114
139
 
115
140
  export declare interface SuperAgentSDK {
116
- /** 获取 token(调用 POST /api/token),自动设置内部凭证 */
141
+ /** 获取 token(调用 POST {tokenGateway}/v1/token),自动设置内部凭证 */
117
142
  getToken(): Promise<string>;
118
143
  /** 创建新会话,返回 sessionId */
119
144
  createSession(): Promise<string>;
@@ -122,11 +147,16 @@ export declare interface SuperAgentSDK {
122
147
  renameConversation(sessionId: string, title: string): Promise<void>;
123
148
  deleteConversation(sessionId: string): Promise<void>;
124
149
  getMessages(sessionId: string): Promise<UIMessage[]>;
125
- /** 响应中断事件 */
126
- respondInterrupt(interruptId: string, sessionId: string, response: InterruptResponse): Promise<void>;
150
+ /** 响应中断事件(返回 SSE 流,后端继续推送后续事件) */
151
+ respondInterrupt(interruptId: string, sessionId: string, response: InterruptResponse, onMessage?: (event: ChatEvent) => void, onError?: (error: Error) => void): Promise<void>;
127
152
  setToken(token: string): void;
128
- feedback(messageId: string, type: "like" | "dislike"): void;
129
- onFeedback?: (messageId: string, type: "like" | "dislike") => void;
153
+ /** 消息反馈(赞/踩),POST /chat/messages/{messageId}/feedback */
154
+ feedback(messageId: string, type: "like" | "dislike", options?: {
155
+ reason?: number;
156
+ remark?: string;
157
+ }): Promise<void>;
158
+ /** 取消消息反馈,DELETE /chat/messages/{messageId}/feedback */
159
+ cancelFeedback(messageId: string): Promise<void>;
130
160
  }
131
161
 
132
162
  export declare interface UIMessage {