super-agent-sdk 1.0.17 → 1.0.19
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 +11 -10
- package/dist/index.cjs +3 -3
- package/dist/index.d.ts +14 -3
- package/dist/index.mjs +45 -23
- package/dist/widget.cjs +81 -37
- package/dist/widget.d.ts +22 -7
- package/dist/widget.mjs +3250 -3100
- package/package.json +1 -1
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}/
|
|
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}/
|
|
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}/
|
|
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}/
|
|
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
|
|
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; //
|
|
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
|
-
|
|
|
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}/
|
|
1799
|
+
请求返回 `401` 时,SDK 自动重新调用 `POST {tokenGateway}/v2/token/generate` 获取新 token。
|
|
1799
1800
|
|
|
1800
1801
|
### 13.4 停止与取消请求
|
|
1801
1802
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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}`}/
|
|
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,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.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(){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}`}/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})();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 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
|
-
${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(`
|
|
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_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=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 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
|
|
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 P(r){return(await r.post("/chat/sessions",{botId:r.getBotId()})).sessionId}function v(r){return{sessionId:r.threadId??r.sessionId,botId:r.botId,title:r.title,createTime:r.createTime,updateTime:r.updateTime}}async function E(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(v)}}async function O(r,e,i){await r.patch(`/chat/conversations/${e}`,{title:i})}async function C(r,e){await r.del(`/chat/conversations/${e}`)}async function x(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:()=>P(e),chat:n=>$(e,n),listConversations:n=>E(e,n),renameConversation:(n,d)=>O(e,n,d),deleteConversation:n=>C(e,n),getMessages:n=>x(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: "session.start" | "user" | "thinking" | "ai" | "tool_call" | "tool_result" | "done" | "stop" | "error" | "interrupt";
|
|
27
|
+
type: "session.start" | "user" | "thinking" | "ai" | "tool_call" | "tool_delta" | "tool_result" | "done" | "stop" | "error" | "interrupt";
|
|
28
28
|
content: string;
|
|
29
29
|
toolName?: string;
|
|
30
30
|
toolCallId?: string;
|
|
@@ -198,12 +198,23 @@ declare interface SkillInfo {
|
|
|
198
198
|
name: string;
|
|
199
199
|
displayName: string | null;
|
|
200
200
|
description: string | null;
|
|
201
|
+
/** 归属:entry=入口 agent 自己的技能;member=Team 中某个成员的技能 */
|
|
202
|
+
owner: 'entry' | 'member';
|
|
203
|
+
/** owner=member 时该成员在 Team 内的 code(member_ref_code);entry 时为 null */
|
|
204
|
+
memberCode: string | null;
|
|
205
|
+
/** owner=member 时该成员的展示名;entry 时为 null */
|
|
206
|
+
memberName: string | null;
|
|
207
|
+
/** 能否通过斜杠命令点名(Pipeline 流水线模式下的成员技能为 false) */
|
|
208
|
+
selectable: boolean;
|
|
209
|
+
/** selectable=false 的原因,展示给用户;可选时为空 */
|
|
210
|
+
disabledReason: string | null;
|
|
201
211
|
}
|
|
202
212
|
|
|
203
213
|
export declare interface SuperAgentSDK {
|
|
204
214
|
/** 当前 Bot ID(只读) */
|
|
205
215
|
readonly botId: number;
|
|
206
|
-
/**
|
|
216
|
+
/** 确保持有 token:已持直接返回缓存;否则 POST {tokenGateway}/v2/token/generate 签发
|
|
217
|
+
*(多 widget 并发挂载合并为一次请求),自动设置内部凭证。401 重签走重试链路 */
|
|
207
218
|
getToken(): Promise<string>;
|
|
208
219
|
/** 创建新会话,返回 sessionId */
|
|
209
220
|
createSession(): Promise<string>;
|
|
@@ -222,7 +233,7 @@ export declare interface SuperAgentSDK {
|
|
|
222
233
|
}): Promise<void>;
|
|
223
234
|
/** 取消消息反馈,DELETE /chat/messages/{messageId}/feedback */
|
|
224
235
|
cancelFeedback(messageId: string): Promise<void>;
|
|
225
|
-
/** 获取当前 bot 绑定的 skill 列表,GET /chat/bots/{botId}/skills */
|
|
236
|
+
/** 获取当前 bot 绑定的 skill 列表,GET /chat/bots/{botId}/skills(含归属与可选性) */
|
|
226
237
|
listSkills(): Promise<SkillInfo[]>;
|
|
227
238
|
/** 停止生成(双信号:POST /chat/stop 广播 + abort SSE),半截回复保留 */
|
|
228
239
|
stopGeneration(sessionId: string): Promise<void>;
|
package/dist/index.mjs
CHANGED
|
@@ -15,7 +15,7 @@ function f(r) {
|
|
|
15
15
|
const A = "/api/agent/runtime/v1";
|
|
16
16
|
class $ {
|
|
17
17
|
constructor(e) {
|
|
18
|
-
this.refreshing = null;
|
|
18
|
+
this.refreshing = null, this.tokenPromise = null;
|
|
19
19
|
const i = e.baseUrl ?? A;
|
|
20
20
|
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;
|
|
21
21
|
}
|
|
@@ -32,20 +32,34 @@ class $ {
|
|
|
32
32
|
getOrigin() {
|
|
33
33
|
return typeof window < "u" ? window.location.origin : "";
|
|
34
34
|
}
|
|
35
|
-
/** POST {origin}{tokenGateway}/
|
|
35
|
+
/** POST {origin}{tokenGateway}/v2/token/generate — 获取 token + appId。
|
|
36
|
+
*
|
|
37
|
+
* 已持 token 直接返回缓存;并发调用凭 in-flight promise 合并为一次请求
|
|
38
|
+
* (多 widget 共享同一 sdk 时,各自 ChatProvider 挂载只打一次签发端点)。
|
|
39
|
+
* 401 强刷前须先清 this.token(见 handleTokenRefresh)。
|
|
40
|
+
*/
|
|
36
41
|
async fetchToken() {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
if (this.token) return this.token;
|
|
43
|
+
if (this.tokenPromise) return this.tokenPromise;
|
|
44
|
+
this.tokenPromise = (async () => {
|
|
45
|
+
const i = `${this.isAbsoluteGateway ? this.tokenGateway : `${this.getOrigin()}${this.tokenGateway}`}/v2/token/generate`, n = await fetch(i, {
|
|
46
|
+
method: "POST",
|
|
47
|
+
headers: { "Content-Type": "application/json" },
|
|
48
|
+
body: JSON.stringify({ botId: this.botId })
|
|
49
|
+
});
|
|
50
|
+
if (!n.ok)
|
|
51
|
+
throw new Error(`HTTP ${n.status}: ${n.statusText}`);
|
|
52
|
+
const d = await n.json();
|
|
53
|
+
if (d.code !== "200")
|
|
54
|
+
throw new Error(d.message || `API error: ${d.code}`);
|
|
55
|
+
const t = f(d.data);
|
|
56
|
+
return this.token = t.token, t.appId && !this.appId && (this.appId = t.appId), t.token;
|
|
57
|
+
})();
|
|
58
|
+
try {
|
|
59
|
+
return await this.tokenPromise;
|
|
60
|
+
} finally {
|
|
61
|
+
this.tokenPromise = null;
|
|
62
|
+
}
|
|
49
63
|
}
|
|
50
64
|
headers(e) {
|
|
51
65
|
return {
|
|
@@ -59,7 +73,7 @@ class $ {
|
|
|
59
73
|
if (this.refreshing)
|
|
60
74
|
return await this.refreshing, !0;
|
|
61
75
|
try {
|
|
62
|
-
return this.refreshing = (async () => {
|
|
76
|
+
return this.token = "", this.refreshing = (async () => {
|
|
63
77
|
await this.fetchToken();
|
|
64
78
|
})(), await this.refreshing, !0;
|
|
65
79
|
} catch {
|
|
@@ -206,6 +220,14 @@ ${a}` : a;
|
|
|
206
220
|
event: n,
|
|
207
221
|
id: i
|
|
208
222
|
};
|
|
223
|
+
case "tool_delta":
|
|
224
|
+
return {
|
|
225
|
+
type: "tool_delta",
|
|
226
|
+
content: typeof t.content == "string" ? t.content : "",
|
|
227
|
+
toolCallId: t.tool_call_id ?? t.toolCallId ?? "",
|
|
228
|
+
event: n,
|
|
229
|
+
id: i
|
|
230
|
+
};
|
|
209
231
|
case "tool_result": {
|
|
210
232
|
const o = s == null ? void 0 : s.result;
|
|
211
233
|
let a;
|
|
@@ -305,7 +327,7 @@ async function T(r, e, i) {
|
|
|
305
327
|
}
|
|
306
328
|
function _(r, e) {
|
|
307
329
|
var t;
|
|
308
|
-
const i = new AbortController(), n = e.signal ?
|
|
330
|
+
const i = new AbortController(), n = e.signal ? P(e.signal, i.signal) : i.signal, d = {
|
|
309
331
|
botId: r.getBotId(),
|
|
310
332
|
message: e.message,
|
|
311
333
|
sessionId: e.sessionId,
|
|
@@ -353,16 +375,16 @@ function _(r, e) {
|
|
|
353
375
|
(o = e.onError) == null || o.call(e, s instanceof Error ? s : new Error(String(s)));
|
|
354
376
|
}), i;
|
|
355
377
|
}
|
|
356
|
-
function
|
|
378
|
+
function P(r, e) {
|
|
357
379
|
const i = new AbortController(), n = () => i.abort();
|
|
358
380
|
return r.addEventListener("abort", n, { once: !0 }), e.addEventListener("abort", n, { once: !0 }), (r.aborted || e.aborted) && i.abort(), i.signal;
|
|
359
381
|
}
|
|
360
|
-
async function
|
|
382
|
+
async function x(r) {
|
|
361
383
|
return (await r.post("/chat/sessions", {
|
|
362
384
|
botId: r.getBotId()
|
|
363
385
|
})).sessionId;
|
|
364
386
|
}
|
|
365
|
-
function
|
|
387
|
+
function E(r) {
|
|
366
388
|
return {
|
|
367
389
|
// 后端返回 thread_id,toCamelCase 转为 threadId,映射为 sessionId
|
|
368
390
|
sessionId: r.threadId ?? r.sessionId,
|
|
@@ -380,13 +402,13 @@ async function v(r, e) {
|
|
|
380
402
|
});
|
|
381
403
|
return {
|
|
382
404
|
...i,
|
|
383
|
-
items: i.items.map(
|
|
405
|
+
items: i.items.map(E)
|
|
384
406
|
};
|
|
385
407
|
}
|
|
386
408
|
async function C(r, e, i) {
|
|
387
409
|
await r.patch(`/chat/conversations/${e}`, { title: i });
|
|
388
410
|
}
|
|
389
|
-
async function
|
|
411
|
+
async function O(r, e) {
|
|
390
412
|
await r.del(`/chat/conversations/${e}`);
|
|
391
413
|
}
|
|
392
414
|
async function U(r, e) {
|
|
@@ -559,11 +581,11 @@ function z(r) {
|
|
|
559
581
|
return {
|
|
560
582
|
botId: e.getBotId(),
|
|
561
583
|
getToken: () => e.fetchToken(),
|
|
562
|
-
createSession: () =>
|
|
584
|
+
createSession: () => x(e),
|
|
563
585
|
chat: (n) => _(e, n),
|
|
564
586
|
listConversations: (n) => v(e, n),
|
|
565
587
|
renameConversation: (n, d) => C(e, n, d),
|
|
566
|
-
deleteConversation: (n) =>
|
|
588
|
+
deleteConversation: (n) => O(e, n),
|
|
567
589
|
getMessages: (n) => U(e, n),
|
|
568
590
|
respondInterrupt: (n, d, t, s, o, a) => G(e, n, d, t, s, o, a),
|
|
569
591
|
setToken: (n) => e.setToken(n),
|