@blade-hq/agent-client 2612.0.0-beta.19 → 2612.0.0-beta.20

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
@@ -111,6 +111,8 @@ const configured = await client.sessions.create({ intent: "数据分析", model:
111
111
 
112
112
  两者都返回 [`AgentSession`](#agentsession)。
113
113
 
114
+ SDK 创建的会话默认归接入应用(`initiator: "sdk"`),运行事件仍由 SDK 交付,提醒展示和点击导航由接入应用自行处理,BA 内置 Web 不弹出这些会话的完成或等待回复提醒。内置 Web 创建入口显式使用 `initiator: "ui"`;此字段表示应用归属,与 headless 执行模式无关。
115
+
114
116
  ### 声明完整会话
115
117
 
116
118
  自定义 Solution、Skill 和模型无需手写上传步骤:
@@ -838,3 +840,23 @@ const delivery = await session.getDelivery(request.requestId)
838
840
  匿名客户端不能读取 owner-only `configuration`,详情不返回 `env`。持链接者可以在共享沙盒执行代码,因此显式提供的环境变量会对该会话参与者可见;不要用它保存创建者的私人凭据。第一版不支持匿名 `app-dev`(软件工厂),也不提供同源 HTML 应用展示;文件可以下载查看。
839
841
 
840
842
  匿名子客户端保留 `commandTransport`,并为匿名命令额外提供第四个可选参数 `{ anonymousSessionId }`。中间件应使用本次调用的 `send()` 保持匿名凭证,或按该范围使用专属通道;不能把命令转发到另一个账号连接。普通命令仍提供原来的三个参数。
843
+
844
+ ### 消息附加资料
845
+
846
+ 应用可通过 `SendOptions.contextAttachments` 或 `PreparedSendOptions.contextAttachments` 提供消息级资料。`ContextAttachment` 的 `id`、`label`、可读纯文本 `content` 与可选 `data`、`files` 都绑定到该条消息,完整资料通过 Context 提供给模型,正文保持原文。资料不是系统指令。
847
+
848
+ ```ts
849
+ const request = session.prepareSend('任务已完成', {
850
+ mode: 'executing',
851
+ contextAttachments: [{
852
+ id: 'receipt-1', label: '市场周报', content: '状态:已完成\n已验证交付。',
853
+ data: { status: 'succeeded' },
854
+ files: [{ name: '周报.html', session_id: workerSessionId, path: '周报.html' }],
855
+ }],
856
+ })
857
+ // 在网络提交前持久化完整 request,重试时复用同一快照和 requestId。
858
+ await persist(request)
859
+ await session.sendPrepared(request)
860
+ ```
861
+
862
+ 每条消息最多 20 份资料,ID 不重复,每份正文最多 64000 个 Unicode 字符,整个资料 JSON 最多 256 KiB,超限拒绝。文件沿用指定会话的鉴权与路径解析,不接受外部 URL;仅有 `name` 的文件显示不可用。带资料的可靠消息作为独立一轮排队,不能走只传正文的「立即补充」。原生智能体目前不支持此通道。
@@ -213,7 +213,7 @@ var ToolProvider = class {
213
213
 
214
214
  // src/version.ts
215
215
  var SDK_NAME = "agent-client";
216
- var SDK_VERSION = true ? "2612.0.0-beta.19" : "1.1.1";
216
+ var SDK_VERSION = true ? "2612.0.0-beta.20" : "1.1.1";
217
217
 
218
218
  // src/auth-login.ts
219
219
  function isAuthCallbackMessage(value) {
@@ -445,6 +445,30 @@ var LogCursor = class {
445
445
  }
446
446
  };
447
447
 
448
+ // src/schemas/context-attachments.ts
449
+ function snapshotContextAttachments(value) {
450
+ const snapshot2 = JSON.parse(JSON.stringify(value));
451
+ if (!Array.isArray(snapshot2) || snapshot2.length > 20) throw new Error("\u6BCF\u6761\u6D88\u606F\u6700\u591A\u63D0\u4F9B 20 \u4EFD\u8D44\u6599");
452
+ const ids = /* @__PURE__ */ new Set();
453
+ const validText = (text, limit) => typeof text === "string" && [...text].length > 0 && [...text].length <= limit;
454
+ for (const item of snapshot2) {
455
+ if (!item || !validText(item.id, 128) || !validText(item.label, 512) || !validText(item.content, 64e3) || ids.has(item.id)) throw new Error("\u9644\u52A0\u8D44\u6599\u683C\u5F0F\u9519\u8BEF\u6216 ID \u91CD\u590D");
456
+ ids.add(item.id);
457
+ if (item.data != null && (typeof item.data !== "object" || Array.isArray(item.data))) throw new Error("\u8D44\u6599\u6570\u636E\u5FC5\u987B\u662F JSON \u5BF9\u8C61");
458
+ if (item.files != null && (!Array.isArray(item.files) || item.files.length > 20)) throw new Error("\u8D44\u6599\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF");
459
+ for (const file of item.files ?? []) {
460
+ if (!validText(file.name, 512)) throw new Error("\u8D44\u6599\u6587\u4EF6\u540D\u683C\u5F0F\u9519\u8BEF");
461
+ if (file.session_id == null && file.path == null) continue;
462
+ if (!validText(file.session_id, 128) || !validText(file.path, 2048) || /[\\:]/.test(file.path) || file.path.replace(/^\//, "").split("/").some((part) => !part || part === "." || part === "..")) throw new Error("\u8D44\u6599\u6587\u4EF6\u5FC5\u987B\u4F7F\u7528\u6709\u6548\u7684\u4F1A\u8BDD\u6587\u4EF6\u8DEF\u5F84");
463
+ }
464
+ }
465
+ if (new TextEncoder().encode(JSON.stringify(snapshot2)).length > 256 * 1024) throw new Error("\u6D88\u606F\u9644\u52A0\u8D44\u6599\u4E0D\u80FD\u8D85\u8FC7 256 KiB");
466
+ return snapshot2;
467
+ }
468
+ function normalizeContextAttachments(value) {
469
+ return Array.isArray(value) ? value : [];
470
+ }
471
+
448
472
  // src/schemas/plugin-refs.ts
449
473
  function normalizePluginRefs(value) {
450
474
  if (!Array.isArray(value)) return [];
@@ -1734,6 +1758,7 @@ var ClientProjectionBuilder = class {
1734
1758
  status: "completed",
1735
1759
  blocks: [{ type: "text", content: displayContent }],
1736
1760
  ...refs.length ? { refs } : {},
1761
+ context_attachments: normalizeContextAttachments(payload.context_attachments),
1737
1762
  topic_asset_refs: normalizeTopicAssetRefs(payload.topic_asset_refs),
1738
1763
  tool_calls: [],
1739
1764
  model: null,
@@ -2439,6 +2464,7 @@ function projectHistory(entries) {
2439
2464
  if (role === "user") {
2440
2465
  const refs = normalizeMessageRefs(message.refs);
2441
2466
  if (refs.length) turn.refs = refs;
2467
+ turn.context_attachments = normalizeContextAttachments(message.context_attachments);
2442
2468
  }
2443
2469
  const isNativeToolEntry = role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.some(
2444
2470
  (toolCall) => isRecord(toolCall) && typeof toolCall.provider === "string"
@@ -3344,6 +3370,7 @@ function toCreateSessionPayload(request) {
3344
3370
  const solutionRef = request.solution_ref ?? externalSolutionRef(request.solution_id);
3345
3371
  return {
3346
3372
  intent: request.intent ?? "",
3373
+ initiator: request.initiator ?? "sdk",
3347
3374
  anonymous: request.anonymous,
3348
3375
  solution_id: solutionRef ? void 0 : request.solution_id,
3349
3376
  solution_ref: solutionRef,
@@ -5154,6 +5181,7 @@ function projectionToMessage(turn) {
5154
5181
  ...turn.started_at ? { timestamp: turn.started_at } : {},
5155
5182
  ...turn.memory_refs?.length ? { memory_refs: turn.memory_refs } : {},
5156
5183
  ...turn.refs?.length ? { refs: turn.refs } : {},
5184
+ ...turn.context_attachments?.length ? { context_attachments: turn.context_attachments } : {},
5157
5185
  ...turn.topic_asset_refs?.length ? { topic_asset_refs: turn.topic_asset_refs } : {}
5158
5186
  };
5159
5187
  }
@@ -5391,7 +5419,7 @@ function withQueue(state, snapshot2) {
5391
5419
  return { ...state, queue: snapshot2 };
5392
5420
  }
5393
5421
  var localTurnCounter = 0;
5394
- function addUserMessage(state, content, clientRequestId, topicAssetRefs, refs) {
5422
+ function addUserMessage(state, content, clientRequestId, topicAssetRefs, refs, contextAttachments) {
5395
5423
  localTurnCounter += 1;
5396
5424
  const turnId = `local-user-${clientRequestId ?? `${Date.now()}-${localTurnCounter}`}`;
5397
5425
  const optimisticTurn = {
@@ -5403,6 +5431,7 @@ function addUserMessage(state, content, clientRequestId, topicAssetRefs, refs) {
5403
5431
  // 消费方才能拿它当"确认前后不变"的稳定标识使用。
5404
5432
  client_render_id: turnId,
5405
5433
  ...refs ? { refs } : {},
5434
+ ...contextAttachments?.length ? { context_attachments: contextAttachments } : {},
5406
5435
  ...topicAssetRefs?.length ? { topic_asset_refs: topicAssetRefs } : {},
5407
5436
  loop_id: "root",
5408
5437
  role: "user",
@@ -5652,6 +5681,8 @@ var AgentSession = class _AgentSession {
5652
5681
  bufferedCommandDeliveries = null;
5653
5682
  pendingReplayMessage = null;
5654
5683
  pendingReplayMode;
5684
+ pendingReplayRequestId;
5685
+ pendingReplayAttachments;
5655
5686
  pendingReplayRefs;
5656
5687
  pendingReplayTopicAssetRefs;
5657
5688
  recentChatEndAt = 0;
@@ -5956,10 +5987,12 @@ var AgentSession = class _AgentSession {
5956
5987
  /** Prepare a durable text input without sending any network request. */
5957
5988
  prepareSend(content, options = {}) {
5958
5989
  if (!content.trim()) throw new Error("\u6D88\u606F\u4E0D\u80FD\u4E3A\u7A7A");
5959
- if (Object.keys(options).some((key) => !["mode", "model", "thinkingOverride", "reasoningLevel"].includes(key))) {
5990
+ if (Object.keys(options).some((key) => !["mode", "model", "thinkingOverride", "reasoningLevel", "contextAttachments"].includes(key))) {
5960
5991
  throw new Error("\u53EF\u9760\u6587\u672C\u53D1\u9001\u4E0D\u652F\u6301\u8FD9\u4E9B\u53C2\u6570\uFF0C\u8BF7\u4F7F\u7528 send()");
5961
5992
  }
5962
- return { sessionId: this.sessionId, requestId: createClientRequestId(), content, options: JSON.parse(JSON.stringify(options)) };
5993
+ const snapshot2 = JSON.parse(JSON.stringify(options));
5994
+ if (snapshot2.contextAttachments) snapshot2.contextAttachments = snapshotContextAttachments(snapshot2.contextAttachments);
5995
+ return { sessionId: this.sessionId, requestId: createClientRequestId(), content, options: snapshot2 };
5963
5996
  }
5964
5997
  /** Durably enqueue an ordinary text input. Retries must reuse the saved request. */
5965
5998
  async sendPrepared(request) {
@@ -5974,7 +6007,8 @@ var AgentSession = class _AgentSession {
5974
6007
  mode: request.options.mode,
5975
6008
  model: request.options.model,
5976
6009
  thinking_override: request.options.thinkingOverride,
5977
- reasoning_level: request.options.reasoningLevel
6010
+ reasoning_level: request.options.reasoningLevel,
6011
+ ...request.options.contextAttachments ? { context_attachments: request.options.contextAttachments } : {}
5978
6012
  }
5979
6013
  }, QUEUE_ACK_TIMEOUT_MS);
5980
6014
  const result = parseQueueAck(response, this.sessionId);
@@ -6151,6 +6185,7 @@ var AgentSession = class _AgentSession {
6151
6185
  }
6152
6186
  }
6153
6187
  async sendUnlocked(content, options) {
6188
+ const contextAttachments = options.contextAttachments ? snapshotContextAttachments(options.contextAttachments) : void 0;
6154
6189
  await this.ensureIdleBeforeSend();
6155
6190
  if (this.state.isStreaming && options.queueWhenRunning !== true || this.state.activeCompaction || this.manualCompactionRequest) {
6156
6191
  this.update(
@@ -6187,7 +6222,7 @@ var AgentSession = class _AgentSession {
6187
6222
  let optimisticAskAnswer;
6188
6223
  let previousAskAnswer;
6189
6224
  this.update((state) => {
6190
- const next = addUserMessage(state, content, clientRequestId, options.topicAssetRefs, options.refs);
6225
+ const next = addUserMessage(state, content, clientRequestId, options.topicAssetRefs, options.refs, contextAttachments);
6191
6226
  optimisticTurnId = next.turns.at(-1)?.turn_id ?? null;
6192
6227
  return next;
6193
6228
  });
@@ -6205,6 +6240,8 @@ var AgentSession = class _AgentSession {
6205
6240
  if (!options.replayDecision) {
6206
6241
  this.pendingReplayMessage = content;
6207
6242
  this.pendingReplayMode = options.mode;
6243
+ this.pendingReplayRequestId = clientRequestId;
6244
+ this.pendingReplayAttachments = contextAttachments;
6208
6245
  this.pendingReplayRefs = options.refs;
6209
6246
  this.pendingReplayTopicAssetRefs = options.topicAssetRefs;
6210
6247
  }
@@ -6221,6 +6258,7 @@ var AgentSession = class _AgentSession {
6221
6258
  whatif: options.whatif,
6222
6259
  replay_decision: options.replayDecision,
6223
6260
  app_context: appContext,
6261
+ context_attachments: contextAttachments,
6224
6262
  refs: options.refs,
6225
6263
  topic_asset_refs: options.topicAssetRefs,
6226
6264
  // 运行中提交不必由客户端挑命令:服务端按会话运行状态决定直接执行还是入队。
@@ -6306,6 +6344,8 @@ var AgentSession = class _AgentSession {
6306
6344
  }
6307
6345
  this.pendingReplayMessage = null;
6308
6346
  this.pendingReplayMode = void 0;
6347
+ this.pendingReplayRequestId = void 0;
6348
+ this.pendingReplayAttachments = void 0;
6309
6349
  this.pendingReplayRefs = void 0;
6310
6350
  this.pendingReplayTopicAssetRefs = void 0;
6311
6351
  this.update((current) => {
@@ -6838,10 +6878,14 @@ var AgentSession = class _AgentSession {
6838
6878
  _handleReplayMismatch(data) {
6839
6879
  const message = this.pendingReplayMessage ?? data.actual_message ?? "";
6840
6880
  const mode = this.pendingReplayMode;
6881
+ const requestId = this.pendingReplayRequestId ?? createClientRequestId();
6882
+ const contextAttachments = this.pendingReplayAttachments;
6841
6883
  const refs = this.pendingReplayRefs;
6842
6884
  const topicAssetRefs = this.pendingReplayTopicAssetRefs;
6843
6885
  this.pendingReplayMessage = null;
6844
6886
  this.pendingReplayMode = void 0;
6887
+ this.pendingReplayRequestId = void 0;
6888
+ this.pendingReplayAttachments = void 0;
6845
6889
  this.pendingReplayRefs = void 0;
6846
6890
  this.pendingReplayTopicAssetRefs = void 0;
6847
6891
  const respond = (decision) => {
@@ -6852,8 +6896,10 @@ var AgentSession = class _AgentSession {
6852
6896
  message,
6853
6897
  mode,
6854
6898
  replay_decision: decision,
6899
+ client_request_id: requestId,
6855
6900
  refs,
6856
- topic_asset_refs: topicAssetRefs
6901
+ topic_asset_refs: topicAssetRefs,
6902
+ context_attachments: contextAttachments
6857
6903
  },
6858
6904
  3e4
6859
6905
  ).then((response) => {
@@ -8554,4 +8600,4 @@ export {
8554
8600
  createSocket,
8555
8601
  BladeClient
8556
8602
  };
8557
- //# sourceMappingURL=chunk-XKAHFAEI.js.map
8603
+ //# sourceMappingURL=chunk-2VIJBVAC.js.map