@blade-hq/agent-client 2612.0.0-beta.5 → 2612.0.0-beta.6

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
@@ -12,6 +12,8 @@ Blade Agent 的框架无关客户端。浏览器和 Node.js 都能用;用 Vue
12
12
  npm install @blade-hq/agent-client
13
13
  ```
14
14
 
15
+ TypeScript 消费者需要开发依赖 `@types/node`:底层 arktype 的声明使用 Node `buffer.File` 类型。若显式配置 `compilerOptions.types`,需包含 `node`;这是类型检查环境要求,浏览器运行时不因此依赖 Node。React 使用者还需对应版本的 `@types/react` / `@types/react-dom`。
16
+
15
17
  默认装到的是当前长期支持版(LTS),厂内离线交付按它开发。要跟两周一发的公网版本,改用 `@next`。
16
18
 
17
19
  最稳妥的做法是先读目标 Server 的 `GET /api/version`,按返回的版本号在 `package.json` 里钉死——NPM 的 `latest` 不一定和目标环境跑的版本一致。
@@ -713,3 +715,11 @@ chat.renderers = {
713
715
 
714
716
 
715
717
  主题类型:`ChatGroup`、`ChatGroupRole`、`ChatGroupMember`、`ChatGroupTask`、`CreateChatGroupTask`、`UpdateChatGroupTask`、`ChatGroupAsset`、`ChatGroupAssetList`、`TopicAssetRef`。`normalizeTopicAssetRefs` 仅规范化展示引用并去重,不代替服务端鉴权。
718
+
719
+ ### 插件条目选择
720
+
721
+ `PluginRef` 保存 `{ provider: "plugin", plugin, server, id, label }`,`normalizePluginRefs(value)` 按插件、服务和条目 id 去重。label 只用于展示,条目权限和全文由服务端按当前账号重新读取。
722
+
723
+ `session.send(text, { refs })` 选择本轮条目;不传 refs 继承上一轮选择,`refs: []` 清除,新的数组替换。AskUser 和暂停续跑沿用本轮冻结内容,下一条新消息才重新读取。流式消息和历史消息都保留 `message.refs`。
724
+
725
+ `ToolEvidence` 是工具调用的原文快照类型。`ToolCallInfo.evidence` 保存引用编号、原文、插件包摘要及具体调用身份;历史查看直接使用该字段,插件停用或卸载后仍可核查当时内容。
@@ -1,6 +1,6 @@
1
1
  // src/version.ts
2
2
  var SDK_NAME = "agent-client";
3
- var SDK_VERSION = true ? "2612.0.0-beta.5" : "1.1.1";
3
+ var SDK_VERSION = true ? "2612.0.0-beta.6" : "1.1.1";
4
4
 
5
5
  // src/auth-login.ts
6
6
  function isAuthCallbackMessage(value) {
@@ -280,6 +280,19 @@ var LogCursor = class {
280
280
  }
281
281
  };
282
282
 
283
+ // src/schemas/plugin-refs.ts
284
+ function normalizePluginRefs(value) {
285
+ if (!Array.isArray(value)) return [];
286
+ const seen = /* @__PURE__ */ new Set();
287
+ return value.flatMap((item) => {
288
+ if (!item || typeof item !== "object" || item.provider !== "plugin" || ![item.plugin, item.server, item.id, item.label].every((part) => typeof part === "string" && part)) return [];
289
+ const key = JSON.stringify([item.plugin, item.server, item.id]);
290
+ if (seen.has(key)) return [];
291
+ seen.add(key);
292
+ return [{ provider: "plugin", plugin: item.plugin, server: item.server, id: item.id, label: item.label }];
293
+ });
294
+ }
295
+
283
296
  // src/schemas/topic-assets.ts
284
297
  function normalizeTopicAssetRefs(value) {
285
298
  if (!Array.isArray(value)) return [];
@@ -828,6 +841,10 @@ function normalizeChildPause(pausePayload) {
828
841
  }
829
842
  return { pauseToolData, childLoopName, childToolCallId, description };
830
843
  }
844
+ function attachToolEvidence(call, evidence) {
845
+ if (!call) return;
846
+ call.evidence = call.status === "done" && Array.isArray(evidence) ? evidence : void 0;
847
+ }
831
848
 
832
849
  // src/schemas/message.ts
833
850
  function inferToolStatus(resultStr) {
@@ -1528,6 +1545,7 @@ var ClientProjectionBuilder = class {
1528
1545
  onUserMessage(_loopId, payload) {
1529
1546
  const entryId = String(payload.entry_id ?? this.nextTurnId("user"));
1530
1547
  const displayContent = payload.display_content ?? payload.content ?? "";
1548
+ const refs = normalizePluginRefs(payload.refs);
1531
1549
  const turn = {
1532
1550
  id: entryId,
1533
1551
  sequence: this.nextSeq(),
@@ -1537,6 +1555,7 @@ var ClientProjectionBuilder = class {
1537
1555
  role: "user",
1538
1556
  status: "completed",
1539
1557
  blocks: [{ type: "text", content: displayContent }],
1558
+ ...refs.length ? { refs } : {},
1540
1559
  topic_asset_refs: normalizeTopicAssetRefs(payload.topic_asset_refs),
1541
1560
  tool_calls: [],
1542
1561
  model: null,
@@ -1672,6 +1691,7 @@ var ClientProjectionBuilder = class {
1672
1691
  const sl = sourceLoopFor(state.loopId, this.loopDescriptions);
1673
1692
  const startedAt = typeof payload.started_at === "string" && payload.started_at ? payload.started_at : null;
1674
1693
  applyToolResult(state, toolCallId, content, status, durationMs, ranInParallel, sl, startedAt);
1694
+ attachToolEvidence(state.toolCalls.find((call) => call.id === toolCallId), payload.evidence);
1675
1695
  const pendingChild = [...this.pendingChildPauses.values()].find(
1676
1696
  (pause) => pause.parentLoopName === loopId && pause.parentToolCallId === toolCallId
1677
1697
  );
@@ -2193,6 +2213,7 @@ function projectHistory(entries) {
2193
2213
  if (owner && toolCall) {
2194
2214
  toolCall.status = message._error ? "error" : inferToolStatus(String(message.content ?? ""));
2195
2215
  toolCall.result = message.content ?? "";
2216
+ attachToolEvidence(toolCall, message._evidence);
2196
2217
  const duration = numberOrNull(message._duration_ms);
2197
2218
  if (duration !== null) toolCall.duration_ms = duration;
2198
2219
  if (typeof message._started_at === "string") {
@@ -2602,6 +2623,7 @@ var HeadlessResource = class {
2602
2623
  return this.runTracked(session_id, prompt, options, true);
2603
2624
  }
2604
2625
  async runTracked(sessionId, prompt, options, returnEnvelope) {
2626
+ if ((options.refs?.length ?? 0) > 20) throw new HeadlessError("\u6BCF\u6761\u6D88\u606F\u6700\u591A\u9009\u62E9 20 \u4E2A\u63D2\u4EF6\u6761\u76EE");
2605
2627
  if ((options.topicAssetRefs?.length ?? 0) > 20) throw new HeadlessError("\u6BCF\u6761\u6D88\u606F\u6700\u591A\u5F15\u7528 20 \u4E2A\u4E3B\u9898\u8D44\u4EA7");
2606
2628
  const timeoutMs = options.timeoutMs ?? 3e5;
2607
2629
  const session_id = sessionId;
@@ -2829,6 +2851,7 @@ var HeadlessResource = class {
2829
2851
  headless: true,
2830
2852
  output_schema: options.schema ?? null,
2831
2853
  model: options.model ?? null,
2854
+ refs: options.refs,
2832
2855
  topic_asset_refs: options.topicAssetRefs
2833
2856
  },
2834
2857
  (response) => {
@@ -3225,18 +3248,21 @@ var SessionsResource = class {
3225
3248
  *
3226
3249
  * Secrets are never returned: `write_only` lists the pointers that hold one.
3227
3250
  */
3228
- getSessionPluginConfig(sessionId, name, init) {
3229
- return this.client.jsonFromInit(`/api/sessions/${encodeURIComponent(sessionId)}/plugins/${encodeURIComponent(name)}/config`, init);
3251
+ getSessionPluginConfig(sessionId, name, init, scope = "personal") {
3252
+ return this.client.jsonFromInit(`/api/sessions/${encodeURIComponent(sessionId)}/plugins/${encodeURIComponent(name)}/config?scope=${scope}`, init);
3230
3253
  }
3231
3254
  /**
3232
- * Publish explicit set/remove operations to the user's keychain file.
3255
+ * Save explicit set/remove operations to encrypted server storage.
3233
3256
  *
3234
3257
  * Fields absent from both lists keep their stored value, so a form never has
3235
- * to round-trip a secret. Rejections leave the previous file untouched; the
3236
- * call never restarts MCP servers.
3258
+ * to round-trip a secret. Rejections preserve the previous values; the
3259
+ * shared settings restart only the affected hosted plugin.
3237
3260
  */
3238
- updateSessionPluginConfig(sessionId, name, update, init) {
3239
- return this.client.jsonFromInit(`/api/sessions/${encodeURIComponent(sessionId)}/plugins/${encodeURIComponent(name)}/config`, { method: "PUT", body: JSON.stringify(update), ...init });
3261
+ updateSessionPluginConfig(sessionId, name, update, init, scope = "personal") {
3262
+ return this.client.jsonFromInit(`/api/sessions/${encodeURIComponent(sessionId)}/plugins/${encodeURIComponent(name)}/config?scope=${scope}`, { method: "PUT", body: JSON.stringify(update), ...init });
3263
+ }
3264
+ restartSessionPluginHost(sessionId, name) {
3265
+ return this.client.jsonFromInit(`/api/sessions/${encodeURIComponent(sessionId)}/plugins/${encodeURIComponent(name)}/host`, { method: "POST" });
3240
3266
  }
3241
3267
  /** 创建新会话并直接连接,返回可收发消息的 AgentSession。 */
3242
3268
  async create(request = {}) {
@@ -4851,6 +4877,7 @@ function projectionToMessage(turn) {
4851
4877
  display_name: toolCall.display_name,
4852
4878
  arguments: toolCall.arguments,
4853
4879
  result: toolCall.result ?? void 0,
4880
+ ...toolCall.evidence ? { evidence: toolCall.evidence } : {},
4854
4881
  pending_question_ref: toolCall.pending_question_ref ?? void 0,
4855
4882
  status: toolCall.status === "pending" || toolCall.status === "awaiting_answer" || toolCall.status === "done" || toolCall.status === "error" || toolCall.status === "cancelled" ? toolCall.status : "pending",
4856
4883
  ...typeof toolCall.duration_ms === "number" ? { duration_ms: toolCall.duration_ms } : {}
@@ -4870,6 +4897,7 @@ function projectionToMessage(turn) {
4870
4897
  ...typeof turn.duration_ms === "number" ? { duration_ms: turn.duration_ms } : {},
4871
4898
  ...turn.started_at ? { timestamp: turn.started_at } : {},
4872
4899
  ...turn.memory_refs?.length ? { memory_refs: turn.memory_refs } : {},
4900
+ ...turn.refs?.length ? { refs: turn.refs } : {},
4873
4901
  ...turn.topic_asset_refs?.length ? { topic_asset_refs: turn.topic_asset_refs } : {}
4874
4902
  };
4875
4903
  }
@@ -5107,7 +5135,7 @@ function withQueue(state, snapshot2) {
5107
5135
  return { ...state, queue: snapshot2 };
5108
5136
  }
5109
5137
  var localTurnCounter = 0;
5110
- function addUserMessage(state, content, clientRequestId, topicAssetRefs) {
5138
+ function addUserMessage(state, content, clientRequestId, topicAssetRefs, refs) {
5111
5139
  localTurnCounter += 1;
5112
5140
  const turnId = `local-user-${clientRequestId ?? `${Date.now()}-${localTurnCounter}`}`;
5113
5141
  const optimisticTurn = {
@@ -5118,6 +5146,7 @@ function addUserMessage(state, content, clientRequestId, topicAssetRefs) {
5118
5146
  // client_render_id(= 乐观 turn 自己的 turn_id)保持同一个值,
5119
5147
  // 消费方才能拿它当"确认前后不变"的稳定标识使用。
5120
5148
  client_render_id: turnId,
5149
+ ...refs ? { refs } : {},
5121
5150
  ...topicAssetRefs?.length ? { topic_asset_refs: topicAssetRefs } : {},
5122
5151
  loop_id: "root",
5123
5152
  role: "user",
@@ -5367,6 +5396,7 @@ var AgentSession = class _AgentSession {
5367
5396
  bufferedCommandDeliveries = null;
5368
5397
  pendingReplayMessage = null;
5369
5398
  pendingReplayMode;
5399
+ pendingReplayRefs;
5370
5400
  pendingReplayKbIds;
5371
5401
  pendingReplayTopicAssetRefs;
5372
5402
  recentChatEndAt = 0;
@@ -5837,7 +5867,7 @@ var AgentSession = class _AgentSession {
5837
5867
  let optimisticAskAnswer;
5838
5868
  let previousAskAnswer;
5839
5869
  this.update((state) => {
5840
- const next = addUserMessage(state, content, clientRequestId, options.topicAssetRefs);
5870
+ const next = addUserMessage(state, content, clientRequestId, options.topicAssetRefs, options.refs);
5841
5871
  optimisticTurnId = next.turns.at(-1)?.turn_id ?? null;
5842
5872
  return next;
5843
5873
  });
@@ -5855,6 +5885,7 @@ var AgentSession = class _AgentSession {
5855
5885
  if (!options.replayDecision) {
5856
5886
  this.pendingReplayMessage = content;
5857
5887
  this.pendingReplayMode = options.mode;
5888
+ this.pendingReplayRefs = options.refs;
5858
5889
  this.pendingReplayKbIds = options.kbIds;
5859
5890
  this.pendingReplayTopicAssetRefs = options.topicAssetRefs;
5860
5891
  }
@@ -5871,6 +5902,7 @@ var AgentSession = class _AgentSession {
5871
5902
  whatif: options.whatif,
5872
5903
  replay_decision: options.replayDecision,
5873
5904
  app_context: appContext,
5905
+ refs: options.refs,
5874
5906
  kb_ids: options.kbIds,
5875
5907
  topic_asset_refs: options.topicAssetRefs,
5876
5908
  // 运行中提交不必由客户端挑命令:服务端按会话运行状态决定直接执行还是入队。
@@ -5956,6 +5988,7 @@ var AgentSession = class _AgentSession {
5956
5988
  }
5957
5989
  this.pendingReplayMessage = null;
5958
5990
  this.pendingReplayMode = void 0;
5991
+ this.pendingReplayRefs = void 0;
5959
5992
  this.pendingReplayKbIds = void 0;
5960
5993
  this.pendingReplayTopicAssetRefs = void 0;
5961
5994
  this.update((current) => {
@@ -6489,10 +6522,12 @@ var AgentSession = class _AgentSession {
6489
6522
  _handleReplayMismatch(data) {
6490
6523
  const message = this.pendingReplayMessage ?? data.actual_message ?? "";
6491
6524
  const mode = this.pendingReplayMode;
6525
+ const refs = this.pendingReplayRefs;
6492
6526
  const kbIds = this.pendingReplayKbIds;
6493
6527
  const topicAssetRefs = this.pendingReplayTopicAssetRefs;
6494
6528
  this.pendingReplayMessage = null;
6495
6529
  this.pendingReplayMode = void 0;
6530
+ this.pendingReplayRefs = void 0;
6496
6531
  this.pendingReplayKbIds = void 0;
6497
6532
  this.pendingReplayTopicAssetRefs = void 0;
6498
6533
  const respond = (decision) => {
@@ -6503,6 +6538,7 @@ var AgentSession = class _AgentSession {
6503
6538
  message,
6504
6539
  mode,
6505
6540
  replay_decision: decision,
6541
+ refs,
6506
6542
  kb_ids: kbIds,
6507
6543
  topic_asset_refs: topicAssetRefs
6508
6544
  },
@@ -6780,6 +6816,7 @@ var AgentSession = class _AgentSession {
6780
6816
  display_name: toolCall.display_name,
6781
6817
  arguments: toolCall.arguments,
6782
6818
  result: toolCall.result ?? void 0,
6819
+ ...toolCall.evidence ? { evidence: toolCall.evidence } : {},
6783
6820
  status: toolCall.status === "pending" || toolCall.status === "awaiting_answer" || toolCall.status === "done" || toolCall.status === "error" || toolCall.status === "cancelled" ? toolCall.status : "pending"
6784
6821
  };
6785
6822
  if (!this.seenToolCallIds.has(toolCall.id)) {
@@ -8084,6 +8121,7 @@ export {
8084
8121
  SDK_VERSION,
8085
8122
  BladeApiError,
8086
8123
  isRecord,
8124
+ normalizePluginRefs,
8087
8125
  normalizeTopicAssetRefs,
8088
8126
  inferToolStatus,
8089
8127
  contextProjectionData,
@@ -8163,4 +8201,4 @@ export {
8163
8201
  createSocket,
8164
8202
  BladeClient
8165
8203
  };
8166
- //# sourceMappingURL=chunk-Q337O3AM.js.map
8204
+ //# sourceMappingURL=chunk-KLI47WAU.js.map