@blade-hq/agent-client 2612.0.0-beta.48 → 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 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, is_primary, last_seen_at, ... }
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
- `is_primary` 表示这次会话本身就跑在这台电脑上。这种电脑恒为可用,也不能停用——
451
- 那是会话自己的工作目录所在。
450
+ 智能体与会话工作目录始终在沙盒,远程电脑只提供命令、文件与画面能力。
452
451
 
453
452
  `ComputersResource` 是 `client.computers` 的类型。
454
453
 
@@ -969,6 +968,23 @@ await client.auth.exchangeCode({ code, state, clientOrigin, codeVerifier, androi
969
968
 
970
969
  `state` 必须与发起请求时一致;PA 还须校验自身登录请求 cookie。访问令牌保存在自己的服务端,不能通过回调 URL 或网页消息转发。手机端回传及部署约定见仓库 `docs/specs/261026-android-browser-login/`。
971
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
+
972
988
  ### 桌面系统浏览器回传
973
989
 
974
990
  Electron 主进程负责临时监听 `http://127.0.0.1:<port>/auth/callback`,并用
@@ -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.48" : "1.1.1";
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) {
@@ -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-2AGTCYFG.js.map
9306
+ //# sourceMappingURL=chunk-NNYV4ZVA.js.map