@blade-hq/agent-client 2610.0.0-beta.9 → 2610.0.0-rc.0
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 +70 -5
- package/dist/blade-client.d.ts +2 -2
- package/dist/index.d.ts +9 -1
- package/dist/index.js +610 -98
- package/dist/index.js.map +1 -1
- package/dist/platform-endpoints.d.ts +14 -0
- package/dist/resources/computers.d.ts +63 -0
- package/dist/resources/models.d.ts +2 -0
- package/dist/resources/sessions.d.ts +3 -1
- package/dist/schemas/context.d.ts +49 -0
- package/dist/schemas/event.d.ts +9 -0
- package/dist/schemas/message-utils.d.ts +5 -1
- package/dist/schemas/message.d.ts +3 -0
- package/dist/schemas/projection.d.ts +12 -1
- package/dist/schemas/session.d.ts +3 -1
- package/dist/session/agent-session.d.ts +10 -2
- package/dist/session/events.d.ts +2 -0
- package/dist/session/hub.d.ts +8 -1
- package/dist/session/state.d.ts +3 -1
- package/dist/shared/projection/builder.d.ts +2 -0
- package/dist/shared/projection/context.d.ts +3 -0
- package/dist/shared/projection/history.d.ts +1 -0
- package/dist/shared/projection/index.d.ts +1 -0
- package/dist/types/socket-events.d.ts +13 -4
- package/package.json +1 -1
- package/public-api.md +214 -7
package/README.md
CHANGED
|
@@ -2,16 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
Blade Agent 的框架无关客户端。浏览器和 Node.js 都能用;用 Vue、Svelte 或自建 UI 的团队直接用这个包,React 团队一般用上层的 `@blade-hq/agent-react`。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
它做四件事:
|
|
6
6
|
|
|
7
7
|
1. **实时会话**(`AgentSession`):把 Socket.IO 协议、历史加载、流式合流、断线重连全部封装掉,你只面对"状态快照 + 动作 + 事件"。
|
|
8
8
|
2. **登录**:`client.auth.login()` 弹窗授权,用户点一下"许可授权"就拿到访问令牌,不用手工复制粘贴。
|
|
9
9
|
3. **REST**:类型化会话和模型目录(`client.sessions.*`、`client.models.list()`)。其他长尾接口对照 Swagger 用原生 `fetch` + `client.token` 调用。
|
|
10
|
+
4. **部署端点**:从同源 `config.json` 读取其他 Blade 服务的公开地址,不根据主机名和固定端口猜测拓扑。
|
|
10
11
|
|
|
11
12
|
```bash
|
|
12
13
|
npm install @blade-hq/agent-client
|
|
13
14
|
```
|
|
14
15
|
|
|
16
|
+
默认装到的是当前长期支持版(LTS),厂内离线交付按它开发。要跟两周一发的公网版本,改用 `@next`。
|
|
17
|
+
|
|
18
|
+
最稳妥的做法是先读目标 Server 的 `GET /api/version`,按返回的版本号在 `package.json` 里钉死——NPM 的 `latest` 不一定和目标环境跑的版本一致。
|
|
19
|
+
|
|
15
20
|
## 快速开始
|
|
16
21
|
|
|
17
22
|
```html
|
|
@@ -47,6 +52,27 @@ const client = new BladeClient({
|
|
|
47
52
|
})
|
|
48
53
|
```
|
|
49
54
|
|
|
55
|
+
## 部署端点
|
|
56
|
+
|
|
57
|
+
Blade 平台前端需要跳转其他服务时,读取当前 origin 的公开配置:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
import { loadPlatformEndpoints, resolveServiceUrl } from "@blade-hq/agent-client"
|
|
61
|
+
|
|
62
|
+
const endpoints = await loadPlatformEndpoints()
|
|
63
|
+
const hubUrl = resolveServiceUrl(endpoints, "hub", "/skills/42")
|
|
64
|
+
if (hubUrl) window.open(hubUrl)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`loadPlatformEndpoints()` 请求 `config.json`,超过 3 秒、网络失败或配置非法时返回空配置;
|
|
68
|
+
调用方应隐藏对应入口。文件只能放浏览器可访问的公开地址,不能写 Docker 服务名、令牌或
|
|
69
|
+
其他内部配置。应用部署在子路径时,通过 `baseUrl` 显式传入部署根路径。
|
|
70
|
+
`resolveServiceUrl()` 的 `path` 只接受服务内相对路径;绝对 URL、反斜杠和越出服务
|
|
71
|
+
base path 的路径返回 `null`。
|
|
72
|
+
|
|
73
|
+
公开类型为 `PlatformEndpoints`、`PlatformServiceName`、`LoadPlatformEndpointsOptions`;
|
|
74
|
+
需要同步初始化时可直接使用 `EMPTY_PLATFORM_ENDPOINTS`。
|
|
75
|
+
|
|
50
76
|
## BladeClient
|
|
51
77
|
|
|
52
78
|
### 构造
|
|
@@ -56,10 +82,12 @@ new BladeClient({
|
|
|
56
82
|
baseUrl: "https://blade.example.com", // 后端地址;同域部署可传 ""
|
|
57
83
|
token: "sk-blade-xxx", // 可选:PAT。不传则用 cookie 或 login()
|
|
58
84
|
tokenStorage: "local", // 可选:login() 的令牌存哪("local" 默认 / "memory")
|
|
59
|
-
streamTokens: false, // 可选:只接收完成态内容,不订阅逐 token 增量
|
|
60
85
|
})
|
|
61
86
|
```
|
|
62
87
|
|
|
88
|
+
SDK 会固定订阅普通聊天所需的完整实时事件。产品内置 Web 的精简/开发者展示模式不属于
|
|
89
|
+
公共 SDK 契约,也没有对应的构造参数或 Socket.IO 字段。
|
|
90
|
+
|
|
63
91
|
> **`baseUrl` 填哪个地址?** 必须是 Blade Agent 后端的地址(形如 `http://<主机>:8020`),只要域名和端口、不带路径。
|
|
64
92
|
> 注意别填成你平时打开的 Blade OS 地址(同主机的 `:80`)—— 那是另一套接口,SDK 连不上。
|
|
65
93
|
|
|
@@ -261,6 +289,40 @@ const body = { model: defaultServiceModel, messages, stream: true }
|
|
|
261
289
|
没问题,直接交给浏览器就指向用户自己的机器了。默认形态是后端透传(密钥本来也不该进浏览器),
|
|
262
290
|
浏览器直连只适合这个地址对浏览器同样可达的场景。
|
|
263
291
|
|
|
292
|
+
### 远程电脑:client.computers
|
|
293
|
+
|
|
294
|
+
一个会话除了自己的运行时,还可以操作用户接入的其他电脑(`blade daemon connect` 接进来的机器)。
|
|
295
|
+
**默认一台都不能用**,要先为这次会话启动它。
|
|
296
|
+
|
|
297
|
+
```ts
|
|
298
|
+
const { computers } = await client.computers.list(sessionId)
|
|
299
|
+
// SessionComputerList → { computers: SessionComputer[] }
|
|
300
|
+
// SessionComputer: { id, label, os, arch, home, workspace, allowed_paths,
|
|
301
|
+
// online, enabled, is_primary, last_seen_at, ... }
|
|
302
|
+
|
|
303
|
+
await client.computers.setEnabled(sessionId, computer.id, true) // 启动
|
|
304
|
+
await client.computers.setEnabled(sessionId, computer.id, false) // 停用
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
`online` 和 `enabled` 是**两件独立的事**:前者指那台电脑此刻连着后端,后者指这次会话已经启动了它。
|
|
308
|
+
离线的电脑也能先启动,等它连上就直接可用。`online` 由服务端读心跳时间判定,不做实时探测,
|
|
309
|
+
所以电脑离线时列表照样返回它——你拿得到「它离线了」这个结论。
|
|
310
|
+
|
|
311
|
+
`is_primary` 表示这次会话本身就跑在这台电脑上。这种电脑恒为可用,也不能停用——
|
|
312
|
+
那是会话自己的工作目录所在。
|
|
313
|
+
|
|
314
|
+
做电脑选择器时用这几个纯函数,别自己重算状态:
|
|
315
|
+
|
|
316
|
+
```ts
|
|
317
|
+
import { canToggleComputer, computerState, sortComputers } from "@blade-hq/agent-client"
|
|
318
|
+
|
|
319
|
+
sortComputers(computers) // 可用的在前,其次在线的,最后按名字
|
|
320
|
+
computerState(computer) // ComputerState: "primary" | "enabled" | "offline" | "idle"
|
|
321
|
+
canToggleComputer(computer) // 主运行时返回 false
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
`ComputersResource` 是 `client.computers` 的类型。
|
|
325
|
+
|
|
264
326
|
## AgentSession
|
|
265
327
|
|
|
266
328
|
一个会话的实时状态机。**状态归属实例**:同一页面建多个会话互不干扰。
|
|
@@ -369,7 +431,7 @@ chat.on("chatEnd", (e) => console.log("回复结束", e.status))
|
|
|
369
431
|
chat.on("error", (e) => console.error(e.message))
|
|
370
432
|
```
|
|
371
433
|
|
|
372
|
-
完整事件表见 `AgentSessionEvents` 类型定义(含 `modeChange` / `workspaceChanged` / `artifact` / `notification` / `backgroundTask` / `taskListUpdated` / `rewind` / `replayMismatch` 等)。`on()`
|
|
434
|
+
完整事件表见 `AgentSessionEvents` 类型定义(含 `modeChange` / `workspaceChanged` / `artifact` / `notification` / `backgroundTask` / `taskListUpdated` / `rewind` / `replayMismatch` 等)。`toolResult.source` 区分实时结果、首次连接回放和断线重连回放;`on()` 返回取消函数,handler 抛异常只告警、不影响会话。
|
|
373
435
|
|
|
374
436
|
## iframe 嵌入形态:connectEmbedded
|
|
375
437
|
|
|
@@ -456,6 +518,9 @@ groupMessagesByLoop(messages) // 按主/子智能体分组(智能体
|
|
|
456
518
|
contentPreview(message.content, 80) // 截断预览
|
|
457
519
|
```
|
|
458
520
|
|
|
521
|
+
错误消息在普通聊天界面展示前用 `chatErrorForDisplay(message)` 转成稳定的业务文案,
|
|
522
|
+
避免把内部路径或传输诊断暴露给用户;仅开发者界面显式传入第二个参数 `true` 保留原文。
|
|
523
|
+
|
|
459
524
|
一个完整的渲染示例:
|
|
460
525
|
|
|
461
526
|
```tsx
|
|
@@ -518,9 +583,9 @@ transformSlashCommand(skillId, prompt, { local: false, installed: false })
|
|
|
518
583
|
- **模型目录**:`ModelsResource`、`ModelCatalog`、`ModelOption`
|
|
519
584
|
- **会话资源(REST)**:`SessionsResource`、`CreateSessionRequest`、`ImportSessionOptions`、`AppCliDefinition`、`AppCliAttachment`、`AttachAppOptions`、`PaginatedSessionsResult`、`GlobalSearchResult`、`GlobalSearchResultItem`、`GlobalSearchConversationResult`、`GlobalSearchFileResult`、`SessionHistory`、`SessionContextStats`、`ResultFeedback`、`ResultFeedbackReason`、`ShareLinkResult`、`FileEntry`、`UploadFileEntry`、`UploadFilesOptions`、`SessionProfile`、`SessionDetail`、`SessionInfo`、`SessionStatus`、`SessionPortMapping`、`ModeId`、`TemplateId`、`PrimarySkillSnapshot`、`PrimarySkillParallelMode`
|
|
520
585
|
- **会话回放**:`ReplayState`、`ReplaySpeed`、`ReplayPreview`、`ReplaySnapshot`、`toReplaySnapshot`、`DEFAULT_REPLAY_SPEED`
|
|
521
|
-
- **会话状态机**:`SessionHub`、`SessionState`、`SendOptions`、`ConnectionStatus`、`AskUserAnswerData`、`AgentLoopInfo`、`ActiveCompactionState`、`createInitialSessionState`、`AgentSessionEventName`
|
|
586
|
+
- **会话状态机**:`SessionHub`、`SessionConnectOptions`、`SessionState`、`SendOptions`、`ConnectionStatus`、`AskUserAnswerData`、`AgentLoopInfo`、`ActiveCompactionState`、`createInitialSessionState`、`AgentSessionEventName`
|
|
522
587
|
- **页面协作**:`EmbeddedChat`、`EmbeddedChatOptions`、`CommandHandler`、`CommandEnvelope`、`InboundAction`、`InboundEnvelope`、`isCommandEnvelope`、`isInboundEnvelope`
|
|
523
|
-
- **消息与投影协议**:`MessageContent`、`MessageContentPart`、`TextContentPart`、`ImageUrlContentPart`、`FileContentPart`、`ToolCallInfo`、`ToolBridgeContent`、`CompactionInfo`、`MemoryRefInfo`、`ArchivedFileInfo`、`ArchivedToolCallInfo`、`TurnProjection`、`ContentBlock`、`PatchEnvelope`、`MemoryRef`、`PostChatFollowup`、`FinalArtifact`、`latestPostChatFollowup`、`buildMessageContent`、`normalizeMessageContent`、`isHiddenInternalMessage`、`transformSlashCommand`、`SkillMentionAvailability`、`extractTextAttachments`、`ParsedTextAttachment`、`ParsedTextContext`
|
|
588
|
+
- **消息与投影协议**:`MessageContent`、`MessageContentPart`、`TextContentPart`、`ImageUrlContentPart`、`FileContentPart`、`ToolCallInfo`、`ToolBridgeContent`、`CompactionInfo`、`ContextProjectionData`、`ContextProjectionFields`、`ContextDisplayState`、`ContextGroupDisplayState`、`ContextAction`、`ContextSourceInfo`、`MemoryRefInfo`、`ArchivedFileInfo`、`ArchivedToolCallInfo`、`TurnProjection`、`ContentBlock`、`PatchEnvelope`、`MemoryRef`、`PostChatFollowup`、`FinalArtifact`、`contextProjectionData`、`getContextDisplayState`、`getContextGroupDisplayState`、`groupAdjacentContextRuns`、`latestPostChatFollowup`、`buildMessageContent`、`normalizeMessageContent`、`isHiddenInternalMessage`、`transformSlashCommand`、`SkillMentionAvailability`、`extractTextAttachments`、`ParsedTextAttachment`、`ParsedTextContext`
|
|
524
589
|
- **Solution / 任务协议**:`Solution`、`SolutionAppField`、`SolutionAppState`、`SolutionAppUiConfig`、`SolutionRef`、`PublishedSolutionRef`、`ExistingSolutionRef`、`PreparedSolution`、`PreparedSolutionAsset`、`LayoutType`、`BizRole`、`TaskStatus`、`BackgroundTask`、`BackgroundTaskStopResult`
|
|
525
590
|
- **Headless**:`HeadlessResource`、`RunOptions`、`RunResult`、`RunTrace`
|
|
526
591
|
- **低层通道(apps/web 等高级集成)**:`createSocket`、`CreateSocketOptions`、`TypedSocket`、`AsrAudioPayload`、`ClientProjectionBuilder`、`RawEvent`、`acceptedPostChatFollowupCompletesLatestRun`、`reconcileOptimisticUserTurns`
|
package/dist/blade-client.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { type LoginOptions, type LoginResult, type TokenStorageMode } from "./au
|
|
|
2
2
|
import { type BladeFetchInit, type HttpMethod } from "./rest";
|
|
3
3
|
import { AuthResource } from "./resources/auth";
|
|
4
4
|
import { HeadlessResource } from "./resources/headless";
|
|
5
|
+
import { ComputersResource } from "./resources/computers";
|
|
5
6
|
import { ModelsResource } from "./resources/models";
|
|
6
7
|
import { SessionsResource } from "./resources/sessions";
|
|
7
8
|
import { SessionHub } from "./session/hub";
|
|
@@ -23,8 +24,6 @@ export interface BladeClientOptions {
|
|
|
23
24
|
tokenStorage?: TokenStorageMode;
|
|
24
25
|
fetchImpl?: typeof fetch;
|
|
25
26
|
onRefreshSuccess?: () => void | Promise<void>;
|
|
26
|
-
/** 是否订阅逐 token 增量,默认 true。关闭后仍接收完整消息和语义事件。 */
|
|
27
|
-
streamTokens?: boolean;
|
|
28
27
|
}
|
|
29
28
|
export declare class BladeClient {
|
|
30
29
|
private refreshPromise;
|
|
@@ -35,6 +34,7 @@ export declare class BladeClient {
|
|
|
35
34
|
readonly options: BladeClientOptions;
|
|
36
35
|
readonly auth: AuthResource;
|
|
37
36
|
readonly headless: HeadlessResource;
|
|
37
|
+
readonly computers: ComputersResource;
|
|
38
38
|
readonly models: ModelsResource;
|
|
39
39
|
readonly sessions: SessionsResource;
|
|
40
40
|
/** 实时会话中枢:client.sessions.connect() 内部使用,一般不直接访问。 */
|
package/dist/index.d.ts
CHANGED
|
@@ -2,10 +2,13 @@ export { BladeClient } from "./blade-client";
|
|
|
2
2
|
export type { BladeClientOptions, UploadProgress } from "./blade-client";
|
|
3
3
|
export { BladeApiError } from "./rest";
|
|
4
4
|
export type { LoginOptions, LoginResult, TokenStorageMode } from "./auth-login";
|
|
5
|
+
export { EMPTY_PLATFORM_ENDPOINTS, loadPlatformEndpoints, resolveServiceUrl, } from "./platform-endpoints";
|
|
6
|
+
export type { LoadPlatformEndpointsOptions, PlatformEndpoints, PlatformServiceName, } from "./platform-endpoints";
|
|
5
7
|
export { SDK_NAME, SDK_VERSION } from "./version";
|
|
6
8
|
export { AgentSession } from "./session/agent-session";
|
|
7
9
|
export type { AttachAppOptions, SendOptions } from "./session/agent-session";
|
|
8
10
|
export { SessionHub } from "./session/hub";
|
|
11
|
+
export type { SessionConnectOptions } from "./session/hub";
|
|
9
12
|
export type { AgentSessionEvents, AgentSessionEventName } from "./session/events";
|
|
10
13
|
export { SessionSetupError } from "./session/definition";
|
|
11
14
|
export type { SessionConfig, SessionDefinition, SessionSetupStage, SkillDefinition, TextFile, SolutionDefinition, } from "./session/definition";
|
|
@@ -18,12 +21,17 @@ export type { CommandEnvelope, InboundAction, InboundEnvelope } from "./commands
|
|
|
18
21
|
export { isCommandEnvelope, isInboundEnvelope } from "./commands/protocol";
|
|
19
22
|
export type { AuthResource, ExchangeCodeParams, ExchangeCodeResult, ProvidersResponse, UserInfo, } from "./resources/auth";
|
|
20
23
|
export type { HeadlessResource } from "./resources/headless";
|
|
24
|
+
export { ComputersResource } from "./resources/computers";
|
|
25
|
+
export { canToggleComputer, computerState, sortComputers, } from "./resources/computers";
|
|
26
|
+
export type { ComputerState, SessionComputer, SessionComputerList, } from "./resources/computers";
|
|
21
27
|
export { ModelsResource } from "./resources/models";
|
|
22
28
|
export type { ModelCatalog, ModelOption } from "./resources/models";
|
|
23
29
|
export type { SessionsResource } from "./resources/sessions";
|
|
24
30
|
export type { CreateSessionRequest, AppCliAttachment, AppCliDefinition, FileEntry, ImportSessionOptions, PaginatedSessionsResult, GlobalSearchConversationResult, GlobalSearchFileResult, GlobalSearchResult, GlobalSearchResultItem, ResultFeedback, ResultFeedbackReason, SessionContextStats, SessionHistory, ShareLinkResult, UploadFileEntry, UploadFilesOptions, } from "./resources/sessions";
|
|
25
31
|
export type { ArchivedFileInfo, ArchivedToolCallInfo, ChatMessage, CompactionInfo, FileContentPart, ImageUrlContentPart, MemoryRefInfo, MessageContent, MessageContentPart, TextContentPart, ToolBridgeContent, ToolCallInfo, } from "./schemas/message";
|
|
26
|
-
export { buildMessageContent, contentPreview, extractTextAttachments, getFileParts, getImageParts, getTextContent, groupMessagesByLoop, isHiddenInternalMessage, normalizeMessageContent, transformSlashCommand, } from "./schemas/message-utils";
|
|
32
|
+
export { buildMessageContent, chatErrorForDisplay, contentPreview, extractTextAttachments, getFileParts, getImageParts, getTextContent, groupMessagesByLoop, isHiddenInternalMessage, normalizeMessageContent, transformSlashCommand, } from "./schemas/message-utils";
|
|
33
|
+
export { contextProjectionData, getContextDisplayState, getContextGroupDisplayState, groupAdjacentContextRuns, } from "./schemas/context";
|
|
34
|
+
export type { ContextAction, ContextDisplayState, ContextGroupDisplayState, ContextProjectionData, ContextProjectionFields, ContextSourceInfo, } from "./schemas/context";
|
|
27
35
|
export type { ParsedTextAttachment, ParsedTextContext, SkillMentionAvailability, } from "./schemas/message-utils";
|
|
28
36
|
export type { ContentBlock, FinalArtifact, MemoryRef, PatchEnvelope, PostChatFollowup, TurnProjection, } from "./schemas/projection";
|
|
29
37
|
export { latestPostChatFollowup } from "./schemas/projection-utils";
|