super-agent-sdk 1.0.21 → 1.0.22

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
@@ -201,7 +201,7 @@ export interface ChatOptions {
201
201
  messageId?: string;
202
202
  roundId?: string; // 本轮对话 id(session.start/session.done 携带)
203
203
  artifacts?: Artifact[]; // done 汇总的本轮文件产物(generate_file 等交付产物)
204
- }) => void; // messageId:后端在 done 事件返回的消息标识(存在时 SDK Widget 用其启用消息反馈,若返回可据此判断该消息可 feedback)
204
+ }) => void; // messageId:done/stop 事件带回的后端消息标识(= conversation_messages.message_id,feedback 按它定位;未带回时 SDK 回查历史兜底)
205
205
  signal?: AbortSignal;
206
206
  }
207
207
 
@@ -352,23 +352,23 @@ sdk.setToken("<TOKEN>");
352
352
 
353
353
  消息反馈(赞/踩)。调用 `sdk.feedback()` 发送 `POST /chat/messages/{messageId}/feedback`;调用 `sdk.cancelFeedback()` 发送 `DELETE` 取消反馈。
354
354
 
355
- > **messageId 说明**:即消息历史返回的表主键 `id`(数字),不是 `messageId`(UUID)。纯 API 模式从 `getMessages()` 结果取 `UIMessage.id`。
355
+ > **messageId 说明**:即消息列表里的 `messageId`(后端 `conversation_messages.message_id`,langchain 原始消息 id,UUID 字符串),**不是** `UIMessage.id`(历史加载为表主键、流式为客户端临时 id,仅作渲染 key)。纯 API 模式从 `getMessages()` 结果取 `UIMessage.messageId`;流式消息由 `done`/`stop` 事件(`onDone` 的 `messageId`)带回,两者都有时以帧内为准。
356
356
 
357
357
  ```ts
358
358
  const messages = await sdk.getMessages(sessionId);
359
359
  const aiMsg = messages.findLast((m) => m.role === "assistant");
360
360
 
361
361
  // 点赞
362
- await sdk.feedback(aiMsg.id, "like");
362
+ await sdk.feedback(aiMsg.messageId!, "like");
363
363
 
364
364
  // 踩(可附原因 + 备注)
365
- await sdk.feedback(aiMsg.id, "dislike", {
365
+ await sdk.feedback(aiMsg.messageId!, "dislike", {
366
366
  reason: 1, // 1=事实错误 2=逻辑问题 3=不相关 4=信息过时 5=冗长啰嗦 6=难以理解
367
367
  remark: "时间描述有误",
368
368
  });
369
369
 
370
370
  // 取消反馈
371
- await sdk.cancelFeedback(aiMsg.id);
371
+ await sdk.cancelFeedback(aiMsg.messageId!);
372
372
  ```
373
373
 
374
374
  组件内置的点赞/踩按钮已自动调用 `feedback()`/`cancelFeedback()`:
@@ -376,7 +376,7 @@ await sdk.cancelFeedback(aiMsg.id);
376
376
  - 点击已选中的按钮 → 取消(DELETE)
377
377
  - 点击另一个按钮 → 切换(POST)
378
378
  - 点踩时弹出原因选择面板(可选填原因 + 备注后提交)
379
- - 流式渲染期间消息尚无后端 ID(临时占位),此时点击反馈 SDK 会自动拉取一次历史消息解析真实 ID 再发送,业务方无感知
379
+ - 消息本身没带 `messageId` 时(如后端 done/stop 帧未回传),SDK 自动拉取一次历史消息,按该消息的 `roundId` 定位到它并取 `messageId` 再发送,业务方无感知
380
380
 
381
381
  ### 5.10 respondInterrupt()
382
382
 
@@ -928,8 +928,9 @@ export interface ActionBarProps {
928
928
  message: UIMessage;
929
929
  onCopy: () => void;
930
930
  onRegenerate?: () => void;
931
+ // 传整条 message(内置 ActionBar 的做法)或 messageId / 本地 id 字符串均可
931
932
  onFeedback?: (
932
- messageId: string,
933
+ message: UIMessage | string,
933
934
  feedback: "like" | "dislike",
934
935
  options?: { reason?: number; remark?: string },
935
936
  ) => void;
@@ -1517,10 +1518,11 @@ ac.abort();
1517
1518
 
1518
1519
  ```ts
1519
1520
  export interface UIMessage {
1520
- id: string;
1521
+ id: string; // 渲染 key:历史加载为表主键,流式为客户端临时 id(不用于 feedback)
1521
1522
  role: "user" | "assistant";
1522
1523
  parts: MessagePart[];
1523
1524
  timestamp: number;
1525
+ messageId?: string; // 后端消息标识(= conversation_messages.message_id),feedback/cancelFeedback 按它定位
1524
1526
  roundId?: string; // 本轮对话 id(历史分组 roundId;后端为 null 时 SDK 随机生成)
1525
1527
  artifacts?: Artifact[]; // done 汇总的本轮文件产物(历史取分组 artifacts),消息末尾渲染文件卡片
1526
1528
  }
@@ -1586,7 +1588,7 @@ export interface ChatEvent {
1586
1588
  toolCallId?: string;
1587
1589
  args?: string; // JSON.stringify 后的字符串
1588
1590
  sessionId?: string;
1589
- messageId?: string; // done 事件携带后端消息标识(后端返回时该消息可反馈/feedback)
1591
+ messageId?: string; // done/stop 事件携带的后端消息标识(= conversation_messages.message_id,feedback 按它定位消息)
1590
1592
  interrupt?: InterruptEvent; // interrupt 事件携带中断详情
1591
1593
  artifacts?: Artifact[]; // tool_result 顶层产物;done 事件汇总本轮产物(Widget 挂到消息级渲染文件卡片)
1592
1594
  renderMode?: string; // "html" 时工具结果为富文本
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("./nosUploader-DLX7JsnR.cjs");function f(s){if(Array.isArray(s))return s.map(e=>f(e));if(s&&typeof s=="object"&&s.constructor===Object){const e={};for(const[i,n]of Object.entries(s)){const d=i.replace(/_([a-z])/g,(t,r)=>r.toUpperCase());e[d]=f(n)}return e}return s}const S="/api/agent/runtime/v1";class C{constructor(e){this.refreshing=null,this.tokenPromise=null;const i=e.baseUrl??S;this.baseUrl=i.replace(/\/$/,""),this.tokenGateway=e.tokenGateway.replace(/\/$/,""),this.appId=e.appId??"",this.token=e.token??"",this.botCode=e.botCode,this.tenantId=e.tenantId,this.isAbsoluteUrl=/^https?:\/\//.test(this.baseUrl),this.isAbsoluteGateway=/^https?:\/\//.test(this.tokenGateway),this.loginUrl=e.loginUrl,this.onAuthExpired=e.onAuthExpired}getBotCode(){return this.botCode}getAppKey(){return this.appId}setToken(e){this.token=e}getOrigin(){return typeof window<"u"?window.location.origin:""}async fetchToken(){if(this.token)return this.token;if(this.tokenPromise)return this.tokenPromise;this.tokenPromise=(async()=>{const i=`${this.isAbsoluteGateway?this.tokenGateway:`${this.getOrigin()}${this.tokenGateway}`}/superagent/v2/token/generate`,n={"Content-Type":"application/json"};this.tenantId!=null&&(n["X-Tenant-Id"]=String(this.tenantId));const d=await fetch(i,{method:"POST",headers:n,body:JSON.stringify({botCode:this.botCode})});if(!d.ok)throw new Error(`HTTP ${d.status}: ${d.statusText}`);const t=await d.json();if(t.code!=="200")throw new Error(t.message||`API error: ${t.code}`);const r=f(t.data);return this.token=r.token,r.appId&&!this.appId&&(this.appId=r.appId),r.token})();try{return await this.tokenPromise}finally{this.tokenPromise=null}}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.token="",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 r=await t.json();if(r.code!=="200")throw new Error(r.message||`API error: ${r.code}`);return f(r.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 r=await h.peekCookieExpired(t.clone());if(r.isCookieExpired&&typeof(i==null?void 0:i.message)=="string"){h.stashPendingChat({botCode:this.botCode,message:i.message,sessionId:i.sessionId??""});const a=r.loginUrl??this.loginUrl;return this.onAuthExpired?this.onAuthExpired({loginUrl:a,sessionId:r.sessionId,botCode:this.botCode}):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(s){return typeof s=="string"?s:Array.isArray(s)?s.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(""):s==null?"":String(s)}function k(s){const e=s.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 r=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_delta":return{type:"tool_delta",content:typeof t.content=="string"?t.content:"",toolCallId:t.tool_call_id??t.toolCallId??"",event:n,id:i};case"tool_result":{const o=r==null?void 0:r.result;let a;return typeof o=="string"?a=o:o!=null&&typeof o=="object"?a=JSON.stringify(o):r&&typeof r=="object"&&Object.keys(r).length>0?a=JSON.stringify(r):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:(r==null?void 0:r.render_mode)??t.render_mode??t.renderMode,html:(r==null?void 0:r.html)??t.html,markdown:(r==null?void 0:r.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(s,e,i){if(!s.body){i(new Error("Response body is null"));return}const n=s.body.getReader(),d=new TextDecoder;let t="";try{for(;;){const{value:r,done:o}=await n.read();if(o)break;t+=d.decode(r,{stream:!0});let a;for(;(a=t.indexOf(`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("./nosUploader-Dk2GyRpT.cjs");function g(r){if(Array.isArray(r))return r.map(e=>g(e));if(r&&typeof r=="object"&&r.constructor===Object){const e={};for(const[o,s]of Object.entries(r)){const d=o.replace(/_([a-z])/g,(t,n)=>n.toUpperCase());e[d]=g(s)}return e}return r}const S="/api/agent/runtime/v1";class C{constructor(e){this.refreshing=null,this.tokenPromise=null;const o=e.baseUrl??S;this.baseUrl=o.replace(/\/$/,""),this.tokenGateway=e.tokenGateway.replace(/\/$/,""),this.appId=e.appId??"",this.token=e.token??"",this.botCode=e.botCode,this.tenantId=e.tenantId,this.isAbsoluteUrl=/^https?:\/\//.test(this.baseUrl),this.isAbsoluteGateway=/^https?:\/\//.test(this.tokenGateway),this.loginUrl=e.loginUrl,this.onAuthExpired=e.onAuthExpired}getBotCode(){return this.botCode}getAppKey(){return this.appId}setToken(e){this.token=e}getOrigin(){return typeof window<"u"?window.location.origin:""}async fetchToken(){if(this.token)return this.token;if(this.tokenPromise)return this.tokenPromise;this.tokenPromise=(async()=>{const o=`${this.isAbsoluteGateway?this.tokenGateway:`${this.getOrigin()}${this.tokenGateway}`}/superagent/v2/token/generate`,s={"Content-Type":"application/json"};this.tenantId!=null&&(s["X-Tenant-Id"]=String(this.tenantId));const d=await fetch(o,{method:"POST",headers:s,body:JSON.stringify({botCode:this.botCode})});if(!d.ok)throw new Error(`HTTP ${d.status}: ${d.statusText}`);const t=await d.json();if(t.code!=="200")throw new Error(t.message||`API error: ${t.code}`);const n=g(t.data);return this.token=n.token,n.appId&&!this.appId&&(this.appId=n.appId),n.token})();try{return await this.tokenPromise}finally{this.tokenPromise=null}}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.token="",this.refreshing=(async()=>{await this.fetchToken()})(),await this.refreshing,!0}catch{return!1}finally{this.refreshing=null}}async request(e,o,s){if(!this.token&&!await this.handleTokenRefresh())throw new Error("SDK token not available: POST /token failed");let d=this.isAbsoluteUrl?`${this.baseUrl}${o}`:`${this.getOrigin()}${this.baseUrl}${o}`;if(s!=null&&s.params){const a=new URLSearchParams;for(const[c,l]of Object.entries(s.params))l!=null&&a.set(c,String(l));const i=a.toString();i&&(d+=`?${i}`)}const t=await fetch(d,{method:e,headers:this.headers(),body:s!=null&&s.body?JSON.stringify(s.body):void 0});if(t.status===401&&!(s!=null&&s.retry)&&await this.handleTokenRefresh())return this.request(e,o,{...s,retry:!0});if(!t.ok){let a=`HTTP ${t.status}: ${t.statusText}`;try{const i=await t.json();i!=null&&i.message&&(a=i.message)}catch{}throw new Error(a)}const n=await t.json();if(n.code!=="200")throw new Error(n.message||`API error: ${n.code}`);return g(n.data)}get(e,o){return this.request("GET",e,{params:o})}post(e,o){return this.request("POST",e,{body:o})}patch(e,o){return this.request("PATCH",e,{body:o})}del(e){return this.request("DELETE",e)}async streamPost(e,o,s){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(o),signal:s});if(t.status===401){const n=await m.peekCookieExpired(t.clone());if(n.isCookieExpired&&typeof(o==null?void 0:o.message)=="string"){m.stashPendingChat({botCode:this.botCode,message:o.message,sessionId:o.sessionId??""});const i=n.loginUrl??this.loginUrl;return this.onAuthExpired?this.onAuthExpired({loginUrl:i,sessionId:n.sessionId,botCode:this.botCode}):i&&window.location.replace(i),t}if(await this.handleTokenRefresh())return fetch(d,{method:"POST",headers:this.headers(),body:JSON.stringify(o),signal:s})}return t}}function h(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(a=>a.trim()).filter(a=>a.length>0);let o,s,d;for(const a of e)if(a.startsWith("id:"))o=a.slice(3).trim();else if(a.startsWith("event:"))s=a.slice(6).trim();else if(a.startsWith("data:")){const i=a.slice(5).trim();d=d?`${d}
3
+ ${i}`:i}if(d===void 0)return null;let t;try{t=JSON.parse(d)}catch{return null}const n=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:s,id:o};case"user":return{type:"user",content:h(t.content),event:s,id:o};case"thinking":return{type:"thinking",content:h(t.content),event:s,id:o};case"ai":return{type:"ai",content:h(t.content),event:s,id:o};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:s,id:o};case"tool_delta":return{type:"tool_delta",content:typeof t.content=="string"?t.content:"",toolCallId:t.tool_call_id??t.toolCallId??"",event:s,id:o};case"tool_result":{const a=n==null?void 0:n.result;let i;return typeof a=="string"?i=a:a!=null&&typeof a=="object"?i=JSON.stringify(a):n&&typeof n=="object"&&Object.keys(n).length>0?i=JSON.stringify(n):i=h(t.output??""),{type:"tool_result",content:i,toolName:t.name,toolCallId:t.id,artifacts:Array.isArray(t.artifacts)?t.artifacts:void 0,renderMode:(n==null?void 0:n.render_mode)??t.render_mode??t.renderMode,html:(n==null?void 0:n.html)??t.html,markdown:(n==null?void 0:n.markdown)??t.markdown,event:s,id:o}}case"done":return{type:"done",content:h(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:s,id:o};case"stop":return{type:"stop",content:h(t.content),sessionId:t.sessionId??t.session_id??"",messageId:t.messageId??t.message_id,roundId:t.roundId??t.round_id,event:s,id:o};case"error":return{type:"error",content:t.message??"Unknown error",event:s,id:o};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:s,id:o};default:return null}}async function b(r,e,o){if(!r.body){o(new Error("Response body is null"));return}const s=r.body.getReader(),d=new TextDecoder;let t="";try{for(;;){const{value:n,done:a}=await s.read();if(a)break;t+=d.decode(n,{stream:!0});let i;for(;(i=t.indexOf(`
4
4
 
5
- `))!==-1;){const c=t.slice(0,a);t=t.slice(a+2);const l=k(c);l&&e(l)}}if(t.trim()){const r=k(t);r&&e(r)}}catch(r){(r==null?void 0:r.name)!=="AbortError"&&i(r instanceof Error?r:new Error(String(r)))}finally{try{n.releaseLock()}catch{}}}function A(s,e){var t;const i=new AbortController,n=e.signal?$(e.signal,i.signal):i.signal,d={botCode:s.getBotCode(),message:e.message,sessionId:e.sessionId,stream:e.stream!==!1,...(t=e.attachments)!=null&&t.length?{attachments:e.attachments.map(({url:r,...o})=>o)}:{}};return d.stream?s.streamPost("/chat",d,n).then(async r=>{var o;if(!r.ok){let a=`HTTP ${r.status}`;try{const c=await r.json();c!=null&&c.message&&(a=c.message)}catch{}(o=e.onError)==null||o.call(e,new Error(a));return}return b(r,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(r=>{var o;(r==null?void 0:r.name)!=="AbortError"&&((o=e.onError)==null||o.call(e,r instanceof Error?r:new Error(String(r))))}):s.post("/chat",d).then(r=>{var o;(o=e.onDone)==null||o.call(e,{sessionId:r.sessionId,content:r.content??"",messageId:r.messageId})}).catch(r=>{var o;(o=e.onError)==null||o.call(e,r instanceof Error?r:new Error(String(r)))}),i}function $(s,e){const i=new AbortController,n=()=>i.abort();return s.addEventListener("abort",n,{once:!0}),e.addEventListener("abort",n,{once:!0}),(s.aborted||e.aborted)&&i.abort(),i.signal}async function _(s){return(await s.post("/chat/sessions",{botCode:s.getBotCode()})).sessionId}function P(s){return{sessionId:s.threadId??s.sessionId,title:s.title,createTime:s.createTime,updateTime:s.updateTime}}async function v(s,e){const i=await s.get("/chat/conversations",{botCode:s.getBotCode(),page:(e==null?void 0:e.page)??1,size:(e==null?void 0:e.size)??20});return{...i,items:i.items.map(P)}}async function E(s,e,i){await s.patch(`/chat/conversations/${e}`,{title:i})}async function O(s,e){await s.del(`/chat/conversations/${e}`)}async function x(s,e){const i=await s.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(s){var d;const e=s.length>0&&Array.isArray((d=s[0])==null?void 0:d.data),i=[];if(e)for(const t of s)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:s});const n=[];for(const t of i){const r=N(t.items);for(const o of r)o.roundId=t.roundId;if(t.artifacts){const o=r.findLast(a=>a.role==="assistant");o&&(o.artifacts=t.artifacts)}n.push(...r)}return n}function N(s){const e=[...s].sort((r,o)=>{const a=new Date(r.createTime??0).getTime()||0,c=new Date(o.createTime??0).getTime()||0;return a!==c?a-c:(r.seq??0)-(o.seq??0)}),i=new Map;for(const r of e)r.role==="tool"&&r.toolCallId&&i.set(r.toolCallId,r.content||"");const n=new Set,d=[],t=(r,o,a)=>{const c=d[d.length-1];(c==null?void 0:c.role)==="assistant"?(c.parts.push(...r),c.id=o):d.push({id:o,role:"assistant",parts:[...r],timestamp:a})};for(const r of e){if(r.role==="system")continue;const o=String(r.id??r.messageId??`msg_${Date.now()}`),a=new Date(r.createTime??"").getTime()||Date.now();if(r.role==="human"){const c=(r.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(r.content)}],timestamp:a});continue}if(r.role==="ai"){const c=M(r,i,n);c.length>0&&t(c,o,a);continue}if(r.role==="tool"){if(r.toolCallId&&n.has(r.toolCallId))continue;t([j(r)],o,a)}}return d}function M(s,e,i){const n=[];s.reasoning&&n.push({type:"thinking",content:s.reasoning}),s.content&&n.push({type:"text",content:u(s.content)});for(const d of s.toolCalls??[])d.is_interrupt??d.isInterrupt?(i.add(d.id),n.push(D(d,e))):n.push(q(d));return n}function D(s,e){const i=e.has(s.id),n=typeof s.args=="object"?s.args:{};return{type:"interrupt",interrupt:{interruptId:s.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(s.id))}:void 0}}function q(s){let e;try{e=typeof s.args=="string"?s.args:JSON.stringify(s.args??{})}catch{e=String(s.args??"{}")}return{type:"tool_call",toolName:s.name??"",toolCallId:s.id??"",args:e}}function j(s){var i,n,d,t;const e=Array.isArray(s.artifacts)?s.artifacts:void 0;return{type:"tool_result",toolName:s.toolName??"",toolCallId:s.toolCallId??"",content:u(s.content),artifacts:e,renderMode:s.renderMode??((i=s.metadata)==null?void 0:i.renderMode)??((n=s.metadata)==null?void 0:n.render_mode),html:s.html??((d=s.metadata)==null?void 0:d.html),markdown:s.markdown??((t=s.metadata)==null?void 0:t.markdown)}}function J(s){if(s!=null)try{return JSON.parse(s)}catch{return s}}async function L(s,e,i,n,d,t,r){const o=await s.streamPost(`/chat/interrupt/${e}/respond`,{sessionId:i,action:n.action,value:n.value},r);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(s){return s.get(`/chat/bots/${s.getBotCode()}/skills`)}async function R(s,e){await s.post("/chat/stop",{sessionId:e})}function B(s){const e=new C(s);return{botCode:e.getBotCode(),getToken:()=>e.fetchToken(),createSession:()=>_(e),chat:n=>A(e,n),listConversations:n=>v(e,n),renameConversation:(n,d)=>E(e,n,d),deleteConversation:n=>O(e,n),getMessages:n=>x(e,n),respondInterrupt:(n,d,t,r,o,a)=>L(e,n,d,t,r,o,a),setToken:n=>e.setToken(n),feedback:async(n,d,t)=>{const r={type:d};d==="dislike"&&((t==null?void 0:t.reason)!=null&&(r.reason=t.reason),t!=null&&t.remark&&(r.remark=t.remark)),await e.post(`/chat/messages/${n}/feedback`,r)},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;
5
+ `))!==-1;){const c=t.slice(0,i);t=t.slice(i+2);const l=k(c);l&&e(l)}}if(t.trim()){const n=k(t);n&&e(n)}}catch(n){(n==null?void 0:n.name)!=="AbortError"&&o(n instanceof Error?n:new Error(String(n)))}finally{try{s.releaseLock()}catch{}}}function A(r,e){var t;const o=new AbortController,s=e.signal?_(e.signal,o.signal):o.signal,d={botCode:r.getBotCode(),message:e.message,sessionId:e.sessionId,stream:e.stream!==!1,...(t=e.attachments)!=null&&t.length?{attachments:e.attachments.map(({url:n,...a})=>a)}:{}};return d.stream?r.streamPost("/chat",d,s).then(async n=>{var a;if(!n.ok){let i=`HTTP ${n.status}`;try{const c=await n.json();c!=null&&c.message&&(i=c.message)}catch{}(a=e.onError)==null||a.call(e,new Error(i));return}return b(n,i=>{var c,l,u,f,y,I,p,w;i.type==="done"&&i.sessionId?((c=e.onMessage)==null||c.call(e,i),(l=e.onDone)==null||l.call(e,{sessionId:i.sessionId,content:i.content,messageId:i.messageId,roundId:i.roundId,artifacts:i.artifacts})):i.type==="done"?((u=e.onMessage)==null||u.call(e,i),(f=e.onDone)==null||f.call(e,{sessionId:"",content:i.content,messageId:i.messageId,roundId:i.roundId,artifacts:i.artifacts})):i.type==="stop"?((y=e.onMessage)==null||y.call(e,i),(I=e.onDone)==null||I.call(e,{sessionId:i.sessionId??"",content:i.content,messageId:i.messageId,roundId:i.roundId})):i.type==="error"?(p=e.onError)==null||p.call(e,new Error(i.content)):(w=e.onMessage)==null||w.call(e,i)},i=>{var c;return(c=e.onError)==null?void 0:c.call(e,i)})}).catch(n=>{var a;(n==null?void 0:n.name)!=="AbortError"&&((a=e.onError)==null||a.call(e,n instanceof Error?n:new Error(String(n))))}):r.post("/chat",d).then(n=>{var a;(a=e.onDone)==null||a.call(e,{sessionId:n.sessionId,content:n.content??"",messageId:n.messageId})}).catch(n=>{var a;(a=e.onError)==null||a.call(e,n instanceof Error?n:new Error(String(n)))}),o}function _(r,e){const o=new AbortController,s=()=>o.abort();return r.addEventListener("abort",s,{once:!0}),e.addEventListener("abort",s,{once:!0}),(r.aborted||e.aborted)&&o.abort(),o.signal}async function $(r){return(await r.post("/chat/sessions",{botCode:r.getBotCode()})).sessionId}function P(r){return{sessionId:r.threadId??r.sessionId,title:r.title,createTime:r.createTime,updateTime:r.updateTime}}async function v(r,e){const o=await r.get("/chat/conversations",{botCode:r.getBotCode(),page:(e==null?void 0:e.page)??1,size:(e==null?void 0:e.size)??20});return{...o,items:o.items.map(P)}}async function E(r,e,o){await r.patch(`/chat/conversations/${e}`,{title:o})}async function O(r,e){await r.del(`/chat/conversations/${e}`)}async function x(r,e){const o=await r.get(`/chat/conversations/${e}/messages`);return U(o)}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),o=[];if(e)for(const t of r)o.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 o.push({roundId:T(),items:r});const s=[];for(const t of o){const n=M(t.items);for(const a of n)a.roundId=t.roundId;if(t.artifacts){const a=n.findLast(i=>i.role==="assistant");a&&(a.artifacts=t.artifacts)}s.push(...n)}return s}function M(r){var n;const e=[...r].sort((a,i)=>{const c=new Date(a.createTime??0).getTime()||0,l=new Date(i.createTime??0).getTime()||0;return c!==l?c-l:(a.seq??0)-(i.seq??0)}),o=new Map;for(const a of e)a.role==="tool"&&a.toolCallId&&o.set(a.toolCallId,a.content||"");const s=new Set,d=[],t=(a,i,c,l)=>{const u=d[d.length-1];(u==null?void 0:u.role)==="assistant"?(u.parts.push(...a),u.id=i,l&&(u.messageId=l)):d.push({id:i,role:"assistant",parts:[...a],timestamp:c,messageId:l})};for(const a of e){if(a.role==="system")continue;const i=String(a.id??a.messageId??`msg_${Date.now()}`),c=new Date(a.createTime??"").getTime()||Date.now();if(a.role==="human"){const l=(a.attachments??[]).map(f=>({type:"attachment",attachment:{nosKey:f.nosKey??f.attachmentId??"",filename:f.filename??"file",size:f.size??void 0,mime:f.mime??void 0,url:f.url??void 0}})),u=(n=a.metadata)==null?void 0:n.raw_message;d.push({id:i,role:"user",parts:[...l,{type:"text",content:h(a.content)}],timestamp:c,messageId:a.messageId,rawContent:typeof u=="string"&&u?u:void 0});continue}if(a.role==="ai"){const l=N(a,o,s);l.length>0&&t(l,i,c,a.messageId);continue}if(a.role==="tool"){if(a.toolCallId&&s.has(a.toolCallId))continue;t([j(a)],i,c)}}return d}function N(r,e,o){const s=[];r.reasoning&&s.push({type:"thinking",content:r.reasoning}),r.content&&s.push({type:"text",content:h(r.content)});for(const d of r.toolCalls??[])d.is_interrupt??d.isInterrupt?(o.add(d.id),s.push(D(d,e))):s.push(q(d));return s}function D(r,e){const o=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:o,response:o?{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 o,s,d,t;const e=Array.isArray(r.artifacts)?r.artifacts:void 0;return{type:"tool_result",toolName:r.toolName??"",toolCallId:r.toolCallId??"",content:h(r.content),artifacts:e,renderMode:r.renderMode??((o=r.metadata)==null?void 0:o.renderMode)??((s=r.metadata)==null?void 0:s.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,o,s,d,t,n){const a=await r.streamPost(`/chat/interrupt/${e}/respond`,{sessionId:o,action:s.action,value:s.value},n);if(!a.ok){const i=new Error(`HTTP ${a.status}`);throw t==null||t(i),i}d&&await b(a,i=>{i.type==="error"?t==null||t(new Error(i.content)):d(i)},i=>t==null?void 0:t(i))}async function G(r){return r.get(`/chat/bots/${r.getBotCode()}/skills`)}async function R(r,e){await r.post("/chat/stop",{sessionId:e})}function B(r){const e=new C(r);return{botCode:e.getBotCode(),getToken:()=>e.fetchToken(),createSession:()=>$(e),chat:s=>A(e,s),listConversations:s=>v(e,s),renameConversation:(s,d)=>E(e,s,d),deleteConversation:s=>O(e,s),getMessages:s=>x(e,s),respondInterrupt:(s,d,t,n,a,i)=>L(e,s,d,t,n,a,i),setToken:s=>e.setToken(s),feedback:async(s,d,t)=>{const n={type:d};d==="dislike"&&((t==null?void 0:t.reason)!=null&&(n.reason=t.reason),t!=null&&t.remark&&(n.remark=t.remark)),await e.post(`/chat/messages/${s}/feedback`,n)},cancelFeedback:async s=>{await e.del(`/chat/messages/${s}/feedback`)},listSkills:()=>G(e),stopGeneration:s=>R(e,s)}}exports.createNosUploader=m.createNosUploader;exports.createSuperAgent=B;
package/dist/index.d.ts CHANGED
@@ -227,12 +227,14 @@ export declare interface SuperAgentSDK {
227
227
  /** 响应中断事件(返回 SSE 流,后端继续推送后续事件);signal 供调用方中断续流 */
228
228
  respondInterrupt(interruptId: string, sessionId: string, response: InterruptResponse, onMessage?: (event: ChatEvent) => void, onError?: (error: Error) => void, signal?: AbortSignal): Promise<void>;
229
229
  setToken(token: string): void;
230
- /** 消息反馈(赞/踩),POST /chat/messages/{messageId}/feedback */
230
+ /** 消息反馈(赞/踩),POST /chat/messages/{messageId}/feedback。
231
+ * messageId = 消息列表的 UIMessage.messageId(后端 conversation_messages.message_id,
232
+ * langchain uuid),不是渲染 key id;流式消息取自 done/stop 事件的 messageId。 */
231
233
  feedback(messageId: string, type: "like" | "dislike", options?: {
232
234
  reason?: number;
233
235
  remark?: string;
234
236
  }): Promise<void>;
235
- /** 取消消息反馈,DELETE /chat/messages/{messageId}/feedback */
237
+ /** 取消消息反馈,DELETE /chat/messages/{messageId}/feedback(messageId 同上) */
236
238
  cancelFeedback(messageId: string): Promise<void>;
237
239
  /** 获取当前 bot 绑定的 skill 列表,GET /chat/bots/{botCode}/skills(含归属与可选性) */
238
240
  listSkills(): Promise<SkillInfo[]>;
@@ -245,8 +247,15 @@ export declare interface UIMessage {
245
247
  role: "user" | "assistant";
246
248
  parts: MessagePart[];
247
249
  timestamp: number;
250
+ /** 后端消息标识(conversation_messages.message_id,langchain 原始 message id uuid):
251
+ * feedback / cancelFeedback 按它定位消息(不是表主键 id)。来源二选一:
252
+ * 历史加载取消息列表的 messageId;流式消息取 done/stop 帧的 messageId。 */
253
+ messageId?: string;
248
254
  roundId?: string;
249
255
  artifacts?: Artifact[];
256
+ /** 用户消息原文(含技能 "/code" 前缀;parts 文本展示 "/技能名" 版本时两者不同)。
257
+ * regenerate 原样重发用;历史加载从后端 metadata.raw_message 还原。 */
258
+ rawContent?: string;
250
259
  }
251
260
 
252
261
  export { }