@blade-hq/agent-client 2608.0.2 → 2608.0.3

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.
@@ -16,6 +16,24 @@ export interface ProvidersResponse {
16
16
  }>;
17
17
  password_enabled: boolean;
18
18
  }
19
+ export interface ExchangeCodeParams {
20
+ /** 授权回调页 postMessage 回来的一次性 code。 */
21
+ code: string;
22
+ /** 发起授权时用的 state,必须原样传回。 */
23
+ state: string;
24
+ /** 发起授权的页面 origin,要和 authorize 时传的 `client_origin` 完全一致。 */
25
+ clientOrigin: string;
26
+ }
27
+ export interface ExchangeCodeResult {
28
+ access_token: string;
29
+ token_type: string;
30
+ user: {
31
+ id: string;
32
+ username: string;
33
+ display_name: string;
34
+ avatar_url: string | null;
35
+ };
36
+ }
19
37
  export declare class AuthResource {
20
38
  private client;
21
39
  constructor(client: BladeClient);
@@ -24,6 +42,14 @@ export declare class AuthResource {
24
42
  * 自动取得 PAT 并热挂载到当前 client。等价于 client.login()。
25
43
  */
26
44
  login(options?: LoginOptions): Promise<LoginResult>;
45
+ /**
46
+ * 用一次性 code 换 PAT。给**服务端**用:浏览器把 code 交给你自己的后端,
47
+ * 后端换到的 PAT 不进浏览器。浏览器里直接用 `login()` 就够了。
48
+ *
49
+ * 服务端调用时会自己补上 `Origin` 头(浏览器会自动带,服务端不会,缺了
50
+ * 后端报 `missing_request_origin`)。
51
+ */
52
+ exchangeCode(params: ExchangeCodeParams): Promise<ExchangeCodeResult>;
27
53
  /** 清除 login() 存储的令牌。 */
28
54
  logoutToken(): void;
29
55
  getProviders(): Promise<ProvidersResponse>;
@@ -6,6 +6,12 @@ export interface ModelOption {
6
6
  export interface ModelCatalog {
7
7
  default: string;
8
8
  models: ModelOption[];
9
+ /**
10
+ * 平台默认模型服务的 OpenAI 兼容地址(Server ≥ 提供 `baseUrl` 的版本才有,否则为空)。
11
+ * 自建应用可以带用户的 PAT 直接调它,不必让用户自己填地址——网关端口各部署不同,
12
+ * 推算不出来。
13
+ */
14
+ baseUrl?: string;
9
15
  }
10
16
  /** Server 可供当前用户选择的模型目录。 */
11
17
  export declare class ModelsResource {
@@ -1,6 +1,6 @@
1
1
  import type { BackgroundTask, BackgroundTaskStopResult } from "../schemas/background";
2
2
  import type { TurnProjection } from "../schemas/projection";
3
- import type { PublishedSolutionRef, SessionDetail, SessionInfo, TemplateId } from "../schemas/session";
3
+ import type { PublishedSolutionRef, ReplayPreview, ReplaySpeed, SessionDetail, SessionInfo, TemplateId } from "../schemas/session";
4
4
  import type { Task } from "../schemas/task";
5
5
  import type { BladeClient, UploadProgress } from "../blade-client";
6
6
  import type { AgentSession } from "../session/agent-session";
@@ -203,15 +203,17 @@ export declare class SessionsResource {
203
203
  }): Promise<SessionDetail>;
204
204
  setSessionEnv(sessionId: string, env: Record<string, string>): Promise<SessionDetail>;
205
205
  pinSession(sessionId: string, pinned: boolean): Promise<SessionInfo>;
206
- startReplaySession(sourceSessionId: string, speed?: 1 | 2 | 5): Promise<{
206
+ startReplaySession(sourceSessionId: string, speed?: ReplaySpeed): Promise<{
207
207
  session_id: string;
208
208
  }>;
209
209
  updateReplaySession(sessionId: string, payload: {
210
- speed?: 1 | 2 | 5;
210
+ speed?: ReplaySpeed;
211
211
  status?: "autonomous";
212
212
  }): Promise<{
213
213
  replay_state: SessionInfo["replay_state"];
214
214
  }>;
215
+ /** 查询会话能否作为回放来源;不支持时 reason 可直接展示,用来提前禁用入口。 */
216
+ getReplayPreview(sessionId: string): Promise<ReplayPreview>;
215
217
  updateSharing(sessionId: string, shared: boolean): Promise<{
216
218
  shared: boolean;
217
219
  }>;
@@ -12,11 +12,21 @@ export declare function buildMessageContent(text: string, attachments: Array<{
12
12
  mimeType?: string;
13
13
  }>): MessageContent;
14
14
  export declare function contentPreview(content: MessageContent, maxLen?: number): string;
15
+ /** `/` 选中的技能当前处于什么状态,决定智能体要不要先装、先加载。 */
16
+ export interface SkillMentionAvailability {
17
+ /** 本地已有(内置 / 技能目录 / 会话已加载),直接可用。 */
18
+ local?: boolean;
19
+ /** Blade Hub 上该账号是否已安装。本地技能恒为 true。 */
20
+ installed?: boolean;
21
+ }
15
22
  /**
16
23
  * Transform a skill mention into a natural language skill invocation.
17
24
  * Strips the `<skill>name</skill>` tag from the raw input and prepends the instruction.
25
+ *
26
+ * Hub 技能装没装、加载没加载,用户不需要知道,但智能体需要——所以把状态翻译
27
+ * 成它能直接照做的 CLI 步骤。不传 availability 时按本地技能处理,与旧行为一致。
18
28
  */
19
- export declare function transformSlashCommand(skillName: string, rawInput: string): string;
29
+ export declare function transformSlashCommand(skillName: string, rawInput: string, { local, installed }?: SkillMentionAvailability): string;
20
30
  export interface ParsedTextAttachment {
21
31
  name: string;
22
32
  uploadedPath?: string;
@@ -12,14 +12,31 @@ export type PublishedSolutionRef = {
12
12
  org: string;
13
13
  name: string;
14
14
  };
15
+ /** 回放时录制内容的播放倍速。 */
16
+ export type ReplaySpeed = 1 | 2 | 5;
17
+ /**
18
+ * 新建回放会话时的默认倍速。
19
+ *
20
+ * 所有创建入口都用它——曾经侧栏走 API 默认 5x、设置菜单初始化成 1x,
21
+ * 同一个源对话从不同入口开出来速度不一样。
22
+ */
23
+ export declare const DEFAULT_REPLAY_SPEED: ReplaySpeed;
15
24
  export interface ReplayState {
16
25
  source_session_id?: string;
17
26
  status?: "replay" | "autonomous";
18
- speed?: 1 | 2 | 5;
27
+ speed?: ReplaySpeed;
19
28
  next_source_entry_id?: string | null;
20
29
  ended_at?: string | null;
21
30
  autonomous_reason?: string | null;
22
31
  }
32
+ /** 某个会话能否作为回放来源。 */
33
+ export interface ReplayPreview {
34
+ session_id: string;
35
+ intent?: string | null;
36
+ supported: boolean;
37
+ /** supported 为 false 时给出的原因,可直接展示给用户。 */
38
+ reason?: string | null;
39
+ }
23
40
  export interface SessionPortMapping {
24
41
  container_port: number;
25
42
  host_port: number;
@@ -1,7 +1,7 @@
1
1
  import { type RawEvent } from "../shared/projection";
2
2
  import type { MessageContent } from "../schemas/message";
3
3
  import type { PatchEnvelope, TurnProjection } from "../schemas/projection";
4
- import type { SessionStatus } from "../schemas/session";
4
+ import type { ReplaySpeed, ReplayState, SessionStatus } from "../schemas/session";
5
5
  import { type CommandHandler } from "../commands/registry";
6
6
  import { type AgentSessionEvents } from "./events";
7
7
  import type { AppCliAttachment, AppCliDefinition, FileEntry } from "../resources/sessions";
@@ -12,6 +12,15 @@ export interface SessionRuntime {
12
12
  emitWithAck(event: string, data: unknown, timeoutMs: number): Promise<Record<string, unknown> | undefined>;
13
13
  ensureConnected(): void;
14
14
  fetchTurns(sessionId: string): Promise<TurnProjection[]>;
15
+ /** 会话详情,目前只用来取回放状态。 */
16
+ fetchSessionInfo(sessionId: string): Promise<{
17
+ replay_state?: ReplayState | null;
18
+ viewer_role?: "owner" | "viewer";
19
+ }>;
20
+ updateReplay(sessionId: string, payload: {
21
+ speed?: ReplaySpeed;
22
+ status?: "autonomous";
23
+ }): Promise<ReplayState | null>;
15
24
  listDir(sessionId: string, dirPath: string): Promise<FileEntry[]>;
16
25
  countFiles(sessionId: string, dirPath?: string): Promise<number>;
17
26
  downloadFile(sessionId: string, filePath: string, downloadName?: string): Promise<void>;
@@ -65,6 +74,7 @@ export declare class AgentSession {
65
74
  private patchFlushCancel;
66
75
  private joined;
67
76
  private joinPending;
77
+ private replayQueue;
68
78
  private pendingReplayMessage;
69
79
  private pendingReplayMode;
70
80
  private recentChatEndAt;
@@ -139,6 +149,16 @@ export declare class AgentSession {
139
149
  _rejoinAfterReconnect(): Promise<void>;
140
150
  /** @internal 首次连接:加载历史 + 加入房间。 */
141
151
  _bootstrap(): Promise<void>;
152
+ /** 改回放是 owner 专属(服务端 PATCH 走 _get_owned_session)。 */
153
+ private get canControlReplay();
154
+ /** 拉一次会话详情,填回放状态和只读身份;失败按非回放会话处理,不挡启动。 */
155
+ private syncReplayFromSession;
156
+ /** 调整回放倍速;不是回放会话、或只读身份时什么都不做。 */
157
+ setReplaySpeed(speed: ReplaySpeed): Promise<void>;
158
+ /** 退出回放,之后的对话交给真实模型运行;不是回放会话、或只读身份时什么都不做。 */
159
+ exitReplay(): Promise<void>;
160
+ /** 把一次回放控制请求排进队列;前一个完成后才发出,响应直接安装。 */
161
+ private applyReplayControl;
142
162
  /** @internal */
143
163
  _handleTurnStart(turn: TurnProjection): void;
144
164
  /** @internal */
@@ -1,6 +1,6 @@
1
1
  import type { ChatMessage, CompactionInfo, MessageContent } from "../schemas/message";
2
2
  import type { ContentBlock, PatchEnvelope, TurnProjection } from "../schemas/projection";
3
- import type { SessionStatus } from "../schemas/session";
3
+ import type { ReplaySpeed, ReplayState, SessionStatus } from "../schemas/session";
4
4
  /** 一次 AskUserQuestion 的用户作答(选项选择 + 自定义输入)。 */
5
5
  export interface AskUserAnswerData {
6
6
  selections: Record<number, number[]>;
@@ -39,7 +39,20 @@ export interface SessionState {
39
39
  askAnswers: Record<string, AskUserAnswerData>;
40
40
  agentLoops: Record<string, AgentLoopInfo>;
41
41
  activeCompaction: ActiveCompactionState | null;
42
+ /** 回放(演示 / 彩排)状态;不是回放会话时为 null。 */
43
+ replay: ReplaySnapshot | null;
44
+ /** 当前身份对这个会话的权限;"viewer" 表示只读(分享链接打开的)。 */
45
+ viewerRole: "owner" | "viewer" | null;
42
46
  }
47
+ /** 回放会话的快照视图,由服务端的 replay_state 归一化而来。 */
48
+ export interface ReplaySnapshot {
49
+ /** 仍在按录制内容走;转自主运行后为 false。 */
50
+ isReplay: boolean;
51
+ speed: ReplaySpeed;
52
+ sourceSessionId: string | null;
53
+ }
54
+ /** 把服务端的 replay_state 归一化成快照;不是回放会话时返回 null。 */
55
+ export declare function toReplaySnapshot(raw: ReplayState | null | undefined): ReplaySnapshot | null;
43
56
  export declare function createInitialSessionState(sessionId: string): SessionState;
44
57
  export declare function extractModeFromBlocks(blocks: ContentBlock[]): "planning" | "executing" | null;
45
58
  /**
@@ -26,6 +26,13 @@ export declare function sourceLoopFor(loopId: string, loopDescriptions: Map<stri
26
26
  loop_name: string;
27
27
  description: string;
28
28
  } | null;
29
+ /** 本轮交付给用户的成果:工作区里的文件,或可以打开的网址。 */
30
+ export interface FinalArtifact {
31
+ kind: "file" | "link";
32
+ /** file 是文件路径(相对工作目录或容器内绝对路径);link 是 http/https 网址。 */
33
+ target: string;
34
+ label: string;
35
+ }
29
36
  /**
30
37
  * Shared by the streaming and history channels — both must decide "is this
31
38
  * follow-up showable" identically. Returns null when there is nothing to show.
@@ -34,6 +41,7 @@ export declare function normalizePostChatFollowup(data: Record<string, unknown>,
34
41
  assistant_entry_id: string;
35
42
  recaption: string;
36
43
  suggestions: string[];
44
+ final_artifacts: FinalArtifact[];
37
45
  } | null;
38
46
  export declare function normalizeChildPause(pausePayload: Record<string, unknown>): {
39
47
  pauseToolData: Record<string, unknown>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blade-hq/agent-client",
3
- "version": "2608.0.2",
3
+ "version": "2608.0.3",
4
4
  "description": "Blade Agent 框架无关客户端:会话实时状态机、REST 通道、弹窗登录、页面协作。浏览器与 Node.js 通用。",
5
5
  "repository": {
6
6
  "type": "git",
package/public-api.md CHANGED
@@ -3,7 +3,7 @@
3
3
  > 本文件由 `scripts/public-api-report.mjs` 生成,请勿手改。
4
4
  > 公共面变更时重新生成本报告,并同步更新 README 对应章节——CI 会校验两者。
5
5
 
6
- 共 117 个公开声明。
6
+ 共 126 个公开声明。
7
7
 
8
8
  ## `ActiveCompactionState` (interface)
9
9
 
@@ -42,6 +42,7 @@ compact: () => Promise<Record<string, unknown>>
42
42
  countFiles: (dirPath?: string) => Promise<number>
43
43
  dispose: () => void
44
44
  downloadFile: (filePath: string, downloadName?: string) => Promise<void>
45
+ exitReplay: () => Promise<void>
45
46
  getState: () => SessionState
46
47
  insertText: (text: string) => void
47
48
  isDisposed: boolean
@@ -51,6 +52,7 @@ on: <K extends keyof AgentSessionEvents>(name: K, handler: (event: AgentSessionE
51
52
  onCommand: (action: string, handler: CommandHandler) => () => void
52
53
  send: (content: MessageContent, options?: SendOptions) => Promise<boolean>
53
54
  sessionId: string
55
+ setReplaySpeed: (speed: ReplaySpeed) => Promise<void>
54
56
  stop: () => Promise<Record<string, unknown>>
55
57
  subscribe: (listener: () => void) => () => void
56
58
  ```
@@ -147,6 +149,7 @@ getContext: () => Record<string, unknown> | Promise<Record<string, unknown>>
147
149
  ## `AuthResource` (class)
148
150
 
149
151
  ```ts
152
+ exchangeCode: (params: ExchangeCodeParams) => Promise<ExchangeCodeResult>
150
153
  getMe: () => Promise<UserInfo>
151
154
  getProviders: () => Promise<ProvidersResponse>
152
155
  login: (options?: LoginOptions) => Promise<LoginResult>
@@ -376,6 +379,12 @@ path: string | undefined
376
379
  token: string | (() => string | null | undefined) | undefined
377
380
  ```
378
381
 
382
+ ## `DEFAULT_REPLAY_SPEED` (const)
383
+
384
+ ```ts
385
+ DEFAULT_REPLAY_SPEED: ReplaySpeed
386
+ ```
387
+
379
388
  ## `EmbeddedChat` (interface)
380
389
 
381
390
  ```ts
@@ -393,6 +402,22 @@ allowedOrigins: string[]
393
402
  iframe: HTMLIFrameElement | undefined
394
403
  ```
395
404
 
405
+ ## `ExchangeCodeParams` (interface)
406
+
407
+ ```ts
408
+ clientOrigin: string
409
+ code: string
410
+ state: string
411
+ ```
412
+
413
+ ## `ExchangeCodeResult` (interface)
414
+
415
+ ```ts
416
+ access_token: string
417
+ token_type: string
418
+ user: { id: string; username: string; display_name: string; avatar_url: string | null; }
419
+ ```
420
+
396
421
  ## `ExistingSolutionRef` (interface)
397
422
 
398
423
  ```ts
@@ -571,6 +596,7 @@ export type ModeId = "planning" | "executing"
571
596
  ## `ModelCatalog` (interface)
572
597
 
573
598
  ```ts
599
+ baseUrl: string | undefined
574
600
  default: string
575
601
  models: ModelOption[]
576
602
  ```
@@ -689,6 +715,40 @@ payload: Record<string, unknown>
689
715
  type: string
690
716
  ```
691
717
 
718
+ ## `ReplayPreview` (interface)
719
+
720
+ ```ts
721
+ intent: string | null | undefined
722
+ reason: string | null | undefined
723
+ session_id: string
724
+ supported: boolean
725
+ ```
726
+
727
+ ## `ReplaySnapshot` (interface)
728
+
729
+ ```ts
730
+ isReplay: boolean
731
+ sourceSessionId: string | null
732
+ speed: ReplaySpeed
733
+ ```
734
+
735
+ ## `ReplaySpeed` (type)
736
+
737
+ ```ts
738
+ export type ReplaySpeed = 1 | 2 | 5
739
+ ```
740
+
741
+ ## `ReplayState` (interface)
742
+
743
+ ```ts
744
+ autonomous_reason: string | null | undefined
745
+ ended_at: string | null | undefined
746
+ next_source_entry_id: string | null | undefined
747
+ source_session_id: string | undefined
748
+ speed: ReplaySpeed | undefined
749
+ status: "replay" | "autonomous" | undefined
750
+ ```
751
+
692
752
  ## `RunOptions` (interface)
693
753
 
694
754
  ```ts
@@ -925,6 +985,7 @@ downloadFile: (sessionId: string, filePath: string, downloadName?: string) => Pr
925
985
  exportSession: (sessionId: string) => Promise<void>
926
986
  getBackgroundTask: (sessionId: string, taskId: string, tail?: number, init?: RequestInit) => Promise<BackgroundTask>
927
987
  getDownloadDirUrl: (sessionId: string, dirPath: string) => string
988
+ getReplayPreview: (sessionId: string) => Promise<ReplayPreview>
928
989
  getSession: (sessionId: string, init?: RequestInit) => Promise<SessionDetail>
929
990
  getSessionCheckpoints: (sessionId: string, init?: RequestInit) => Promise<{ nodes: CheckpointNode[]; leaf_id: string | null; }>
930
991
  getSessionContextStats: (sessionId: string, init?: RequestInit) => Promise<SessionContextStats>
@@ -946,12 +1007,12 @@ revokeShare: (sessionId: string, token: string) => Promise<{ revoked: boolean; }
946
1007
  rewindSession: (sessionId: string, checkpointId: string) => Promise<{ id: string; content: string; }>
947
1008
  setSessionEnv: (sessionId: string, env: Record<string, string>) => Promise<SessionDetail>
948
1009
  shareFile: (sessionId: string, sourcePath: string, linkName?: string, shareFolder?: string) => Promise<{ path: string; target: string; }>
949
- startReplaySession: (sourceSessionId: string, speed?: 1 | 2 | 5) => Promise<{ session_id: string; }>
1010
+ startReplaySession: (sourceSessionId: string, speed?: ReplaySpeed) => Promise<{ session_id: string; }>
950
1011
  stopBackgroundTask: (sessionId: string, taskId: string) => Promise<BackgroundTaskStopResult>
951
1012
  switchBranch: (sessionId: string, checkpointId: string) => Promise<{ id: string; leaf_id: string; }>
952
1013
  tokenizeMessages: (messages: Array<Record<string, unknown>>, options?: { model?: string; add_generation_prompt?: boolean; enable_thinking?: boolean | null; tools?: Array<Record<string, unknown>>; }) => Promise<TokenizeResult>
953
1014
  tokenizePrompt: (prompt: string, model?: string) => Promise<TokenizeResult>
954
- updateReplaySession: (sessionId: string, payload: { speed?: 1 | 2 | 5; status?: "autonomous"; }) => Promise<{ replay_state: SessionInfo["replay_state"]; }>
1015
+ updateReplaySession: (sessionId: string, payload: { speed?: ReplaySpeed; status?: "autonomous"; }) => Promise<{ replay_state: SessionInfo["replay_state"]; }>
955
1016
  updateSession: (sessionId: string, payload: { intent?: string; }) => Promise<SessionDetail>
956
1017
  updateSessionMemory: (sessionId: string, memoryEnabled: boolean) => Promise<{ memory_enabled: boolean; }>
957
1018
  updateSharing: (sessionId: string, shared: boolean) => Promise<{ shared: boolean; }>
@@ -970,9 +1031,11 @@ errorMessage: string | null
970
1031
  isStreaming: boolean
971
1032
  messages: ChatMessage[]
972
1033
  mode: "planning" | "executing" | null
1034
+ replay: ReplaySnapshot | null
973
1035
  sessionId: string
974
1036
  status: "completed" | "failed" | "interrupted" | "running" | "created" | "waiting_for_input" | null
975
1037
  turns: TurnProjection[]
1038
+ viewerRole: "owner" | "viewer" | null
976
1039
  ```
977
1040
 
978
1041
  ## `SessionStatus` (type)
@@ -998,6 +1061,13 @@ files: TextFile[]
998
1061
  name: string
999
1062
  ```
1000
1063
 
1064
+ ## `SkillMentionAvailability` (interface)
1065
+
1066
+ ```ts
1067
+ installed: boolean | undefined
1068
+ local: boolean | undefined
1069
+ ```
1070
+
1001
1071
  ## `Solution` (interface)
1002
1072
 
1003
1073
  ```ts
@@ -1141,10 +1211,16 @@ result: unknown
1141
1211
  status: "done" | "error" | "cancelled" | "awaiting_answer" | "pending" | undefined
1142
1212
  ```
1143
1213
 
1214
+ ## `toReplaySnapshot` (function)
1215
+
1216
+ ```ts
1217
+ toReplaySnapshot: (raw: ReplayState | null | undefined) => ReplaySnapshot | null
1218
+ ```
1219
+
1144
1220
  ## `transformSlashCommand` (function)
1145
1221
 
1146
1222
  ```ts
1147
- transformSlashCommand: (skillName: string, rawInput: string) => string
1223
+ transformSlashCommand: (skillName: string, rawInput: string, { local, installed }?: SkillMentionAvailability) => string
1148
1224
  ```
1149
1225
 
1150
1226
  ## `TurnProjection` (interface)