super-agent-sdk 1.0.18 → 1.0.20

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
@@ -65,7 +65,7 @@ import { createSuperAgent } from "super-agent-sdk";
65
65
  import { mount } from "super-agent-sdk/widget";
66
66
 
67
67
  const sdk = createSuperAgent({
68
- botId: 1,
68
+ botCode: "tech-researcher",
69
69
  tokenGateway: "/api/gateway",
70
70
  });
71
71
  // Token 自动获取,无需手动设置
@@ -85,19 +85,22 @@ function createSuperAgent(config: SDKConfig): SuperAgentSDK;
85
85
 
86
86
  ```ts
87
87
  export interface SDKConfig {
88
- botId: number; // Bot ID(必填)
89
- tokenGateway: string; // Token 网关前缀(必填,不带 host),如 "/api/gateway";token URL = {origin}{tokenGateway}/v2/token/generate
88
+ botCode: string; // Bot 业务编码(必填,bots.code,跨环境稳定)
89
+ tokenGateway: string; // Token 网关前缀(必填,不带 host),如 "/api/gateway";token URL = {origin}{tokenGateway}/superagent/v2/token/generate
90
90
  baseUrl?: string; // 业务接口前缀(可选,默认 "/api/agent/runtime/v1"),不带 host
91
91
  appId?: string; // 可选,不传则从 token 接口响应自动获取
92
92
  token?: string; // 可选,不传则自动调 token 接口获取
93
+ tenantId?: number; // 可选:token 网关需租户上下文时传(如 Playground 走 admin 网关),fetchToken 带 X-Tenant-Id 头透传;自建公开网关不传
94
+ loginUrl?: string; // 可选:cookie 失效重登的兜底跳转页(agent 含 COOKIE 工具时 runtime 校验 cookie,失效 401 cookie_expired)
95
+ onAuthExpired?: (ctx: { loginUrl?: string; sessionId?: string; botCode: string }) => void; // 可选:完全自定义重登(如带 returnUrl 的 SSO),提供则 SDK 不自行跳转
93
96
  }
94
97
  ```
95
98
 
96
- 只需提供 `botId` 与 `tokenGateway` 即可。`baseUrl` 默认为 `/api/agent/runtime/v1`,`appId` 从 token 接口响应中自动获取。SDK 不要求在创建时传入 `token`——组件挂载后会自动调用 `sdk.getToken()` 获取 token 并内部保存,无需手动设置。
99
+ 只需提供 `botCode` 与 `tokenGateway` 即可。`baseUrl` 默认为 `/api/agent/runtime/v1`,`appId` 从 token 接口响应中自动获取。SDK 不要求在创建时传入 `token`——组件挂载后会自动调用 `sdk.getToken()` 获取 token 并内部保存,无需手动设置。`getToken()` 自带并发去重:多 widget 共享同一 sdk 实例时,并发取 token 合并为一次签发请求;业务接口 401 时自动清缓存重签并重试一次。
97
100
 
98
101
  ```ts
99
102
  const sdk = createSuperAgent({
100
- botId: 1,
103
+ botCode: "tech-researcher",
101
104
  tokenGateway: "/api/gateway",
102
105
  });
103
106
  ```
@@ -105,11 +108,11 @@ const sdk = createSuperAgent({
105
108
  凭证获取流程:
106
109
 
107
110
  ```
108
- createSuperAgent({ botId, tokenGateway })
111
+ createSuperAgent({ botCode, tokenGateway })
109
112
  ↓
110
113
  Widget 挂载时自动调用 sdk.getToken()
111
114
  ↓
112
- POST {origin}{tokenGateway}/v2/token/generate(body: { botId })
115
+ POST {origin}{tokenGateway}/superagent/v2/token/generate(body: { botCode })
113
116
  ↓
114
117
  后端返回 { token, appId }
115
118
  ↓
@@ -120,20 +123,22 @@ ready
120
123
 
121
124
  `tokenGateway` 用于拼接 token 接口路径,`appId` 自动从 token 响应获取(也可手动传入覆盖)。
122
125
 
126
+ **cookie 失效重登**(agent 含 COOKIE 工具时):runtime 入口校验浏览器 cookie,失效返回 401 `{code:"cookie_expired", data:{login_url, session_id}}`。SDK 暂存 pending 消息(含 botCode)后跳转重登(优先响应里的 `login_url`,其次配置的 `loginUrl`;提供 `onAuthExpired` 则完全交宿主处理);重登回来后 widget 恢复同一会话(botCode 定位)并自动重发暂存消息。
127
+
123
128
  ---
124
129
 
125
130
  ## 5. API 参考
126
131
 
127
132
  > **字段命名**:后端接口返回 camelCase 字段,SDK 直接使用,无需转换。
128
133
  >
129
- > - 后端返回 `sessionId`、`botId`、`createTime`、`updateTime`
134
+ > - 后端返回 `sessionId`、`createTime`、`updateTime`(bot 外部标识统一 botCode,SDK 不消费内部 id)
130
135
  > - SDK 所有公开 API 均使用 camelCase
131
136
 
132
137
  ### 5.1 SDK 实例
133
138
 
134
139
  ```ts
135
140
  export interface SuperAgentSDK {
136
- readonly botId: number; // 当前 Bot ID
141
+ readonly botCode: string; // 当前 Bot Code(bots.code,跨环境稳定)
137
142
  createSession(): Promise<string>;
138
143
  chat(options: ChatOptions): AbortController;
139
144
  listConversations(
@@ -166,7 +171,7 @@ export interface SuperAgentSDK {
166
171
 
167
172
  创建新会话,返回 `sessionId`。聊天前必须先创建会话。
168
173
 
169
- - SDK 调用 `POST /chat/sessions`,请求体为 `{ botId }`
174
+ - SDK 调用 `POST /chat/sessions`,请求体为 `{ botCode }`
170
175
  - 后端返回 `{ sessionId: "..." }`
171
176
  - SDK 直接返回 `sessionId` 字符串
172
177
 
@@ -178,7 +183,7 @@ const sessionId = await sdk.createSession();
178
183
 
179
184
  流式聊天。**`sessionId` 为必填**,必须先调用 `createSession()` 获取。返回 `AbortController`,可随时中断。
180
185
 
181
- - SDK 发送 `POST /chat`,请求体为 `{ botId, sessionId, message, stream }`
186
+ - SDK 发送 `POST /chat`,请求体为 `{ botCode, sessionId, message, stream }`
182
187
  - 后端 SSE 在 `done` 事件中返回 `sessionId`
183
188
 
184
189
  ```ts
@@ -282,7 +287,6 @@ export interface ListConversationsResult {
282
287
 
283
288
  export interface Conversation {
284
289
  sessionId: string;
285
- botId: number;
286
290
  title: string | null;
287
291
  createTime: string;
288
292
  updateTime: string;
@@ -293,8 +297,8 @@ export interface Conversation {
293
297
  const { items, total } = await sdk.listConversations({ page: 1, size: 20 });
294
298
  ```
295
299
 
296
- - SDK 调用 `GET /chat/conversations?botId=1&page=1&size=20`
297
- - 后端返回的每一项为 `{ sessionId, botId, title, createTime, updateTime }`
300
+ - SDK 调用 `GET /chat/conversations?botCode=tech-researcher&page=1&size=20`
301
+ - 后端返回的每一项为 `{ sessionId, title, createTime, updateTime }`(bot 外部标识统一 botCode,SDK 不暴露内部 id)
298
302
 
299
303
  ### 5.5 getMessages()
300
304
 
@@ -323,7 +327,7 @@ sdk.getToken(): Promise<string>
323
327
 
324
328
  自动获取并保存访问 token:
325
329
 
326
- - SDK 调用 `POST {origin}{tokenGateway}/v2/token/generate`,请求体 `{ botId }`
330
+ - SDK 调用 `POST {origin}{tokenGateway}/superagent/v2/token/generate`,请求体 `{ botCode }`
327
331
  - 后端返回 `{ token, appId }`
328
332
  - SDK 自动将 token + appId 保存在内部
329
333
  - Widget 在挂载时自动调用此方法 —— 通常无需手动调用
@@ -433,15 +437,15 @@ SDK 方法 → 后端接口的完整映射:
433
437
 
434
438
  | SDK 方法 | HTTP 请求 | 请求体 | 后端返回 |
435
439
  | --------------------- | -------------------------------------------- | --------------------------------------- | ----------------------------------------------- |
436
- | `getToken()` | `POST {gateway}/v2/token/generate` | `{ botId }` | `{ token, appId }` |
437
- | `createSession()` | `POST /chat/sessions` | `{ botId }` | `{ sessionId }` |
438
- | `chat()` | `POST /chat` | `{ botId, sessionId, message, stream, attachments? }` | SSE 流,`done`/`stop` 事件含 `sessionId` |
439
- | `listConversations()` | `GET /chat/conversations` | 查询参数 `botId`、`page`、`size` | `{ items: [{ sessionId, botId, ... }], total }` |
440
+ | `getToken()` | `POST {gateway}/superagent/v2/token/generate` | `{ botCode }` | `{ token, appId }` |
441
+ | `createSession()` | `POST /chat/sessions` | `{ botCode }` | `{ sessionId }` |
442
+ | `chat()` | `POST /chat` | `{ botCode, sessionId, message, stream, attachments? }` | SSE 流,`done`/`stop` 事件含 `sessionId` |
443
+ | `listConversations()` | `GET /chat/conversations` | 查询参数 `botCode`、`page`、`size` | `{ items: [{ sessionId, ... }], total }`(按 botCode 过滤) |
440
444
  | `feedback()` | `POST /chat/messages/{messageId}/feedback` | `{ type, reason?, remark? }` | `null` |
441
445
  | `cancelFeedback()` | `DELETE /chat/messages/{messageId}/feedback` | 无 body | `null` |
442
446
  | `respondInterrupt()` | `POST /chat/interrupt/{interruptId}/respond` | `{ sessionId, action, value? }` | SSE 流(后续事件) |
443
447
  | `stopGeneration()` | `POST /chat/stop` | `{ sessionId }` | `{ stopped: "pending", sessionId }` |
444
- | `listSkills()` | `GET /chat/bots/{botId}/skills` | — | `[{ code, name, displayName, description }]` |
448
+ | `listSkills()` | `GET /chat/bots/{botCode}/skills` | — | `[{ code, name, displayName, description }]` |
445
449
 
446
450
  ---
447
451
 
@@ -506,7 +510,7 @@ import { createSuperAgent } from "super-agent-sdk";
506
510
  import { mount } from "super-agent-sdk/widget";
507
511
 
508
512
  const sdk = createSuperAgent({
509
- botId: 1,
513
+ botCode: "tech-researcher",
510
514
  tokenGateway: "/api/gateway",
511
515
  });
512
516
 
@@ -1196,7 +1200,7 @@ import type {
1196
1200
  } from "super-agent-sdk/widget";
1197
1201
 
1198
1202
  const sdk = createSuperAgent({
1199
- botId: 1,
1203
+ botCode: "tech-researcher",
1200
1204
  tokenGateway: "/api/gateway",
1201
1205
  });
1202
1206
  sdk.setToken("demo_token");
@@ -1418,7 +1422,7 @@ await sdk.deleteConversation(items[0].sessionId);
1418
1422
  - **新建**:点击「新会话」清空当前消息,下次发送时自动调用 `createSession()` 创建新会话。
1419
1423
  - **重命名**:`fullpage` 侧边栏或自定义 `ThreadList` 中调用 `renameConversation`。
1420
1424
  - **删除**:悬停会话项后点击删除按钮。
1421
- - **本地持久化**:最近一次活跃会话写入 `localStorage`,键为 `sa_active_conversation_{botId}`(按 Bot 隔离,切换 Bot 后互不串扰)。
1425
+ - **本地持久化**:最近一次活跃会话写入 `localStorage`,键为 `sa_active_conversation_{botCode}`(按 Bot 隔离,切换 Bot 后互不串扰)。
1422
1426
 
1423
1427
  ---
1424
1428
 
@@ -1490,7 +1494,7 @@ ac.abort();
1490
1494
 
1491
1495
  页面刷新或组件重新挂载时,会话状态自动恢复:
1492
1496
 
1493
- 1. 挂载时从 `localStorage` 读取上次活跃会话 ID(键 `sa_active_conversation_{botId}`)。
1497
+ 1. 挂载时从 `localStorage` 读取上次活跃会话 ID(键 `sa_active_conversation_{botCode}`)。
1494
1498
  2. 若该会话仍在列表中,自动调用 `getMessages` 拉取历史消息并渲染。
1495
1499
  3. 若存储的会话已不存在(被删除),则自动清空并回退到「新会话」。
1496
1500
 
@@ -1696,7 +1700,7 @@ sdk.chat({
1696
1700
  import { createSuperAgent } from "super-agent-sdk";
1697
1701
 
1698
1702
  const sdk = createSuperAgent({
1699
- botId: 1,
1703
+ botCode: "tech-researcher",
1700
1704
  tokenGateway: "/api/gateway",
1701
1705
  });
1702
1706
  sdk.setToken("<TOKEN>");
@@ -1796,7 +1800,7 @@ function MyChat({ sdk }: { sdk: SuperAgentSDK }) {
1796
1800
 
1797
1801
  ### 13.3 Token 续期
1798
1802
 
1799
- 请求返回 `401` 时,SDK 自动重新调用 `POST {tokenGateway}/v2/token/generate` 获取新 token。
1803
+ 请求返回 `401` 时,SDK 自动重新调用 `POST {tokenGateway}/superagent/v2/token/generate` 获取新 token。
1800
1804
 
1801
1805
  ### 13.4 停止与取消请求
1802
1806
 
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}`}/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(`
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
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 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(`
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 E(r){return(await r.post("/chat/sessions",{botId:r.getBotId()})).sessionId}function O(r){return{sessionId:r.threadId??r.sessionId,botId:r.botId,title:r.title,createTime:r.createTime,updateTime:r.updateTime}}async function v(r,e){const i=await r.get("/chat/conversations",{botId:r.getBotId(),page:(e==null?void 0:e.page)??1,size:(e==null?void 0:e.size)??20});return{...i,items:i.items.map(O)}}async function x(r,e,i){await r.patch(`/chat/conversations/${e}`,{title:i})}async function P(r,e){await r.del(`/chat/conversations/${e}`)}async function C(r,e){const i=await r.get(`/chat/conversations/${e}/messages`);return U(i)}function T(){return`r_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,10)}`}function U(r){var d;const e=r.length>0&&Array.isArray((d=r[0])==null?void 0:d.data),i=[];if(e)for(const t of r)i.push({roundId:t.roundId??T(),artifacts:Array.isArray(t.artifacts)&&t.artifacts.length?t.artifacts:void 0,items:Array.isArray(t.data)?t.data:[]});else i.push({roundId:T(),items:r});const n=[];for(const t of i){const s=N(t.items);for(const o of s)o.roundId=t.roundId;if(t.artifacts){const o=s.findLast(a=>a.role==="assistant");o&&(o.artifacts=t.artifacts)}n.push(...s)}return n}function N(r){const e=[...r].sort((s,o)=>{const a=new Date(s.createTime??0).getTime()||0,c=new Date(o.createTime??0).getTime()||0;return a!==c?a-c:(s.seq??0)-(o.seq??0)}),i=new Map;for(const s of e)s.role==="tool"&&s.toolCallId&&i.set(s.toolCallId,s.content||"");const n=new Set,d=[],t=(s,o,a)=>{const c=d[d.length-1];(c==null?void 0:c.role)==="assistant"?(c.parts.push(...s),c.id=o):d.push({id:o,role:"assistant",parts:[...s],timestamp:a})};for(const s of e){if(s.role==="system")continue;const o=String(s.id??s.messageId??`msg_${Date.now()}`),a=new Date(s.createTime??"").getTime()||Date.now();if(s.role==="human"){const c=(s.attachments??[]).map(l=>({type:"attachment",attachment:{nosKey:l.nosKey??l.attachmentId??"",filename:l.filename??"file",size:l.size??void 0,mime:l.mime??void 0,url:l.url??void 0}}));d.push({id:o,role:"user",parts:[...c,{type:"text",content:u(s.content)}],timestamp:a});continue}if(s.role==="ai"){const c=M(s,i,n);c.length>0&&t(c,o,a);continue}if(s.role==="tool"){if(s.toolCallId&&n.has(s.toolCallId))continue;t([j(s)],o,a)}}return d}function M(r,e,i){const n=[];r.reasoning&&n.push({type:"thinking",content:r.reasoning}),r.content&&n.push({type:"text",content:u(r.content)});for(const d of r.toolCalls??[])d.is_interrupt??d.isInterrupt?(i.add(d.id),n.push(D(d,e))):n.push(q(d));return n}function D(r,e){const i=e.has(r.id),n=typeof r.args=="object"?r.args:{};return{type:"interrupt",interrupt:{interruptId:r.id??"",interruptType:n.interruptType??"input",content:n.content??"",options:n.options,placeholder:n.placeholder,inputType:n.inputType,maxLength:n.maxLength,required:n.required,fields:n.fields,metadata:n.metadata},resolved:i,response:i?{action:"submit",value:J(e.get(r.id))}:void 0}}function q(r){let e;try{e=typeof r.args=="string"?r.args:JSON.stringify(r.args??{})}catch{e=String(r.args??"{}")}return{type:"tool_call",toolName:r.name??"",toolCallId:r.id??"",args:e}}function j(r){var i,n,d,t;const e=Array.isArray(r.artifacts)?r.artifacts:void 0;return{type:"tool_result",toolName:r.toolName??"",toolCallId:r.toolCallId??"",content:u(r.content),artifacts:e,renderMode:r.renderMode??((i=r.metadata)==null?void 0:i.renderMode)??((n=r.metadata)==null?void 0:n.render_mode),html:r.html??((d=r.metadata)==null?void 0:d.html),markdown:r.markdown??((t=r.metadata)==null?void 0:t.markdown)}}function J(r){if(r!=null)try{return JSON.parse(r)}catch{return r}}async function L(r,e,i,n,d,t,s){const o=await r.streamPost(`/chat/interrupt/${e}/respond`,{sessionId:i,action:n.action,value:n.value},s);if(!o.ok){const a=new Error(`HTTP ${o.status}`);throw t==null||t(a),a}d&&await b(o,a=>{a.type==="error"?t==null||t(new Error(a.content)):d(a)},a=>t==null?void 0:t(a))}async function G(r){return r.get(`/chat/bots/${r.getBotId()}/skills`)}async function R(r,e){await r.post("/chat/stop",{sessionId:e})}function B(r){const e=new A(r);return{botId:e.getBotId(),getToken:()=>e.fetchToken(),createSession:()=>E(e),chat:n=>$(e,n),listConversations:n=>v(e,n),renameConversation:(n,d)=>x(e,n,d),deleteConversation:n=>P(e,n),getMessages:n=>C(e,n),respondInterrupt:(n,d,t,s,o,a)=>L(e,n,d,t,s,o,a),setToken:n=>e.setToken(n),feedback:async(n,d,t)=>{const s={type:d};d==="dislike"&&((t==null?void 0:t.reason)!=null&&(s.reason=t.reason),t!=null&&t.remark&&(s.remark=t.remark)),await e.post(`/chat/messages/${n}/feedback`,s)},cancelFeedback:async n=>{await e.del(`/chat/messages/${n}/feedback`)},listSkills:()=>G(e),stopGeneration:n=>R(e,n)}}exports.createNosUploader=h.createNosUploader;exports.createSuperAgent=B;
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;
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;
@@ -61,7 +61,6 @@ export declare interface ChatOptions {
61
61
 
62
62
  export declare interface Conversation {
63
63
  sessionId: string;
64
- botId: number;
65
64
  title: string | null;
66
65
  createTime: string;
67
66
  updateTime: string;
@@ -180,16 +179,17 @@ export declare interface NosUploaderConfig {
180
179
  }
181
180
 
182
181
  export declare interface SDKConfig {
183
- botId: number;
182
+ botCode: string;
184
183
  tokenGateway: string;
185
184
  baseUrl?: string;
186
185
  appId?: string;
187
186
  token?: string;
187
+ tenantId?: number;
188
188
  loginUrl?: string;
189
189
  onAuthExpired?: (ctx: {
190
190
  loginUrl?: string;
191
191
  sessionId?: string;
192
- botId: number;
192
+ botCode: string;
193
193
  }) => void;
194
194
  }
195
195
 
@@ -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
- /** 当前 Bot ID(只读) */
205
- readonly botId: number;
206
- /** 获取 token(调用 POST {tokenGateway}/v2/token/generate),自动设置内部凭证 */
214
+ /** 当前 Bot Code(只读,bots.code,跨环境稳定) */
215
+ readonly botCode: string;
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/{botCode}/skills(含归属与可选性) */
226
237
  listSkills(): Promise<SkillInfo[]>;
227
238
  /** 停止生成(双信号:POST /chat/stop 广播 + abort SSE),半截回复保留 */
228
239
  stopGeneration(sessionId: string): Promise<void>;