@blade-hq/agent-client 2610.0.0-beta.70 → 2610.0.0-beta.71

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.
@@ -204,6 +204,32 @@ export interface SessionTurnsPage {
204
204
  nextBefore: string | null;
205
205
  currentMode: "planning" | "executing";
206
206
  }
207
+ /** `getSessionTurnsPage` 的取数参数:向后翻页(before)或从某条发言定位(fromEntryId)。 */
208
+ export interface SessionTurnsQuery {
209
+ limit?: number;
210
+ before?: string;
211
+ /**
212
+ * 从这条用户发言开始、一直到最新。服务端按当前分支校验它,命中不了不会回空页
213
+ * (`entry_not_found` / `entry_not_in_branch`),窗口首条就是这条发言,它的
214
+ * `nextBefore` 可以继续当 `before` 往上翻。
215
+ */
216
+ fromEntryId?: string;
217
+ }
218
+ /**
219
+ * 服务端明确说这条发言不在当前分支上(`entry_not_found` / `entry_not_in_branch`),
220
+ * 和"这次没取到"(网络 / 5xx / 鉴权)分开:前者说明这个定位目标已经没了,后者只说明这次失败。
221
+ */
222
+ export declare function isEntryGoneError(error: unknown): boolean;
223
+ /** 侧栏「消息历史」的一条:只有 id、标题和时间,没有消息体。 */
224
+ export interface SessionTurnIndexItem {
225
+ entryId: string;
226
+ preview: string;
227
+ createdAt: string | null;
228
+ }
229
+ export interface SessionTurnIndex {
230
+ sessionId: string;
231
+ items: SessionTurnIndexItem[];
232
+ }
207
233
  export interface HistoricalCommand {
208
234
  deliveryId: string;
209
235
  toolCallId?: string;
@@ -407,10 +433,14 @@ export declare class SessionsResource {
407
433
  getSharedSession(token: string): Promise<TurnProjection[]>;
408
434
  getSessionTasks(sessionId: string): Promise<Task[]>;
409
435
  getSessionTurns(sessionId: string): Promise<TurnProjection[]>;
410
- getSessionTurnsPage(sessionId: string, options?: {
411
- limit?: number;
412
- before?: string;
413
- }): Promise<SessionTurnsPage>;
436
+ getSessionTurnsPage(sessionId: string, options?: SessionTurnsQuery, init?: RequestInit): Promise<SessionTurnsPage>;
437
+ /**
438
+ * 当前分支上可导航的用户发言目录(消息导航侧栏)。
439
+ *
440
+ * 只回 id、标题和时间:侧栏要列的是**整条会话**的发言,而窗口外的发言 id 只能
441
+ * 从服务端拿;消息体仍然走 `/turns`。
442
+ */
443
+ getSessionTurnIndex(sessionId: string): Promise<SessionTurnIndex>;
414
444
  getMcpAppContext(sessionId: string, sourceId: string, init?: RequestInit): Promise<McpAppContextState>;
415
445
  updateMcpAppContext(sessionId: string, sourceId: string, body: McpAppContextUpdate, init?: RequestInit): Promise<{
416
446
  status: "accepted";
@@ -5,6 +5,14 @@ export declare function normalizeMessageContent(content: unknown): MessageConten
5
5
  export declare function getTextContent(content: MessageContent): string;
6
6
  export declare function isSystemReminderText(text: string): boolean;
7
7
  export declare function isLegacyForkContextText(text: string): boolean;
8
+ /**
9
+ * 平台自己写进去、不该露给用户的内部提示。
10
+ *
11
+ * 服务端的消息导航目录有一份同名同语义的 Python 实现
12
+ * (`server/.../routes/sessions.py` 的 `_is_hidden_internal_message`):客户端靠它决定
13
+ * 渲染不渲染,服务端靠它决定进不进目录。改这里必须同时改那边,否则目录会列出没有对应
14
+ * 行的死条目,或者把内部提示原文当标题露出去。
15
+ */
8
16
  export declare function isHiddenInternalMessage(message: Pick<ChatMessage, "role" | "content">, options?: {
9
17
  includeLegacyForkContext?: boolean;
10
18
  }): boolean;
@@ -4,7 +4,7 @@ import type { PatchEnvelope, TurnProjection } from "../schemas/projection";
4
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
- import type { AppCliAttachment, AppCliDefinition, FileEntry, HistoricalCommand, SessionTurnsPage } from "../resources/sessions";
7
+ import type { AppCliAttachment, AppCliDefinition, FileEntry, HistoricalCommand, SessionTurnIndex, SessionTurnIndexItem, SessionTurnsPage, SessionTurnsQuery } from "../resources/sessions";
8
8
  import { type QueueOperationResult } from "./queue";
9
9
  import { type ConnectionStatus, type SessionState } from "./state";
10
10
  /** SessionHub 注入给 AgentSession 的运行时依赖(socket 收发 + REST 补数)。 */
@@ -12,7 +12,8 @@ export interface SessionRuntime {
12
12
  emitEvent(event: string, data: unknown): void;
13
13
  emitWithAck(event: string, data: unknown, timeoutMs: number): Promise<Record<string, unknown> | undefined>;
14
14
  ensureConnected(): void;
15
- fetchTurnsPage(sessionId: string, before?: string): Promise<SessionTurnsPage>;
15
+ fetchTurnsPage(sessionId: string, query?: SessionTurnsQuery, init?: RequestInit): Promise<SessionTurnsPage>;
16
+ fetchTurnIndex(sessionId: string): Promise<SessionTurnIndex>;
16
17
  fetchCommands(sessionId: string): Promise<HistoricalCommand[]>;
17
18
  /** 会话详情,目前只用来取回放状态。 */
18
19
  fetchSessionInfo(sessionId: string): Promise<{
@@ -54,7 +55,7 @@ export interface SendOptions {
54
55
  deprecate_entry_ids: string[];
55
56
  };
56
57
  replayDecision?: "keep_replay" | "continue_replay";
57
- /** 用户 @ 的知识库 id:后端先用原话在这些库里预检索,本轮 kb_search 也默认限定在这些库。 */
58
+ /** 用户显式选择的知识库 id;后端将元信息作为 once Context 提供给模型。 */
58
59
  kbIds?: number[];
59
60
  /**
60
61
  * 声明"会话在跑就把这条消息放进等待队列"。默认不排队、运行中直接报错:
@@ -86,6 +87,10 @@ export declare class AgentSession {
86
87
  private subscriptionQueue;
87
88
  private replaceQueue;
88
89
  private timelineEpoch;
90
+ /** 定位请求的流水号:被后一次选择取代的那次定位不再提交窗口(见 locateEntry)。 */
91
+ private locateToken;
92
+ /** 在途那次定位的请求句柄。**只**服务定位:权威刷新不共用它(见 cancelPendingLocate)。 */
93
+ private locateAbort;
89
94
  private pagingGeneration;
90
95
  private liveRevision;
91
96
  private modeRevision;
@@ -114,7 +119,16 @@ export declare class AgentSession {
114
119
  private readonly seenToolCallIds;
115
120
  private readonly finishedToolCallIds;
116
121
  private readonly emittedMessageTurnIds;
117
- constructor(sessionId: string, runtime: SessionRuntime, connection: ConnectionStatus);
122
+ constructor(sessionId: string, runtime: SessionRuntime, connection: ConnectionStatus, options?: {
123
+ staticHistory?: boolean;
124
+ });
125
+ /**
126
+ * 静态历史(分享页 / `fromTurns`):没有目录接口,也**没有**"目录还没到位"这个中间态。
127
+ *
128
+ * 宿主据此决定要不要拿已加载窗口当兜底条目——真实会话在 timeline 被重写后,窗口里还是
129
+ * 旧分支的发言,拿它兜底会把已经失效的 entry id 重新摆到轨道上,点了必然找不到。
130
+ */
131
+ readonly isStatic: boolean;
118
132
  /** 从一份静态 turn 快照构造只展示历史的会话(例如公开分享页)。 */
119
133
  static fromTurns(sessionId: string, turns: TurnProjection[]): AgentSession;
120
134
  /** 返回当前会话快照。引用稳定:状态未变化时返回同一对象。 */
@@ -124,6 +138,36 @@ export declare class AgentSession {
124
138
  loadOlderHistory(options?: {
125
139
  beforeCommit?: () => void;
126
140
  }): Promise<void>;
141
+ /**
142
+ * 定位到一条窗口外的历史发言:请服务端返回"从这条发言到最新"的窗口并整窗替换。
143
+ *
144
+ * 返回 false 表示这次定位没有落地(请求失败,或期间 timeline 被重写、会话已释放),
145
+ * 当前窗口保持不变,调用方可以原样重试。已加载的发言不要走这里——宿主直接滚动,
146
+ * 一次网络请求都不该发。
147
+ */
148
+ locateEntry(entryId: string): Promise<boolean>;
149
+ /**
150
+ * 取消在途定位:用户改选了另一条发言(哪怕那条已经加载、不需要请求),
151
+ * 先前那次定位既不该再落地,也不该继续占着替换队列——排队中的下一次定位
152
+ * 不然要等它跑完(用户看到的是"点了新目标一直转圈")。
153
+ *
154
+ * **只**中止定位自己的请求:权威刷新(运行结束 / 重连补数)不共用这个 controller,
155
+ * 否则"运行刚结束时点一下侧栏"就会把终态对账一起中止,流式与历史对不上。
156
+ */
157
+ cancelPendingLocate(): void;
158
+ /**
159
+ * timeline 被整体改写(rewind / checkout / 释放):推进纪元,并把在途定位请求一并中止
160
+ * ——它已经属于旧 timeline,却还占着替换队列,会让改写后的权威窗口排在后面等它跑完。
161
+ * 作废号仍然保留:中止只是让它更早结束。
162
+ */
163
+ private invalidateTimeline;
164
+ /**
165
+ * 拉取当前分支的用户发言目录(消息导航侧栏用)。
166
+ *
167
+ * 不在这里缓存:什么时候该刷新只有调用方知道(会话切换、历史被替换、新发言),
168
+ * 缓存只会让旧条目在 rewind 之后继续可点。
169
+ */
170
+ loadTurnIndex(): Promise<SessionTurnIndexItem[]>;
127
171
  /** 订阅状态变化。返回取消订阅函数。 */
128
172
  subscribe(listener: () => void): () => void;
129
173
  private setState;
@@ -289,6 +333,15 @@ export declare class AgentSession {
289
333
  private deliverCommand;
290
334
  private deliverCommandNow;
291
335
  private notifySandboxOom;
336
+ /**
337
+ * 权威刷新(运行结束 / 重连补数):**按当前窗口第一条发言取窗口**,不再另记"用户想看哪段"。
338
+ *
339
+ * 窗口本身就是"用户在看哪段":首屏就是最新一页,向上翻页 / 定位之后首条就是用户滚到的位置。
340
+ * 直接拿 `from_entry_id = 当前窗口第一条 turn_id` 去取,运行结束、重连补数、翻页之后的对账
341
+ * 是同一条规则,不需要意图、锚点、已落地锚点这些状态;窗口首条已经不在分支上(404 / 409)时
342
+ * 回落到最新一页。
343
+ */
344
+ private refreshAuthoritativeHistory;
292
345
  private replaceFromHistory;
293
346
  private invalidateOlderPaging;
294
347
  private beginCommandRecovery;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blade-hq/agent-client",
3
- "version": "2610.0.0-beta.70",
3
+ "version": "2610.0.0-beta.71",
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
- 共 223 个公开声明。
6
+ 共 244 个公开声明。
7
7
 
8
8
  ## `acceptedPostChatFollowupCompletesLatestRun` (function)
9
9
 
@@ -71,6 +71,7 @@ toolCallId: string
71
71
  ```ts
72
72
  attach: (label: string, data: unknown) => void
73
73
  attachApp: (options: AttachAppOptions) => Promise<AppCliAttachment | null>
74
+ cancelPendingLocate: () => void
74
75
  cancelQueuedMessage: (itemId: string, expectedVersion?: number) => Promise<QueueOperationResult>
75
76
  compact: () => Promise<Record<string, unknown>>
76
77
  countFiles: (dirPath?: string) => Promise<number>
@@ -82,8 +83,11 @@ getState: () => SessionState
82
83
  hasOlderHistory: boolean
83
84
  insertText: (text: string) => void
84
85
  isDisposed: boolean
86
+ isStatic: boolean
85
87
  listDir: (dirPath?: string) => Promise<FileEntry[]>
86
88
  loadOlderHistory: (options?: { beforeCommit?: () => void; }) => Promise<void>
89
+ loadTurnIndex: () => Promise<SessionTurnIndexItem[]>
90
+ locateEntry: (entryId: string) => Promise<boolean>
87
91
  off: <K extends keyof AgentSessionEvents>(name: K, handler: (event: AgentSessionEvents[K]) => void) => void
88
92
  on: <K extends keyof AgentSessionEvents>(name: K, handler: (event: AgentSessionEvents[K]) => void) => () => void
89
93
  onCommand: (action: string, handler: CommandHandler) => () => void
@@ -341,6 +345,13 @@ canEditQueuedMessage: (item: QueuedMessage) => boolean
341
345
  canToggleComputer: (computer: SessionComputer) => boolean
342
346
  ```
343
347
 
348
+ ## `ChatEnd` (interface)
349
+
350
+ ```ts
351
+ duration_ms: number
352
+ status: string
353
+ ```
354
+
344
355
  ## `chatErrorForDisplay` (function)
345
356
 
346
357
  ```ts
@@ -508,6 +519,13 @@ tool_name: string | null | undefined
508
519
  type: "text" | "thinking" | "tool_use" | "tool_result" | "tool_ui" | "tool_bridge" | "system_notification" | "mode_change" | "plan_status" | "ask_user_answer"
509
520
  ```
510
521
 
522
+ ## `ContentDelta` (interface)
523
+
524
+ ```ts
525
+ content: string
526
+ loop_name: string | undefined
527
+ ```
528
+
511
529
  ## `contentPreview` (function)
512
530
 
513
531
  ```ts
@@ -840,6 +858,12 @@ direction: "host-to-agent"
840
858
  payload: unknown
841
859
  ```
842
860
 
861
+ ## `inferToolStatus` (function)
862
+
863
+ ```ts
864
+ inferToolStatus: (resultStr: string) => "done" | "error" | "cancelled"
865
+ ```
866
+
843
867
  ## `InlineToolUiCardEntry` (interface)
844
868
 
845
869
  ```ts
@@ -860,6 +884,12 @@ isAppDevToolUiCard: (card: ToolUiCard, isAppDev: boolean) => boolean
860
884
  isCommandEnvelope: (value: unknown) => value is CommandEnvelope
861
885
  ```
862
886
 
887
+ ## `isEntryGoneError` (function)
888
+
889
+ ```ts
890
+ isEntryGoneError: (error: unknown) => boolean
891
+ ```
892
+
863
893
  ## `isHiddenInternalMessage` (function)
864
894
 
865
895
  ```ts
@@ -925,6 +955,16 @@ byTurnId: ReadonlyMap<string, number>
925
955
  current: number
926
956
  ```
927
957
 
958
+ ## `LlmResponseDone` (interface)
959
+
960
+ ```ts
961
+ content: string | null | undefined
962
+ loop_name: string | undefined
963
+ reasoning: string | null | undefined
964
+ role: string
965
+ tool_calls: { id: string; function: { name: string; arguments: string; }; }[] | undefined
966
+ ```
967
+
928
968
  ## `loadPlatformEndpoints` (function)
929
969
 
930
970
  ```ts
@@ -1102,6 +1142,14 @@ sequence: number
1102
1142
  turn_id: string
1103
1143
  ```
1104
1144
 
1145
+ ## `PendingQuestionRef` (interface)
1146
+
1147
+ ```ts
1148
+ child_loop_name: string
1149
+ child_tool_call_id: string
1150
+ description: string | null | undefined
1151
+ ```
1152
+
1105
1153
  ## `PlatformEndpoints` (interface)
1106
1154
 
1107
1155
  ```ts
@@ -1204,6 +1252,21 @@ title: string
1204
1252
  version: number
1205
1253
  ```
1206
1254
 
1255
+ ## `PrimarySkillStageSpec` (interface)
1256
+
1257
+ ```ts
1258
+ id: string
1259
+ name: string
1260
+ steps: PrimarySkillStepSpec[]
1261
+ ```
1262
+
1263
+ ## `PrimarySkillStepSpec` (interface)
1264
+
1265
+ ```ts
1266
+ label: string
1267
+ n: number
1268
+ ```
1269
+
1207
1270
  ## `ProvidersResponse` (interface)
1208
1271
 
1209
1272
  ```ts
@@ -1390,6 +1453,17 @@ result: unknown
1390
1453
  sessionId: string
1391
1454
  ```
1392
1455
 
1456
+ ## `RunTiming` (interface)
1457
+
1458
+ ```ts
1459
+ duration_ms: number | null | undefined
1460
+ loop_id: string
1461
+ run_id: string
1462
+ scope: "chat" | "subagent"
1463
+ started_at: string | null | undefined
1464
+ status: "completed" | "paused" | "failed" | "cancelled" | "incomplete"
1465
+ ```
1466
+
1393
1467
  ## `RunTrace` (interface)
1394
1468
 
1395
1469
  ```ts
@@ -1691,6 +1765,13 @@ revision: number
1691
1765
  session_id: string
1692
1766
  ```
1693
1767
 
1768
+ ## `SessionSearchMatch` (interface)
1769
+
1770
+ ```ts
1771
+ field: "title" | "content"
1772
+ snippet: { role: string; text: string; } | null
1773
+ ```
1774
+
1694
1775
  ## `SessionSetupError` (class)
1695
1776
 
1696
1777
  ```ts
@@ -1739,8 +1820,9 @@ getSessionHistory: (sessionId: string, init?: RequestInit) => Promise<SessionHis
1739
1820
  getSessionPluginConfig: (sessionId: string, name: string, init?: RequestInit) => Promise<{ plugin: string; config: SessionPluginConfigState; }>
1740
1821
  getSessionTasks: (sessionId: string) => Promise<Task[]>
1741
1822
  getSessionTurnCommands: (sessionId: string) => Promise<HistoricalCommand[]>
1823
+ getSessionTurnIndex: (sessionId: string) => Promise<SessionTurnIndex>
1742
1824
  getSessionTurns: (sessionId: string) => Promise<TurnProjection[]>
1743
- getSessionTurnsPage: (sessionId: string, options?: { limit?: number; before?: string; }) => Promise<SessionTurnsPage>
1825
+ getSessionTurnsPage: (sessionId: string, options?: SessionTurnsQuery, init?: RequestInit) => Promise<SessionTurnsPage>
1744
1826
  getSharedSession: (token: string) => Promise<TurnProjection[]>
1745
1827
  importSession: (file: File, name?: string, solutionOverride?: string | null | ImportSessionOptions) => Promise<{ session_id: string; }>
1746
1828
  listBackgroundTasks: (sessionId: string, init?: RequestInit) => Promise<BackgroundTask[]>
@@ -1808,6 +1890,28 @@ SessionStatus = type(
1808
1890
  )
1809
1891
  ```
1810
1892
 
1893
+ ## `SessionStatusEvent` (interface)
1894
+
1895
+ ```ts
1896
+ session_id: string
1897
+ status: string
1898
+ ```
1899
+
1900
+ ## `SessionTurnIndex` (interface)
1901
+
1902
+ ```ts
1903
+ items: SessionTurnIndexItem[]
1904
+ sessionId: string
1905
+ ```
1906
+
1907
+ ## `SessionTurnIndexItem` (interface)
1908
+
1909
+ ```ts
1910
+ createdAt: string | null
1911
+ entryId: string
1912
+ preview: string
1913
+ ```
1914
+
1811
1915
  ## `SessionTurnsPage` (interface)
1812
1916
 
1813
1917
  ```ts
@@ -1816,6 +1920,14 @@ nextBefore: string | null
1816
1920
  turns: TurnProjection[]
1817
1921
  ```
1818
1922
 
1923
+ ## `SessionTurnsQuery` (interface)
1924
+
1925
+ ```ts
1926
+ before: string | undefined
1927
+ fromEntryId: string | undefined
1928
+ limit: number | undefined
1929
+ ```
1930
+
1819
1931
  ## `ShareLinkResult` (interface)
1820
1932
 
1821
1933
  ```ts
@@ -1855,6 +1967,12 @@ files: TextFile[]
1855
1967
  name: string
1856
1968
  ```
1857
1969
 
1970
+ ## `SkillEditorTemplateId` (type)
1971
+
1972
+ ```ts
1973
+ export type SkillEditorTemplateId = "skill_editor"
1974
+ ```
1975
+
1858
1976
  ## `SkillMentionAvailability` (interface)
1859
1977
 
1860
1978
  ```ts
@@ -1938,6 +2056,12 @@ export type SolutionRef = ExistingSolutionRef | PreparedSolutionAsset
1938
2056
  sortComputers: (computers: SessionComputer[]) => SessionComputer[]
1939
2057
  ```
1940
2058
 
2059
+ ## `SystemError` (interface)
2060
+
2061
+ ```ts
2062
+ message: string
2063
+ ```
2064
+
1941
2065
  ## `Task` (type)
1942
2066
 
1943
2067
  ```ts
@@ -1998,6 +2122,25 @@ action: string
1998
2122
  payload: unknown
1999
2123
  ```
2000
2124
 
2125
+ ## `ToolCallArgumentsDelta` (interface)
2126
+
2127
+ ```ts
2128
+ arguments_delta: string
2129
+ function: { name: string; }
2130
+ id: string
2131
+ index: number
2132
+ loop_name: string | undefined
2133
+ ```
2134
+
2135
+ ## `ToolCallCreated` (interface)
2136
+
2137
+ ```ts
2138
+ function: { name: string; arguments: string; }
2139
+ id: string
2140
+ index: number
2141
+ loop_name: string | undefined
2142
+ ```
2143
+
2001
2144
  ## `ToolCallInfo` (interface)
2002
2145
 
2003
2146
  ```ts
@@ -2011,6 +2154,40 @@ result: unknown
2011
2154
  status: "done" | "error" | "cancelled" | "awaiting_answer" | "pending" | undefined
2012
2155
  ```
2013
2156
 
2157
+ ## `ToolCallProjection` (interface)
2158
+
2159
+ ```ts
2160
+ arguments: string
2161
+ display_name: string
2162
+ duration_ms: number | null | undefined
2163
+ id: string
2164
+ pending_question_ref: PendingQuestionRef | null | undefined
2165
+ ran_in_parallel: boolean | undefined
2166
+ result: unknown
2167
+ started_at: string | null | undefined
2168
+ status: string
2169
+ subagent_runs: RunTiming[] | undefined
2170
+ tool_name: string
2171
+ ```
2172
+
2173
+ ## `ToolResultDelta` (interface)
2174
+
2175
+ ```ts
2176
+ content: string
2177
+ loop_name: string | undefined
2178
+ stream: "stdout" | "stderr" | undefined
2179
+ tool_call_id: string
2180
+ ```
2181
+
2182
+ ## `ToolResultDone` (interface)
2183
+
2184
+ ```ts
2185
+ content: string
2186
+ function: { name: string; }
2187
+ loop_name: string | undefined
2188
+ tool_call_id: string
2189
+ ```
2190
+
2014
2191
  ## `ToolUiCard` (interface)
2015
2192
 
2016
2193
  ```ts