super-agent-sdk 1.0.17 → 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
  ↓
@@ -323,7 +323,7 @@ sdk.getToken(): Promise<string>
323
323
 
324
324
  自动获取并保存访问 token:
325
325
 
326
- - SDK 调用 `POST {origin}{tokenGateway}/v1/token`,请求体 `{ botId }`
326
+ - SDK 调用 `POST {origin}{tokenGateway}/v2/token/generate`,请求体 `{ botId }`
327
327
  - 后端返回 `{ token, appId }`
328
328
  - SDK 自动将 token + appId 保存在内部
329
329
  - Widget 在挂载时自动调用此方法 —— 通常无需手动调用
@@ -433,7 +433,7 @@ SDK 方法 → 后端接口的完整映射:
433
433
 
434
434
  | SDK 方法 | HTTP 请求 | 请求体 | 后端返回 |
435
435
  | --------------------- | -------------------------------------------- | --------------------------------------- | ----------------------------------------------- |
436
- | `getToken()` | `POST {gateway}/v1/token` | `{ botId }` | `{ token, appId }` |
436
+ | `getToken()` | `POST {gateway}/v2/token/generate` | `{ botId }` | `{ token, appId }` |
437
437
  | `createSession()` | `POST /chat/sessions` | `{ botId }` | `{ sessionId }` |
438
438
  | `chat()` | `POST /chat` | `{ botId, sessionId, message, stream, attachments? }` | SSE 流,`done`/`stop` 事件含 `sessionId` |
439
439
  | `listConversations()` | `GET /chat/conversations` | 查询参数 `botId`、`page`、`size` | `{ items: [{ sessionId, botId, ... }], total }` |
@@ -757,7 +757,7 @@ function MyTrigger({ isOpen, onClick, unreadCount }: TriggerProps) {
757
757
 
758
758
  floating 与 fullpage 模式均支持替换;`onToggleThreadList` 在 floating 下切换内嵌会话侧边栏、在 fullpage 下切换左侧边栏;开启 `artifactPreview` 后额外提供产物入口字段。
759
759
 
760
- > 注:fullpage 内置 Header 只有标题与产物入口(无关闭按钮);需要关闭入口时通过自定义 Header 的 `onClose` 自行渲染。floating 内置 Header 含历史/回首页/大窗/关闭按钮。
760
+ > 注:fullpage 内置 Header 有标题与产物入口(无关闭按钮);整屏容器态标题换成面板 `title`、并出现 home 返回入口,需要关闭入口时通过自定义 Header 的 `onClose` 自行渲染。floating 内置 Header 含历史/回首页/大窗/关闭按钮。
761
761
 
762
762
  ```ts
763
763
  export interface HeaderProps {
@@ -766,10 +766,11 @@ export interface HeaderProps {
766
766
  onToggleThreadList: () => void;
767
767
  isMaximized?: boolean; // floating:大窗状态
768
768
  onToggleMaximize?: () => void; // floating:大窗/小窗切换
769
- showHome?: boolean; // floating:聊天态显示回到首页
770
- onHome?: () => void; // floating:回到首页(新会话)
769
+ showHome?: boolean; // floating:聊天态显示回到首页;整屏容器态显示「返回聊天」
770
+ onHome?: () => void; // 回到首页(新会话);整屏容器态为 closePanel 返回聊天
771
771
  artifactCount?: number; // 会话产物数量(artifactPreview 开启时提供)
772
772
  onToggleArtifactDrawer?: () => void; // 打开/关闭产物预览抽屉
773
+ panelTitle?: string; // 整屏容器态:面板标题(内置 Header 居中显示;自定义 Header 据此自行渲染)
773
774
  }
774
775
  ```
775
776
 
@@ -1138,9 +1139,9 @@ mount("#app", {
1138
1139
  | 项 | 表现 |
1139
1140
  | --- | --- |
1140
1141
  | 呈现 | 替换「内容区 + 输入区」,Header 保留(小窗仍可拖拽);`link` 走 `window.open`,不占状态 |
1141
- | 标题栏 | 返回箭头 + `title`(可选);`Esc` 等价返回 |
1142
+ | 标题 | 无独立标题栏(纯白背景);`title` 传入时显示在 **Header 居中**(floating 内置 Header / fullpage 均适用,自定义 `slots.Header` 收 `panelTitle` 自行渲染) |
1143
+ | 退出 | Header 的 home 图标(tooltip「返回聊天」)/ 业务组件 `close()` / `Esc`;关闭聊天面板时一并清掉 |
1142
1144
  | 窗口几何 | 保持打开前窗态,小窗不自动升大窗;内容在容器内滚动(业务页不写滚动容器) |
1143
- | 关闭 | 返回 / `close()` / `Esc`;关闭聊天面板时一并清掉 |
1144
1145
  | 栈 | 单层不叠栈,容器内部导航由业务组件自己管 |
1145
1146
 
1146
1147
  注意:浮层组件渲染在 SDK 自己的 `createRoot` 树内,拿不到宿主的 React Context / Router。组件引用直接给,不需要注册表——类型即校验。
@@ -1795,7 +1796,7 @@ function MyChat({ sdk }: { sdk: SuperAgentSDK }) {
1795
1796
 
1796
1797
  ### 13.3 Token 续期
1797
1798
 
1798
- 请求返回 `401` 时,SDK 自动重新调用 `POST {tokenGateway}/v1/token` 获取新 token。
1799
+ 请求返回 `401` 时,SDK 自动重新调用 `POST {tokenGateway}/v2/token/generate` 获取新 token。
1799
1800
 
1800
1801
  ### 13.4 停止与取消请求
1801
1802
 
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
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}`}/v1/token`,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(`
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
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
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
 
package/dist/index.d.ts CHANGED
@@ -203,7 +203,7 @@ declare interface SkillInfo {
203
203
  export declare interface SuperAgentSDK {
204
204
  /** 当前 Bot ID(只读) */
205
205
  readonly botId: number;
206
- /** 获取 token(调用 POST {tokenGateway}/v1/token),自动设置内部凭证 */
206
+ /** 获取 token(调用 POST {tokenGateway}/v2/token/generate),自动设置内部凭证 */
207
207
  getToken(): Promise<string>;
208
208
  /** 创建新会话,返回 sessionId */
209
209
  createSession(): Promise<string>;
package/dist/index.mjs CHANGED
@@ -32,9 +32,9 @@ class $ {
32
32
  getOrigin() {
33
33
  return typeof window < "u" ? window.location.origin : "";
34
34
  }
35
- /** POST {origin}{tokenGateway}/v1/token — 获取 token + appId */
35
+ /** POST {origin}{tokenGateway}/v2/token/generate — 获取 token + appId */
36
36
  async fetchToken() {
37
- const i = `${this.isAbsoluteGateway ? this.tokenGateway : `${this.getOrigin()}${this.tokenGateway}`}/v1/token`, n = await fetch(i, {
37
+ const i = `${this.isAbsoluteGateway ? this.tokenGateway : `${this.getOrigin()}${this.tokenGateway}`}/v2/token/generate`, n = await fetch(i, {
38
38
  method: "POST",
39
39
  headers: { "Content-Type": "application/json" },
40
40
  body: JSON.stringify({ botId: this.botId })