@blade-hq/agent-client 2612.0.0-beta.47 → 2612.0.0-beta.49
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 +31 -5
- package/dist/{chunk-GYJFPRM3.js → chunk-NNYV4ZVA.js} +68 -5
- package/dist/chunk-NNYV4ZVA.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -1
- package/dist/internal.js +5 -1
- package/dist/internal.js.map +1 -1
- package/dist/resources/auth.d.ts +4 -1
- package/dist/resources/computers.d.ts +1 -1
- package/dist/schemas/ask-user-question.d.ts +21 -0
- package/package.json +1 -1
- package/public-api.md +37 -1
- package/dist/chunk-GYJFPRM3.js.map +0 -1
package/README.md
CHANGED
|
@@ -431,24 +431,23 @@ const body = { model: defaultServiceModel, messages, stream: true }
|
|
|
431
431
|
### 远程电脑:client.computers
|
|
432
432
|
|
|
433
433
|
一个会话除了自己的运行时,还可以操作用户接入的其他电脑(`blade daemon connect` 接进来的机器)。
|
|
434
|
-
|
|
434
|
+
**用户接入的电脑默认在本次会话可用**,可以按会话停用。
|
|
435
435
|
|
|
436
436
|
```ts
|
|
437
437
|
const { computers } = await client.computers.list(sessionId)
|
|
438
438
|
// SessionComputerList → { computers: SessionComputer[] }
|
|
439
439
|
// SessionComputer: { id, label, os, arch, home, workspace, allowed_paths,
|
|
440
|
-
// online, enabled,
|
|
440
|
+
// online, enabled, last_seen_at, ... }
|
|
441
441
|
|
|
442
442
|
await client.computers.setEnabled(sessionId, computer.id, true) // 启动
|
|
443
443
|
await client.computers.setEnabled(sessionId, computer.id, false) // 停用
|
|
444
444
|
```
|
|
445
445
|
|
|
446
|
-
`online` 和 `enabled`
|
|
446
|
+
`online` 和 `enabled` 是**两件独立的事**:前者指那台电脑此刻连着后端,后者指这次会话允许使用它(默认启用,显式停用优先)。
|
|
447
447
|
离线的电脑也能先启动,等它连上就直接可用。`online` 由服务端读心跳时间判定,不做实时探测,
|
|
448
448
|
所以电脑离线时列表照样返回它——你拿得到「它离线了」这个结论。
|
|
449
449
|
|
|
450
|
-
|
|
451
|
-
那是会话自己的工作目录所在。
|
|
450
|
+
智能体与会话工作目录始终在沙盒,远程电脑只提供命令、文件与画面能力。
|
|
452
451
|
|
|
453
452
|
`ComputersResource` 是 `client.computers` 的类型。
|
|
454
453
|
|
|
@@ -968,3 +967,30 @@ await client.auth.exchangeCode({ code, state, clientOrigin, codeVerifier, androi
|
|
|
968
967
|
```
|
|
969
968
|
|
|
970
969
|
`state` 必须与发起请求时一致;PA 还须校验自身登录请求 cookie。访问令牌保存在自己的服务端,不能通过回调 URL 或网页消息转发。手机端回传及部署约定见仓库 `docs/specs/261026-android-browser-login/`。
|
|
970
|
+
|
|
971
|
+
### 原生提问和回答
|
|
972
|
+
|
|
973
|
+
`parseAskUserQuestion` 解析 `AskUserQuestion` 的工具参数或结果,返回 `AskUserQuestionData`。每个 `AskUserQuestionItem` 包含问题、`AskUserQuestionOption` 选项和可选多选标记。组件和后端共享这些定义,支持历史中的字符串选项与 `multi_select` 字段。
|
|
974
|
+
|
|
975
|
+
`formatAskUserAnswer` 根据问题及 `AskUserAnswerData` 生成用户可读文本;回答应送回原始会话和工具调用。`getState().askAnswers` 同时从实时事件和历史恢复已回答内容。`sendPrepared` 是普通输入队列,不能代替原生回答。
|
|
976
|
+
|
|
977
|
+
```ts
|
|
978
|
+
const question = parseAskUserQuestion(toolCall.arguments)
|
|
979
|
+
if (question) {
|
|
980
|
+
const answer = { selections: { 0: [1] }, custom: {} }
|
|
981
|
+
const accepted = await session.send(formatAskUserAnswer(question, answer), {
|
|
982
|
+
askUserAnswer: { tool_call_id: toolCall.id, ...answer },
|
|
983
|
+
})
|
|
984
|
+
// 只有 accepted 为 true,才能把此次投递视为服务端已接收。
|
|
985
|
+
}
|
|
986
|
+
```
|
|
987
|
+
|
|
988
|
+
### 桌面系统浏览器回传
|
|
989
|
+
|
|
990
|
+
Electron 主进程负责临时监听 `http://127.0.0.1:<port>/auth/callback`,并用
|
|
991
|
+
`desktop_app=ba|pa`、`callback_uri`、`code_challenge`(S256)、`state` 和
|
|
992
|
+
`client_origin` 请求 `/api/auth/sdk/authorize`。平台和回调绑定不可省略或改写。
|
|
993
|
+
服务端通过 `auth.exchangeCode({ code, state, clientOrigin, codeVerifier,
|
|
994
|
+
desktopApp: "pa", callbackUri })` 换码;PA 的 PAT 留在服务端。
|
|
995
|
+
BA 桌面使用同源 `/api/auth/sdk/desktop-session` 建立自身 cookie 会话。
|
|
996
|
+
`auth.login()` 仍是普通浏览器的弹窗登录,不负责本机监听。
|
|
@@ -224,7 +224,7 @@ var ToolProvider = class {
|
|
|
224
224
|
|
|
225
225
|
// src/version.ts
|
|
226
226
|
var SDK_NAME = "agent-client";
|
|
227
|
-
var SDK_VERSION = true ? "2612.0.0-beta.
|
|
227
|
+
var SDK_VERSION = true ? "2612.0.0-beta.49" : "1.1.1";
|
|
228
228
|
|
|
229
229
|
// src/auth-login.ts
|
|
230
230
|
function isAuthCallbackMessage(value) {
|
|
@@ -378,7 +378,7 @@ var AuthResource = class {
|
|
|
378
378
|
headers: { Origin: params.clientOrigin },
|
|
379
379
|
body: JSON.stringify({
|
|
380
380
|
code: params.code,
|
|
381
|
-
...params.codeVerifier ? { code_verifier: params.codeVerifier, android_app: params.androidApp } : {},
|
|
381
|
+
...params.codeVerifier ? { code_verifier: params.codeVerifier, android_app: params.androidApp, desktop_app: params.desktopApp, callback_uri: params.callbackUri } : {},
|
|
382
382
|
state: params.state,
|
|
383
383
|
client_origin: params.clientOrigin
|
|
384
384
|
})
|
|
@@ -8616,7 +8616,7 @@ function encode(input) {
|
|
|
8616
8616
|
if (value && typeof value === "object")
|
|
8617
8617
|
return [
|
|
8618
8618
|
"dict",
|
|
8619
|
-
Object.entries(value).map(([key, item]) => [key, walk(item)])
|
|
8619
|
+
Object.entries(value).filter(([, item]) => item !== void 0).map(([key, item]) => [key, walk(item)])
|
|
8620
8620
|
];
|
|
8621
8621
|
return ["value", value ?? null];
|
|
8622
8622
|
};
|
|
@@ -9145,6 +9145,67 @@ var ApplicationProviderSocket = class extends Events {
|
|
|
9145
9145
|
}
|
|
9146
9146
|
};
|
|
9147
9147
|
|
|
9148
|
+
// src/schemas/ask-user-question.ts
|
|
9149
|
+
function parseAskUserQuestion(toolResult) {
|
|
9150
|
+
if (!toolResult) return null;
|
|
9151
|
+
try {
|
|
9152
|
+
const parsed = JSON.parse(toolResult);
|
|
9153
|
+
let questions = parsed?.questions;
|
|
9154
|
+
if (typeof questions === "string") {
|
|
9155
|
+
try {
|
|
9156
|
+
questions = JSON.parse(questions);
|
|
9157
|
+
} catch {
|
|
9158
|
+
return null;
|
|
9159
|
+
}
|
|
9160
|
+
}
|
|
9161
|
+
if (Array.isArray(questions) && questions.length > 0) {
|
|
9162
|
+
const normalized = questions.map(normalizeQuestionItem);
|
|
9163
|
+
if (normalized.every((question) => question !== null)) {
|
|
9164
|
+
return { ...parsed, questions: normalized };
|
|
9165
|
+
}
|
|
9166
|
+
}
|
|
9167
|
+
} catch {
|
|
9168
|
+
}
|
|
9169
|
+
return null;
|
|
9170
|
+
}
|
|
9171
|
+
function formatAskUserAnswer(data, answer) {
|
|
9172
|
+
const parts = data.questions.map((question, index) => {
|
|
9173
|
+
const text = typeof answer.custom[index] === "string" ? answer.custom[index].trim() : [...answer.selections[index] ?? []].sort((a, b) => a - b).map((optionIndex) => question.options[optionIndex].label).join(", ");
|
|
9174
|
+
return `- ${question.question} -> ${indentAnswerContinuationLines(text)}`;
|
|
9175
|
+
});
|
|
9176
|
+
const note = answer.note?.trim() ?? "";
|
|
9177
|
+
return [
|
|
9178
|
+
`\u5173\u4E8E\u9700\u8981\u786E\u8BA4\u7684\u95EE\u9898\uFF0C\u7528\u6237\u7684\u56DE\u7B54\u5982\u4E0B\uFF1A
|
|
9179
|
+
${parts.join("\n")}`,
|
|
9180
|
+
note ? `\u8865\u5145\u8BF4\u660E\uFF1A${indentAnswerContinuationLines(note)}` : ""
|
|
9181
|
+
].filter(Boolean).join("\n");
|
|
9182
|
+
}
|
|
9183
|
+
function indentAnswerContinuationLines(answer) {
|
|
9184
|
+
return answer.replaceAll("\n", "\n ");
|
|
9185
|
+
}
|
|
9186
|
+
function normalizeQuestionItem(value) {
|
|
9187
|
+
if (!value || typeof value !== "object") return null;
|
|
9188
|
+
const item = value;
|
|
9189
|
+
if (typeof item.question !== "string" || !Array.isArray(item.options)) return null;
|
|
9190
|
+
const options = item.options.map(normalizeOptionItem);
|
|
9191
|
+
if (!options.every((option) => option !== null)) return null;
|
|
9192
|
+
return {
|
|
9193
|
+
question: item.question,
|
|
9194
|
+
options,
|
|
9195
|
+
multiSelect: item.multiSelect === true || item.multi_select === true
|
|
9196
|
+
};
|
|
9197
|
+
}
|
|
9198
|
+
function normalizeOptionItem(value) {
|
|
9199
|
+
if (typeof value === "string") return { label: value, description: "" };
|
|
9200
|
+
if (!value || typeof value !== "object") return null;
|
|
9201
|
+
const option = value;
|
|
9202
|
+
if (typeof option.label !== "string") return null;
|
|
9203
|
+
return {
|
|
9204
|
+
label: option.label,
|
|
9205
|
+
description: typeof option.description === "string" ? option.description : ""
|
|
9206
|
+
};
|
|
9207
|
+
}
|
|
9208
|
+
|
|
9148
9209
|
export {
|
|
9149
9210
|
SandboxResource,
|
|
9150
9211
|
BladeApiError,
|
|
@@ -9238,6 +9299,8 @@ export {
|
|
|
9238
9299
|
SessionHub,
|
|
9239
9300
|
createSocket,
|
|
9240
9301
|
BladeClient,
|
|
9241
|
-
BladeApplicationClient
|
|
9302
|
+
BladeApplicationClient,
|
|
9303
|
+
parseAskUserQuestion,
|
|
9304
|
+
formatAskUserAnswer
|
|
9242
9305
|
};
|
|
9243
|
-
//# sourceMappingURL=chunk-
|
|
9306
|
+
//# sourceMappingURL=chunk-NNYV4ZVA.js.map
|