@blade-hq/agent-client 1.1.12-beta.4 → 1.2.0-beta.1
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 +21 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +72 -3
- package/dist/index.js.map +1 -1
- package/dist/resources/sessions.d.ts +18 -0
- package/dist/session/agent-session.d.ts +17 -1
- package/dist/types/socket-events.d.ts +4 -0
- package/package.json +1 -1
- package/public-api.md +28 -2
package/README.md
CHANGED
|
@@ -196,6 +196,26 @@ chat.dispose() // 彻底释放(什么时候
|
|
|
196
196
|
|
|
197
197
|
### 页面协作:让智能体和你的页面互动
|
|
198
198
|
|
|
199
|
+
**页面状态与业务后端 → 智能体**:
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
await chat.attachApp({
|
|
203
|
+
cli: {
|
|
204
|
+
command: "library",
|
|
205
|
+
runtime: "python",
|
|
206
|
+
source: new URL("./agent/library_cli.py", location.href),
|
|
207
|
+
},
|
|
208
|
+
getContext: () => ({
|
|
209
|
+
route: location.pathname,
|
|
210
|
+
selectedBookId: bookStore.getState().selectedBookId,
|
|
211
|
+
}),
|
|
212
|
+
})
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
`getContext` 在每次 `send()` 前执行一次,适合路由、当前选中对象等轻量页面状态;它不做响应式依赖追踪。完整业务数据由开发者自己的 CLI 查询。`command` 是智能体在 Bash 中直接执行的命令名,不会套在 `blade` 命令下。
|
|
216
|
+
|
|
217
|
+
`runtime: "python"` 使用沙盒系统 Python 运行单文件脚本;`runtime: "executable"` 接受能在 Linux 沙盒运行的可执行文件。`source` 可传 `Blob`、`File` 或浏览器可读取的 URL。应用 CLI 安装成功后随会话工作区保留;运行时可通过 `BLADE_APP_CONTEXT_FILE` 读取同一份页面上下文 JSON。
|
|
218
|
+
|
|
199
219
|
**智能体 → 页面**(例如智能体让地图高亮某个点):
|
|
200
220
|
|
|
201
221
|
```ts
|
|
@@ -365,7 +385,7 @@ function Message({ message }: { message: ChatMessage }) {
|
|
|
365
385
|
- **SDK 身份**:`SDK_NAME`、`SDK_VERSION`
|
|
366
386
|
- **声明式会话**:`SessionDefinition`、`SolutionDefinition`、`SkillDefinition`、`SessionConfig`、`TextFile`、`SessionSetupError`、`SessionSetupStage`
|
|
367
387
|
- **模型目录**:`ModelsResource`、`ModelCatalog`、`ModelOption`
|
|
368
|
-
- **会话资源(REST)**:`SessionsResource`、`CreateSessionRequest`、`PaginatedSessionsResult`、`SessionHistory`、`SessionContextStats`、`ShareLinkResult`、`FileEntry`、`UploadFileEntry`、`UploadFilesOptions`、`SessionProfile`、`SessionDetail`、`SessionInfo`、`SessionStatus`、`SessionPortMapping`、`ModeId`、`TemplateId`、`PrimarySkillSnapshot`、`PrimarySkillParallelMode`
|
|
388
|
+
- **会话资源(REST)**:`SessionsResource`、`CreateSessionRequest`、`AppCliDefinition`、`AppCliAttachment`、`AttachAppOptions`、`PaginatedSessionsResult`、`SessionHistory`、`SessionContextStats`、`ShareLinkResult`、`FileEntry`、`UploadFileEntry`、`UploadFilesOptions`、`SessionProfile`、`SessionDetail`、`SessionInfo`、`SessionStatus`、`SessionPortMapping`、`ModeId`、`TemplateId`、`PrimarySkillSnapshot`、`PrimarySkillParallelMode`
|
|
369
389
|
- **会话状态机**:`SessionHub`、`SessionState`、`SendOptions`、`ConnectionStatus`、`AskUserAnswerData`、`AgentLoopInfo`、`ActiveCompactionState`、`createInitialSessionState`、`AgentSessionEventName`
|
|
370
390
|
- **页面协作**:`EmbeddedChat`、`EmbeddedChatOptions`、`CommandHandler`、`CommandEnvelope`、`InboundAction`、`InboundEnvelope`、`isCommandEnvelope`、`isInboundEnvelope`
|
|
371
391
|
- **消息与投影协议**:`MessageContent`、`MessageContentPart`、`TextContentPart`、`ImageUrlContentPart`、`FileContentPart`、`ToolCallInfo`、`ToolBridgeContent`、`CompactionInfo`、`MemoryRefInfo`、`ArchivedFileInfo`、`ArchivedToolCallInfo`、`TurnProjection`、`ContentBlock`、`PatchEnvelope`、`MemoryRef`、`buildMessageContent`、`normalizeMessageContent`、`isHiddenInternalMessage`、`transformSlashCommand`、`extractTextAttachments`、`ParsedTextAttachment`、`ParsedTextContext`
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export { BladeApiError } from "./rest";
|
|
|
4
4
|
export type { LoginOptions, LoginResult, TokenStorageMode } from "./auth-login";
|
|
5
5
|
export { SDK_NAME, SDK_VERSION } from "./version";
|
|
6
6
|
export { AgentSession } from "./session/agent-session";
|
|
7
|
-
export type { SendOptions } from "./session/agent-session";
|
|
7
|
+
export type { AttachAppOptions, SendOptions } from "./session/agent-session";
|
|
8
8
|
export { SessionHub } from "./session/hub";
|
|
9
9
|
export type { AgentSessionEvents, AgentSessionEventName } from "./session/events";
|
|
10
10
|
export { SessionSetupError } from "./session/definition";
|
|
@@ -21,7 +21,7 @@ export type { HeadlessResource } from "./resources/headless";
|
|
|
21
21
|
export { ModelsResource } from "./resources/models";
|
|
22
22
|
export type { ModelCatalog, ModelOption } from "./resources/models";
|
|
23
23
|
export type { SessionsResource } from "./resources/sessions";
|
|
24
|
-
export type { CreateSessionRequest, FileEntry, PaginatedSessionsResult, SessionContextStats, SessionHistory, ShareLinkResult, UploadFileEntry, UploadFilesOptions, } from "./resources/sessions";
|
|
24
|
+
export type { CreateSessionRequest, AppCliAttachment, AppCliDefinition, FileEntry, PaginatedSessionsResult, SessionContextStats, SessionHistory, ShareLinkResult, UploadFileEntry, UploadFilesOptions, } from "./resources/sessions";
|
|
25
25
|
export type { ArchivedFileInfo, ArchivedToolCallInfo, ChatMessage, CompactionInfo, FileContentPart, ImageUrlContentPart, MemoryRefInfo, MessageContent, MessageContentPart, TextContentPart, ToolBridgeContent, ToolCallInfo, } from "./schemas/message";
|
|
26
26
|
export { buildMessageContent, contentPreview, extractTextAttachments, getFileParts, getImageParts, getTextContent, groupMessagesByLoop, isHiddenInternalMessage, normalizeMessageContent, transformSlashCommand, } from "./schemas/message-utils";
|
|
27
27
|
export type { ParsedTextAttachment, ParsedTextContext } from "./schemas/message-utils";
|
package/dist/index.js
CHANGED
|
@@ -2106,6 +2106,30 @@ var SessionsResource = class {
|
|
|
2106
2106
|
);
|
|
2107
2107
|
return response.json();
|
|
2108
2108
|
}
|
|
2109
|
+
/** 把应用自己的业务 CLI 安装到会话沙盒,并保留开发者声明的命令名。 */
|
|
2110
|
+
async attachAppCli(sessionId, definition) {
|
|
2111
|
+
let source;
|
|
2112
|
+
if (definition.source instanceof Blob) {
|
|
2113
|
+
source = definition.source;
|
|
2114
|
+
} else {
|
|
2115
|
+
const response2 = await globalThis.fetch(definition.source.toString());
|
|
2116
|
+
if (!response2.ok) {
|
|
2117
|
+
throw new Error(`\u8BFB\u53D6\u5E94\u7528 CLI \u5931\u8D25\uFF1AHTTP ${response2.status}`);
|
|
2118
|
+
}
|
|
2119
|
+
source = await response2.blob();
|
|
2120
|
+
}
|
|
2121
|
+
const filename = definition.filename ?? (typeof File !== "undefined" && definition.source instanceof File ? definition.source.name : void 0) ?? (definition.runtime === "python" ? "app-cli.py" : "app-cli");
|
|
2122
|
+
const form = new FormData();
|
|
2123
|
+
form.append("command", definition.command);
|
|
2124
|
+
form.append("runtime", definition.runtime);
|
|
2125
|
+
form.append("file", source, filename);
|
|
2126
|
+
const response = await this.client.formData(
|
|
2127
|
+
"POST",
|
|
2128
|
+
`/api/sessions/${sessionId}/app-cli`,
|
|
2129
|
+
form
|
|
2130
|
+
);
|
|
2131
|
+
return response.json();
|
|
2132
|
+
}
|
|
2109
2133
|
async deleteFile(sessionId, filePath) {
|
|
2110
2134
|
await this.client.json("DELETE", `/api/sessions/${sessionId}/files/${encodeURIComponent(filePath)}`);
|
|
2111
2135
|
}
|
|
@@ -2936,6 +2960,8 @@ var AgentSession = class _AgentSession {
|
|
|
2936
2960
|
pendingReplayMode;
|
|
2937
2961
|
recentChatEndAt = 0;
|
|
2938
2962
|
disposed = false;
|
|
2963
|
+
getAppContext = null;
|
|
2964
|
+
sendPending = false;
|
|
2939
2965
|
deliveredCommandKeys = /* @__PURE__ */ new Set();
|
|
2940
2966
|
deliveredToolPreviews = /* @__PURE__ */ new Map();
|
|
2941
2967
|
oomNotifiedKeys = /* @__PURE__ */ new Set();
|
|
@@ -2962,6 +2988,7 @@ var AgentSession = class _AgentSession {
|
|
|
2962
2988
|
listDir: async () => readonlyError(),
|
|
2963
2989
|
countFiles: async () => readonlyError(),
|
|
2964
2990
|
downloadFile: async () => readonlyError(),
|
|
2991
|
+
attachAppCli: async () => readonlyError(),
|
|
2965
2992
|
onDispose: () => void 0
|
|
2966
2993
|
},
|
|
2967
2994
|
"connected"
|
|
@@ -3016,18 +3043,58 @@ var AgentSession = class _AgentSession {
|
|
|
3016
3043
|
return this.commands.onCommand(action, handler);
|
|
3017
3044
|
}
|
|
3018
3045
|
// ---------------------------------------------------------------- 动作
|
|
3046
|
+
/**
|
|
3047
|
+
* 声明当前应用提供的页面上下文和业务 CLI。
|
|
3048
|
+
*
|
|
3049
|
+
* CLI 安装成功后才保存 getContext;之后每次 send 前恰好读取一次。
|
|
3050
|
+
*/
|
|
3051
|
+
async attachApp(options) {
|
|
3052
|
+
const attachment = options.cli ? await this.runtime.attachAppCli(this.sessionId, options.cli) : null;
|
|
3053
|
+
this.getAppContext = options.getContext;
|
|
3054
|
+
return attachment;
|
|
3055
|
+
}
|
|
3019
3056
|
/** 发送一条消息。字符串或多模态内容均可。 */
|
|
3020
3057
|
async send(content, options = {}) {
|
|
3021
3058
|
this.runtime.ensureConnected();
|
|
3022
|
-
if (this.state.isStreaming) {
|
|
3059
|
+
if (this.state.isStreaming || this.sendPending) {
|
|
3023
3060
|
this.update((s) => addErrorMessage(s, "\u5F53\u524D\u56DE\u590D\u5C1A\u672A\u7ED3\u675F\uFF0C\u8BF7\u7A0D\u540E\u518D\u53D1\u9001\u3002"));
|
|
3024
3061
|
return;
|
|
3025
3062
|
}
|
|
3063
|
+
this.sendPending = true;
|
|
3064
|
+
try {
|
|
3065
|
+
await this.sendUnlocked(content, options);
|
|
3066
|
+
} finally {
|
|
3067
|
+
this.sendPending = false;
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3070
|
+
async sendUnlocked(content, options) {
|
|
3026
3071
|
await this.ensureIdleBeforeSend();
|
|
3027
3072
|
if (this.state.isStreaming) {
|
|
3028
3073
|
this.update((s) => addErrorMessage(s, "\u5F53\u524D\u56DE\u590D\u5C1A\u672A\u7ED3\u675F\uFF0C\u8BF7\u7A0D\u540E\u518D\u53D1\u9001\u3002"));
|
|
3029
3074
|
return;
|
|
3030
3075
|
}
|
|
3076
|
+
let appContext;
|
|
3077
|
+
if (this.getAppContext) {
|
|
3078
|
+
try {
|
|
3079
|
+
const rawContext = await this.getAppContext();
|
|
3080
|
+
if (!isRecord5(rawContext)) {
|
|
3081
|
+
throw new Error("getContext \u5FC5\u987B\u8FD4\u56DE JSON \u5BF9\u8C61");
|
|
3082
|
+
}
|
|
3083
|
+
const serialized = JSON.stringify(rawContext);
|
|
3084
|
+
if (serialized === void 0) {
|
|
3085
|
+
throw new Error("getContext \u5FC5\u987B\u8FD4\u56DE\u53EF\u5E8F\u5217\u5316\u7684 JSON \u5BF9\u8C61");
|
|
3086
|
+
}
|
|
3087
|
+
const normalized = JSON.parse(serialized);
|
|
3088
|
+
if (!isRecord5(normalized)) {
|
|
3089
|
+
throw new Error("getContext \u5FC5\u987B\u8FD4\u56DE JSON \u5BF9\u8C61");
|
|
3090
|
+
}
|
|
3091
|
+
appContext = normalized;
|
|
3092
|
+
} catch (error) {
|
|
3093
|
+
const message = error instanceof Error && error.message ? `\u8BFB\u53D6\u5E94\u7528\u4E0A\u4E0B\u6587\u5931\u8D25\uFF1A${error.message}` : "\u8BFB\u53D6\u5E94\u7528\u4E0A\u4E0B\u6587\u5931\u8D25\uFF0C\u6D88\u606F\u672A\u53D1\u9001";
|
|
3094
|
+
this.update((s) => addErrorMessage(s, message));
|
|
3095
|
+
return;
|
|
3096
|
+
}
|
|
3097
|
+
}
|
|
3031
3098
|
const askUserAnswer = options.askUserAnswer;
|
|
3032
3099
|
if (!(askUserAnswer && typeof askUserAnswer.tool_call_id === "string")) {
|
|
3033
3100
|
this.update((s) => addUserMessage(s, content));
|
|
@@ -3052,7 +3119,8 @@ var AgentSession = class _AgentSession {
|
|
|
3052
3119
|
model: options.model,
|
|
3053
3120
|
thinking_override: options.thinkingOverride,
|
|
3054
3121
|
whatif: options.whatif,
|
|
3055
|
-
replay_decision: options.replayDecision
|
|
3122
|
+
replay_decision: options.replayDecision,
|
|
3123
|
+
app_context: appContext
|
|
3056
3124
|
};
|
|
3057
3125
|
try {
|
|
3058
3126
|
await this.ensureJoined();
|
|
@@ -3633,6 +3701,7 @@ var SessionHub = class {
|
|
|
3633
3701
|
listDir: (sessionId, dirPath) => this.client.sessions.listDir(sessionId, dirPath),
|
|
3634
3702
|
countFiles: (sessionId, dirPath) => this.client.sessions.countFiles(sessionId, dirPath),
|
|
3635
3703
|
downloadFile: (sessionId, filePath, downloadName) => this.client.sessions.downloadFile(sessionId, filePath, downloadName),
|
|
3704
|
+
attachAppCli: (sessionId, definition) => this.client.sessions.attachAppCli(sessionId, definition),
|
|
3636
3705
|
onDispose: (session) => {
|
|
3637
3706
|
if (this.sessions.get(session.sessionId) === session) {
|
|
3638
3707
|
this.sessions.delete(session.sessionId);
|
|
@@ -3825,7 +3894,7 @@ function resolveAuthToken(options) {
|
|
|
3825
3894
|
|
|
3826
3895
|
// src/version.ts
|
|
3827
3896
|
var SDK_NAME = "agent-client";
|
|
3828
|
-
var SDK_VERSION = true ? "1.
|
|
3897
|
+
var SDK_VERSION = true ? "1.2.0-beta.1" : "1.1.1";
|
|
3829
3898
|
|
|
3830
3899
|
// src/socket.ts
|
|
3831
3900
|
function withSdkIdentity(auth) {
|