@webskill/sdk 0.10.0 → 0.12.0

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.
Files changed (35) hide show
  1. package/dist/agent.d.ts +3 -2
  2. package/dist/agent.js +3 -1102
  3. package/dist/browser.d.ts +258 -11
  4. package/dist/browser.js +763 -47
  5. package/dist/{catalogComponents-DTcYfpLQ-CcoOaz-Z.js → catalogComponents-BgAJN0p8-C3K8klJd.js} +508 -923
  6. package/dist/dist-DU9KDAuR.js +1468 -0
  7. package/dist/{dist-1OFC-zax.js → dist-DqcL6jKO.js} +668 -60
  8. package/dist/{dist-BViUeszk.js → dist-sdKFgERo.js} +956 -115
  9. package/dist/{echarts-DhNm2ene.js → echarts-De78wXqV.js} +599 -61
  10. package/dist/{eventTypes-s2uwAcLG-Go3l_dUe.js → eventTypes-FllCrX-Z-DNDeHWoG.js} +6 -2
  11. package/dist/governance.d.ts +7 -3
  12. package/dist/governance.js +1 -1
  13. package/dist/{index-B0QPLWPZ.d.ts → index-3fCHc1mQ.d.ts} +198 -11
  14. package/dist/{index-DtFdMKBX.d.ts → index-C9pzXLKy.d.ts} +366 -9
  15. package/dist/{index-BF4E1a9j.d.ts → index-DFhU1uks.d.ts} +286 -19
  16. package/dist/index.d.ts +4 -4
  17. package/dist/index.js +3 -3
  18. package/dist/mcp.d.ts +58 -7
  19. package/dist/mcp.js +124 -21
  20. package/dist/node.d.ts +3 -3
  21. package/dist/node.js +60 -4
  22. package/dist/{openUiLibrary-CIrV--Ad-B8zG_91e.js → openUiLibrary-BKXW7Iwx-DaymVubt.js} +3 -3
  23. package/dist/processSandboxEntry.js +8 -1
  24. package/dist/sandboxWorkerEntry.js +8 -1
  25. package/dist/{skillVersionStore-D-qHk9ZE-DBsYYCWn.d.ts → skillVersionStore-D-qHk9ZE-DheTIwAB.d.ts} +1 -1
  26. package/dist/testing.d.ts +1 -1
  27. package/dist/{types-CrRcT-LM-DZAp8sWv.d.ts → types-DLctJep_-B5G4uk2u.d.ts} +22 -5
  28. package/dist/ui-react.d.ts +13 -4
  29. package/dist/ui-react.js +93 -259
  30. package/dist/ui-vue.d.ts +1 -1
  31. package/dist/ui-vue.js +2 -2
  32. package/dist/ui.d.ts +4 -4
  33. package/dist/ui.js +3 -3
  34. package/dist/{webskillLitCatalog-BJrphK0y-SGmRXaaO.js → webskillLitCatalog-D_zCqeQF-C9lrvvMr.js} +135 -16
  35. package/package.json +1 -1
package/dist/mcp.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { B as JsonSchema, _ as LlmToolSpec, it as SkillCatalogEntry, ot as SkillDocument } from "./types-CrRcT-LM-DZAp8sWv.js";
2
- import { Fn as mergeCatalogEntries, O as ExternalSkillProvider, Xt as ToolResult, k as ExternalToolSource } from "./index-DtFdMKBX.js";
1
+ import { B as JsonSchema, _ as LlmToolSpec, it as SkillCatalogEntry, ot as SkillDocument } from "./types-DLctJep_-B5G4uk2u.js";
2
+ import { F as ExternalToolSource, P as ExternalSkillProvider, dn as ToolResult, tr as mergeCatalogEntries } from "./index-C9pzXLKy.js";
3
3
  import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
4
4
  import { JSONRPCMessage } from "@modelcontextprotocol/sdk/types.js";
5
5
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -141,8 +141,26 @@ declare class McpToolResolver {
141
141
  */
142
142
  declare function endpointToolLlmName(endpoint: string, toolName: string): string;
143
143
  declare function parseEndpointToolLlmName(endpoint: string, llmName: string): string | undefined;
144
- declare function webMcpToolLlmName(toolName: string): string;
145
- declare function parseWebMcpToolLlmName(llmName: string): string | undefined;
144
+ /**
145
+ * 来源标识的长度上限(分册 26 §2.2)。
146
+ *
147
+ * 前缀计入工具名,而工具名进**每一次**请求 —— 长 sourceId 是持续成本。
148
+ * 装配期校验并给出可读错误,比运行时被 provider 拒掉好查。
149
+ */
150
+ declare const WEB_MCP_SOURCE_ID_MAX = 24;
151
+ /**
152
+ * WebMCP 工具的 LLM 可见名。
153
+ *
154
+ * 多来源时带来源前缀(FR-26.2):三个文档都注册 `get_current_date` 是常态,
155
+ * 「首个来源优先」是**静默歧义** —— 模型选中的到底是哪个,谁也说不清。
156
+ * 不传 sourceId 时保持 0.10.0 的旧名,单来源宿主无感。
157
+ */
158
+ declare function webMcpToolLlmName(toolName: string, sourceId?: string): string;
159
+ /** 解析回 `{ sourceId?, toolName }`;旧名(无来源段)解析出 `sourceId: undefined` */
160
+ declare function parseWebMcpToolLlmName(llmName: string, sourceIds?: readonly string[]): {
161
+ sourceId?: string;
162
+ toolName: string;
163
+ } | undefined;
146
164
  //#endregion
147
165
  //#region src/skills/temporarySkillProvider.d.ts
148
166
  /**
@@ -241,8 +259,14 @@ interface WebMcpToolDescriptor {
241
259
  */
242
260
  declare class ExperimentalWebMcpAdapter {
243
261
  #private;
262
+ /**
263
+ * 多来源时的消歧标识(分册 26 FR-26.2)。不设即沿用 0.10.0 的旧工具名,
264
+ * 单来源宿主无感;**两个以上来源必须各自设**,否则同名工具会撞车。
265
+ */
266
+ readonly sourceId?: string;
244
267
  constructor(api?: BrowserModelContextLike | (() => BrowserModelContextLike | undefined), options?: {
245
268
  enabled?: boolean;
269
+ sourceId?: string;
246
270
  });
247
271
  /**
248
272
  * 宿主能力检测(FR-19.2/19.4):**只**看 `document.modelContext.executeTool` 是否存在,
@@ -275,7 +299,24 @@ interface McpToolVisibility {
275
299
  /** 端点工具级开关;返回 false 时该工具对大模型不可见 */
276
300
  isEndpointToolEnabled?(endpoint: string, tool: string): boolean;
277
301
  /** WebMCP 工具级开关;返回 false 时该工具对大模型不可见 */
278
- isWebMcpToolEnabled?(tool: string): boolean;
302
+ /**
303
+ * 两级启停(FR-26.3,与端点/工具同款):`sourceId` 为空即整个来源那一组。
304
+ * 宿主按来源关 → 该组全灭;按工具关 → 只灭一个。
305
+ */
306
+ isWebMcpToolEnabled?(tool: string, sourceId?: string): boolean;
307
+ }
308
+ /**
309
+ * 参数留存的宿主侧信任声明(分册 30 / FR-30.6)。
310
+ *
311
+ * 声明只吃 endpoint / sourceId 这两个**宿主配置里的标识**,
312
+ * 不读工具 schema、不读工具描述、不读服务器元数据——服务器自称可信不算数。
313
+ * 缺省不信任;信任只影响脱敏判定,不影响可见性与审批。
314
+ */
315
+ interface McpSourceTrust {
316
+ /** 宿主声明「这台端点的工具 schema 我审查过」 */
317
+ isEndpointTrusted?(endpoint: string): boolean;
318
+ /** WebMCP 来源同款;`sourceId` 为空即未命名的那一个 */
319
+ isWebMcpSourceTrusted?(sourceId: string | undefined): boolean;
279
320
  }
280
321
  /**
281
322
  * runtime 扩展点实现:endpoint 注册表 + WebMCP adapter 一处装配。
@@ -286,15 +327,25 @@ declare class McpRuntimePlugin implements ExternalToolSource {
286
327
  readonly kind = "mcp";
287
328
  constructor(deps: {
288
329
  registry: EndpointRegistry<McpClientLike>;
289
- webMcp?: ExperimentalWebMcpAdapter;
330
+ webMcp?: readonly ExperimentalWebMcpAdapter[];
290
331
  resolver?: McpToolResolver;
291
332
  /** 工具可见性策略(端点/工具级启停);缺省全部可见 */
292
333
  visibility?: McpToolVisibility;
334
+ /** 参数留存的信任声明(分册 30);**缺省不信任** */
335
+ trust?: McpSourceTrust;
293
336
  /** 已知的 endpoint 名(注销后仍按 MCP_ENDPOINT_UNAVAILABLE 响应,而非 TOOL_NOT_FOUND) */
294
337
  endpoints?: string[];
295
338
  /** endpoint 不可用时的告警出口(默认 console.warn) */
296
339
  onWarning?(message: string): void;
297
340
  });
341
+ /**
342
+ * 参数留存的信任判定(分册 30 / FR-30.6)。
343
+ * 只按宿主配置里的 endpoint / sourceId 判,服务器传回的内容进不了这条路径。
344
+ */
345
+ argCaptureTrust(llmToolName: string): {
346
+ tier: 'host-trusted';
347
+ declaredBy?: string;
348
+ } | undefined;
298
349
  listToolSpecs(): Promise<LlmToolSpec[]>;
299
350
  canHandle(llmToolName: string): boolean;
300
351
  call(llmToolName: string, args: Record<string, unknown>): Promise<ToolResult>;
@@ -443,4 +494,4 @@ interface RemoteEndpointHandle {
443
494
  */
444
495
  declare function connectRemoteEndpoint(registry: EndpointRegistry<McpClientLike>, config: RemoteEndpointConfig): Promise<RemoteEndpointHandle>;
445
496
  //#endregion
446
- export { type BrowserModelContextLike, EndpointRegistry, ExperimentalWebMcpAdapter, type McpClientLike, type McpOAuthClient, type McpOAuthConfig, type McpOAuthHandshake, type McpOAuthHandshakeStore, type McpOAuthProvider, type McpOAuthStage, type McpOAuthTokenStore, type McpOAuthTokens, McpRuntimePlugin, McpToolResolver, type McpToolVisibility, MessageChannelTransport, type MessageChannelTransportOptions, type MessagePortLike, type RemoteEndpointConfig, type RemoteEndpointHandle, type ServedSkill, TemporarySkillProvider, type TransportState, type WebMcpToolDescriptor, type WebMcpToolLike, catalogMerge, connectRemoteEndpoint, createMemoryOAuthStores, createOAuthProvider, endpointToolLlmName, parseEndpointToolLlmName, parseWebMcpToolLlmName, serveSkillAsMcp, validateJsonRpcMessage, webMcpToolLlmName };
497
+ export { type BrowserModelContextLike, EndpointRegistry, ExperimentalWebMcpAdapter, type McpClientLike, type McpOAuthClient, type McpOAuthConfig, type McpOAuthHandshake, type McpOAuthHandshakeStore, type McpOAuthProvider, type McpOAuthStage, type McpOAuthTokenStore, type McpOAuthTokens, McpRuntimePlugin, type McpSourceTrust, McpToolResolver, type McpToolVisibility, MessageChannelTransport, type MessageChannelTransportOptions, type MessagePortLike, type RemoteEndpointConfig, type RemoteEndpointHandle, type ServedSkill, TemporarySkillProvider, type TransportState, WEB_MCP_SOURCE_ID_MAX, type WebMcpToolDescriptor, type WebMcpToolLike, catalogMerge, connectRemoteEndpoint, createMemoryOAuthStores, createOAuthProvider, endpointToolLlmName, parseEndpointToolLlmName, parseWebMcpToolLlmName, serveSkillAsMcp, validateJsonRpcMessage, webMcpToolLlmName };
package/dist/mcp.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { M as messageOf, g as assertRemoteUrlAllowed, h as WebSkillError } from "./dist-Bev6i6Ip.js";
2
- import { it as mergeCatalogEntries, lt as normalizeToolContent } from "./dist-BViUeszk.js";
2
+ import { St as normalizeToolContent, _t as mergeCatalogEntries } from "./dist-sdKFgERo.js";
3
3
 
4
4
  //#region ../mcp/dist/index.js
5
5
  /**
@@ -249,6 +249,11 @@ var McpToolResolver = class {
249
249
  return failure$1("TOOL_EXECUTION_FAILED", text || "MCP tool returned an error");
250
250
  }
251
251
  for (const item of content) if (item.text !== void 0 && item.text.length > MAX_MCP_RESULT_TEXT_BYTES) item.text = `${item.text.slice(0, MAX_MCP_RESULT_TEXT_BYTES)}…[truncated ${item.text.length - MAX_MCP_RESULT_TEXT_BYTES} chars]`;
252
+ const structured = result?.structuredContent;
253
+ if (typeof structured === "object" && structured !== null) content.push({
254
+ type: "json",
255
+ data: structured
256
+ });
252
257
  return {
253
258
  ok: true,
254
259
  content
@@ -267,11 +272,35 @@ function parseEndpointToolLlmName(endpoint, llmName) {
267
272
  const prefix = `${endpoint}__`;
268
273
  return llmName.startsWith(prefix) && llmName.length > prefix.length ? llmName.slice(prefix.length) : void 0;
269
274
  }
270
- function webMcpToolLlmName(toolName) {
271
- return `mcp__${toolName}`;
275
+ /**
276
+ * 来源标识的长度上限(分册 26 §2.2)。
277
+ *
278
+ * 前缀计入工具名,而工具名进**每一次**请求 —— 长 sourceId 是持续成本。
279
+ * 装配期校验并给出可读错误,比运行时被 provider 拒掉好查。
280
+ */
281
+ const WEB_MCP_SOURCE_ID_MAX = 24;
282
+ /**
283
+ * WebMCP 工具的 LLM 可见名。
284
+ *
285
+ * 多来源时带来源前缀(FR-26.2):三个文档都注册 `get_current_date` 是常态,
286
+ * 「首个来源优先」是**静默歧义** —— 模型选中的到底是哪个,谁也说不清。
287
+ * 不传 sourceId 时保持 0.10.0 的旧名,单来源宿主无感。
288
+ */
289
+ function webMcpToolLlmName(toolName, sourceId) {
290
+ return sourceId === void 0 ? `mcp__${toolName}` : `mcp__${sourceId}__${toolName}`;
272
291
  }
273
- function parseWebMcpToolLlmName(llmName) {
274
- return llmName.startsWith("mcp__") && llmName.length > 5 ? llmName.slice(5) : void 0;
292
+ /** 解析回 `{ sourceId?, toolName }`;旧名(无来源段)解析出 `sourceId: undefined` */
293
+ function parseWebMcpToolLlmName(llmName, sourceIds = []) {
294
+ if (!llmName.startsWith("mcp__") || llmName.length <= 5) return void 0;
295
+ const rest = llmName.slice(5);
296
+ for (const sourceId of sourceIds) {
297
+ const sourcePrefix = `${sourceId}__`;
298
+ if (rest.startsWith(sourcePrefix) && rest.length > sourcePrefix.length) return {
299
+ sourceId,
300
+ toolName: rest.slice(sourcePrefix.length)
301
+ };
302
+ }
303
+ return { toolName: rest };
275
304
  }
276
305
  const textOfContent = (content) => {
277
306
  if (typeof content === "string") return content;
@@ -354,6 +383,10 @@ async function loadFromJSONSchema() {
354
383
  throw new WebSkillError("MCP_ENDPOINT_UNAVAILABLE", "The \"zod\" package is required to serve skills as MCP tools; install it first (npm i zod)", e);
355
384
  }
356
385
  }
386
+ /** MCP 的 structuredContent 必须是对象(规范用 `z.record`):数组与标量不适用 */
387
+ function isPlainObject(value) {
388
+ return typeof value === "object" && value !== null && !Array.isArray(value);
389
+ }
357
390
  /** 注册端:在页面 MCP server 上一行声明动态技能(prompt + resources + tools) */
358
391
  async function serveSkillAsMcp(server, skill) {
359
392
  server.registerPrompt(skill.name, { description: skill.description }, async () => ({ messages: [{
@@ -372,13 +405,18 @@ async function serveSkillAsMcp(server, skill) {
372
405
  description: tool.description ?? "",
373
406
  ...tool.inputSchema ? { inputSchema: (await loadFromJSONSchema())(tool.inputSchema) } : {}
374
407
  }, async (args) => {
375
- return { content: normalizeToolContent(await tool.handler(args ?? {})).map((item) => item.type === "text" ? {
408
+ const value = await tool.handler(args ?? {});
409
+ const content = normalizeToolContent(value).map((item) => item.type === "text" ? {
376
410
  type: "text",
377
411
  text: item.text ?? ""
378
412
  } : {
379
413
  type: "text",
380
414
  text: JSON.stringify(item.data ?? null)
381
- }) };
415
+ });
416
+ return isPlainObject(value) ? {
417
+ content,
418
+ structuredContent: value
419
+ } : { content };
382
420
  });
383
421
  }
384
422
  /**
@@ -394,6 +432,14 @@ const failure = (code, message) => ({
394
432
  message
395
433
  }
396
434
  });
435
+ /**
436
+ * `executeTool` 按 MCP 规范返回 `{ content: [...] }`,但也有页面直接返回分片数组或裸值。
437
+ * 先解包 `content` 再归一——不解包的话规范形状会被整体序列化成一段 JSON 文本,
438
+ * 模型读到的不是工具答案而是一层信封。与 McpToolResolver 同一口径。
439
+ */
440
+ function unwrapToolContent(raw) {
441
+ return normalizeToolContent((typeof raw === "object" && raw !== null ? raw.content : void 0) ?? raw);
442
+ }
397
443
  /** getTools() 返回的工具 → 描述符:inputSchema 为 JSON 字符串时解析为对象,并保留原始对象 */
398
444
  function toDescriptor(raw) {
399
445
  if (typeof raw !== "object" || raw === null) return void 0;
@@ -437,9 +483,19 @@ function extractToolDescriptors(raw) {
437
483
  var ExperimentalWebMcpAdapter = class {
438
484
  #resolveApi;
439
485
  #enabled;
486
+ /**
487
+ * 多来源时的消歧标识(分册 26 FR-26.2)。不设即沿用 0.10.0 的旧工具名,
488
+ * 单来源宿主无感;**两个以上来源必须各自设**,否则同名工具会撞车。
489
+ */
490
+ sourceId;
440
491
  constructor(api, options) {
441
492
  this.#resolveApi = typeof api === "function" ? api : () => api;
442
493
  this.#enabled = options?.enabled ?? false;
494
+ if (options?.sourceId !== void 0) {
495
+ if (!/^[a-zA-Z0-9-]+$/.test(options.sourceId)) throw new WebSkillError("VALIDATION_FAILED", `WebMCP sourceId "${options.sourceId}" may only contain letters, digits and hyphens.`);
496
+ if (options.sourceId.length > 24) throw new WebSkillError("VALIDATION_FAILED", `WebMCP sourceId "${options.sourceId}" is longer than 24 characters; it is prefixed onto every tool name and therefore costs tokens on every request.`);
497
+ this.sourceId = options.sourceId;
498
+ }
443
499
  }
444
500
  /**
445
501
  * 宿主能力检测(FR-19.2/19.4):**只**看 `document.modelContext.executeTool` 是否存在,
@@ -486,7 +542,7 @@ var ExperimentalWebMcpAdapter = class {
486
542
  const tool = match?.raw ?? { name: toolName };
487
543
  return {
488
544
  ok: true,
489
- content: normalizeToolContent(await api.executeTool(tool, argsJson))
545
+ content: unwrapToolContent(await api.executeTool(tool, argsJson))
490
546
  };
491
547
  } catch (e) {
492
548
  return failure("TOOL_EXECUTION_FAILED", `WebMCP tool "${toolName}" failed: ${messageOf(e)}`);
@@ -494,7 +550,7 @@ var ExperimentalWebMcpAdapter = class {
494
550
  try {
495
551
  return {
496
552
  ok: true,
497
- content: normalizeToolContent(await api.executeTool(toolName, argsJson))
553
+ content: unwrapToolContent(await api.executeTool(toolName, argsJson))
498
554
  };
499
555
  } catch (e) {
500
556
  return failure("TOOL_EXECUTION_FAILED", `WebMCP tool "${toolName}" failed: ${messageOf(e)}`);
@@ -517,15 +573,22 @@ var McpRuntimePlugin = class {
517
573
  kind = "mcp";
518
574
  #registry;
519
575
  #resolver;
576
+ /**
577
+ * 多来源(分册 26 FR-26.1):**不做聚合适配器**。
578
+ * 聚合会让「部分来源可用」无法回答,把 0.9.0 刚理清的
579
+ * 「不支持 / 未启用」二分重新搅浑。这里逐个问,不合并成一个布尔。
580
+ */
520
581
  #webMcp;
521
582
  #visibility;
583
+ #trust;
522
584
  #configuredEndpoints;
523
585
  #onWarning;
524
586
  constructor(deps) {
525
587
  this.#registry = deps.registry;
526
588
  this.#resolver = deps.resolver ?? new McpToolResolver(deps.registry);
527
- this.#webMcp = deps.webMcp;
589
+ this.#webMcp = deps.webMcp ?? [];
528
590
  this.#visibility = deps.visibility;
591
+ this.#trust = deps.trust;
529
592
  this.#configuredEndpoints = deps.endpoints ?? [];
530
593
  this.#onWarning = deps.onWarning ?? ((message) => console.warn(message));
531
594
  }
@@ -549,6 +612,40 @@ var McpRuntimePlugin = class {
549
612
  return true;
550
613
  }
551
614
  }
615
+ /**
616
+ * 信任回调统一求值。**刻意不复用 `#visible()`**:两者的失败代价不对称。
617
+ * 可见性判不出来最坏是工具从列表里消失;信任判不出来而放行,落盘的就是明文。
618
+ * 因此这里缺省 false、异常也按 false,并同样走 onWarning。
619
+ */
620
+ #trusted(probe) {
621
+ try {
622
+ return probe() === true;
623
+ } catch (e) {
624
+ this.#onWarning(`[webskill] MCP trust callback failed; treating the source as untrusted: ${e instanceof Error ? e.message : String(e)}`);
625
+ return false;
626
+ }
627
+ }
628
+ /**
629
+ * 参数留存的信任判定(分册 30 / FR-30.6)。
630
+ * 只按宿主配置里的 endpoint / sourceId 判,服务器传回的内容进不了这条路径。
631
+ */
632
+ argCaptureTrust(llmToolName) {
633
+ const parsed = parseWebMcpToolLlmName(llmToolName, this.#sourceIds());
634
+ if (parsed !== void 0) {
635
+ if (!this.#trusted(() => this.#trust?.isWebMcpSourceTrusted?.(parsed.sourceId))) return void 0;
636
+ return {
637
+ tier: "host-trusted",
638
+ declaredBy: `webmcp:${parsed.sourceId ?? ""}`
639
+ };
640
+ }
641
+ const endpoint = this.#endpoints().find((name) => parseEndpointToolLlmName(name, llmToolName) !== void 0);
642
+ if (endpoint === void 0) return void 0;
643
+ if (!this.#trusted(() => this.#trust?.isEndpointTrusted?.(endpoint))) return void 0;
644
+ return {
645
+ tier: "host-trusted",
646
+ declaredBy: endpoint
647
+ };
648
+ }
552
649
  async listToolSpecs() {
553
650
  const specs = [];
554
651
  for (const endpoint of this.#endpoints()) {
@@ -570,12 +667,13 @@ var McpRuntimePlugin = class {
570
667
  this.#onWarning(`[webskill] MCP endpoint "${endpoint}" is unavailable; its tools are omitted from this turn: ${e instanceof Error ? e.message : String(e)}`);
571
668
  }
572
669
  }
573
- if (this.#webMcp?.isEnabled()) {
574
- const tools = await this.#webMcp.listTools();
670
+ for (const source of this.#webMcp) {
671
+ if (!source.isEnabled()) continue;
672
+ const tools = await source.listTools();
575
673
  for (const tool of tools ?? []) {
576
- if (!this.#visible(() => this.#visibility?.isWebMcpToolEnabled?.(tool.name))) continue;
674
+ if (!this.#visible(() => this.#visibility?.isWebMcpToolEnabled?.(tool.name, source.sourceId))) continue;
577
675
  specs.push({
578
- name: webMcpToolLlmName(tool.name),
676
+ name: webMcpToolLlmName(tool.name, source.sourceId),
579
677
  description: tool.description ?? `[webmcp] ${tool.name}`,
580
678
  inputSchema: typeof tool.inputSchema === "object" && tool.inputSchema !== null ? tool.inputSchema : {
581
679
  type: "object",
@@ -586,14 +684,19 @@ var McpRuntimePlugin = class {
586
684
  }
587
685
  return specs;
588
686
  }
687
+ /** 已知来源标识;解析工具名时用它切分,避免把工具名里的 `__` 当成来源分隔 */
688
+ #sourceIds() {
689
+ return this.#webMcp.map((source) => source.sourceId).filter((id) => id !== void 0);
690
+ }
589
691
  canHandle(llmToolName) {
590
- if (parseWebMcpToolLlmName(llmToolName) !== void 0) return true;
692
+ if (parseWebMcpToolLlmName(llmToolName, this.#sourceIds()) !== void 0) return true;
591
693
  return this.#endpoints().some((endpoint) => parseEndpointToolLlmName(endpoint, llmToolName) !== void 0);
592
694
  }
593
695
  async call(llmToolName, args) {
594
- const webMcpTool = parseWebMcpToolLlmName(llmToolName);
595
- if (webMcpTool !== void 0) {
596
- if (!this.#webMcp) return {
696
+ const parsed = parseWebMcpToolLlmName(llmToolName, this.#sourceIds());
697
+ if (parsed !== void 0) {
698
+ const source = parsed.sourceId === void 0 ? this.#webMcp.find((candidate) => candidate.sourceId === void 0) : this.#webMcp.find((candidate) => candidate.sourceId === parsed.sourceId);
699
+ if (source === void 0) return {
597
700
  ok: false,
598
701
  content: [],
599
702
  error: {
@@ -601,8 +704,8 @@ var McpRuntimePlugin = class {
601
704
  message: "WebMCP adapter is not configured"
602
705
  }
603
706
  };
604
- if (!this.#visible(() => this.#visibility?.isWebMcpToolEnabled?.(webMcpTool))) return disabledResult(llmToolName);
605
- return this.#webMcp.call(webMcpTool, args);
707
+ if (!this.#visible(() => this.#visibility?.isWebMcpToolEnabled?.(parsed.toolName, source.sourceId))) return disabledResult(llmToolName);
708
+ return source.call(parsed.toolName, args);
606
709
  }
607
710
  for (const endpoint of this.#endpoints()) {
608
711
  const toolName = parseEndpointToolLlmName(endpoint, llmToolName);
@@ -893,4 +996,4 @@ async function connectRemoteEndpoint(registry, config) {
893
996
  }
894
997
 
895
998
  //#endregion
896
- export { EndpointRegistry, ExperimentalWebMcpAdapter, McpRuntimePlugin, McpToolResolver, MessageChannelTransport, TemporarySkillProvider, catalogMerge, connectRemoteEndpoint, createMemoryOAuthStores, createOAuthProvider, endpointToolLlmName, parseEndpointToolLlmName, parseWebMcpToolLlmName, serveSkillAsMcp, validateJsonRpcMessage, webMcpToolLlmName };
999
+ export { EndpointRegistry, ExperimentalWebMcpAdapter, McpRuntimePlugin, McpToolResolver, MessageChannelTransport, TemporarySkillProvider, WEB_MCP_SOURCE_ID_MAX, catalogMerge, connectRemoteEndpoint, createMemoryOAuthStores, createOAuthProvider, endpointToolLlmName, parseEndpointToolLlmName, parseWebMcpToolLlmName, serveSkillAsMcp, validateJsonRpcMessage, webMcpToolLlmName };
package/dist/node.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { $ as SignatureAuditSink, B as JsonSchema, Ct as VerifyResult, J as SKILL_MANIFEST_FILE, L as FileStat, M as ArchiveLimits, R as FileSystemProvider, S as UiBridge, _t as SkillsLockfile, b as RenderResultRequest, c as InteractionResponse, dt as SkillManifest, q as SKILLS_LOCKFILE, s as InteractionRequest, st as SkillInstallSource, ut as SkillManagerPort, xt as UnsignedPolicy, yt as TrustedKeyStore } from "./types-CrRcT-LM-DZAp8sWv.js";
2
- import { Dt as ScriptExecutor, Et as ScriptExecutionContext, Jt as ToolDefinition, M as FsMemoryStore, Tt as SchemaInferer, Xt as ToolResult, Y as NetworkPolicy, _ as BridgeCapabilities, bn as createScriptContext, f as ApprovalScope, hn as WebSkillRuntimeDeps, j as FsArtifactStore, mn as WebSkillRuntime } from "./index-DtFdMKBX.js";
3
- import { a as AuditLog, b as SkillVersionStore, d as CandidateSkill, m as CandidateStore, r as ApprovalPolicy } from "./skillVersionStore-D-qHk9ZE-DBsYYCWn.js";
1
+ import { $ as SignatureAuditSink, B as JsonSchema, Ct as VerifyResult, J as SKILL_MANIFEST_FILE, L as FileStat, M as ArchiveLimits, R as FileSystemProvider, S as UiBridge, _t as SkillsLockfile, b as RenderResultRequest, c as InteractionResponse, dt as SkillManifest, q as SKILLS_LOCKFILE, s as InteractionRequest, st as SkillInstallSource, ut as SkillManagerPort, xt as UnsignedPolicy, yt as TrustedKeyStore } from "./types-DLctJep_-B5G4uk2u.js";
2
+ import { Bn as createScriptContext, Bt as ScriptExecutionContext, Fn as WebSkillRuntimeDeps, L as FsArtifactStore, Pn as WebSkillRuntime, R as FsMemoryStore, Vt as ScriptExecutor, dn as ToolResult, it as NetworkPolicy, ln as ToolDefinition, m as ApprovalScope, y as BridgeCapabilities, zt as SchemaInferer } from "./index-C9pzXLKy.js";
3
+ import { a as AuditLog, b as SkillVersionStore, d as CandidateSkill, m as CandidateStore, r as ApprovalPolicy } from "./skillVersionStore-D-qHk9ZE-DheTIwAB.js";
4
4
  import { n as LlmEnvConfig, s as probeLlmCapabilities, t as LlmCapabilities } from "./env-AK3cSMEA-Dli6QU5E.js";
5
5
  import { Readable, Writable } from "node:stream";
6
6
  //#region ../node/dist/index.d.ts
package/dist/node.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { B as resolveArchiveLimits, D as exportSkills, F as parseSkillPackManifest, G as unzipWithLimits, I as readResponseWithLimit, J as verifySkillSignature, K as validateSkills, L as readSkillSignature, M as messageOf, O as isAtomicTempPath, P as parseSkillMarkdown, V as resolveInsideRoot, _ as assertSafePathSegment, b as buildManifest, c as SKILL_MANIFEST_FILE, d as SKILL_PACK_FILE, g as assertRemoteUrlAllowed, h as WebSkillError, i as MANIFEST_EXCLUDED_FILES, k as isValidSkillName, q as verifyManifest, s as SKILLS_LOCKFILE, v as atomicWriteText } from "./dist-Bev6i6Ip.js";
2
- import { B as bridgeError, H as createScriptContext, L as WebSkillRuntime, c as CapabilityApproval, dt as parseBridgeRequest, h as FsMemoryStore, lt as normalizeToolContent, m as FsArtifactStore, ot as networkPolicyLibSource, ut as normalizeToolError } from "./dist-BViUeszk.js";
2
+ import { $ as bridgeError, Ct as normalizeToolError, St as normalizeToolContent, X as WebSkillRuntime, b as FsMemoryStore, tt as createScriptContext, u as CapabilityApproval, wt as parseBridgeRequest, y as FsArtifactStore, yt as networkPolicyLibSource } from "./dist-sdKFgERo.js";
3
3
  import { i as probeLlmCapabilities } from "./env-8cY40DXB-CGnEVZby.js";
4
- import { t as AUDIT_EVENT_TYPES } from "./eventTypes-s2uwAcLG-Go3l_dUe.js";
4
+ import { t as AUDIT_EVENT_TYPES } from "./eventTypes-FllCrX-Z-DNDeHWoG.js";
5
5
  import { createRequire } from "node:module";
6
6
  import { unzipSync, zipSync } from "fflate";
7
7
  import { existsSync, promises, realpathSync } from "node:fs";
@@ -336,6 +336,8 @@ var SandboxedScriptExecutor = class {
336
336
  this.#options = options;
337
337
  this.#capabilities = {
338
338
  readReference: options.capabilities?.readReference ?? true,
339
+ readAsset: options.capabilities?.readAsset ?? true,
340
+ fetchData: options.capabilities?.fetchData ?? false,
339
341
  writeArtifact: options.capabilities?.writeArtifact ?? true,
340
342
  confirm: options.capabilities?.confirm ?? true
341
343
  };
@@ -509,6 +511,29 @@ var SandboxedScriptExecutor = class {
509
511
  value: await context.readReference(request.path)
510
512
  };
511
513
  }
514
+ case "readAsset":
515
+ case "readAssetBinary": {
516
+ const read = request.kind === "readAsset" ? context.readAsset : context.readAssetBinary;
517
+ if (!read) return bridgeError(request.id, "TOOL_UNSUPPORTED", "Capability \"readAsset\" is disabled");
518
+ const denied = await gate("readAsset", `Script "${context.skillName}" wants to read asset "${request.path}"`, { path: request.path });
519
+ if (denied) return denied;
520
+ const value = await read(request.path);
521
+ return {
522
+ id: request.id,
523
+ ok: true,
524
+ value: typeof value === "string" ? value : Array.from(value)
525
+ };
526
+ }
527
+ case "fetchData": {
528
+ if (!context.fetchData) return bridgeError(request.id, "TOOL_UNSUPPORTED", "Capability \"fetchData\" is disabled");
529
+ const denied = await gate("fetchData", `Script "${context.skillName}" wants to fetch data source "${request.sourceId}"`, { sourceId: request.sourceId });
530
+ if (denied) return denied;
531
+ return {
532
+ id: request.id,
533
+ ok: true,
534
+ value: await context.fetchData(request.sourceId, request.params)
535
+ };
536
+ }
512
537
  case "writeArtifact": {
513
538
  const denied = await gate("writeArtifact", `Script "${context.skillName}" wants to write artifact "${request.path}"`, {
514
539
  path: request.path,
@@ -516,7 +541,10 @@ var SandboxedScriptExecutor = class {
516
541
  });
517
542
  if (denied) return denied;
518
543
  const content = typeof request.content === "string" ? request.content : new Uint8Array(request.content);
519
- const artifact = await context.writeArtifact(request.path, content, { ...request.mimeType ? { mimeType: request.mimeType } : {} });
544
+ const artifact = await context.writeArtifact(request.path, content, {
545
+ ...request.mimeType ? { mimeType: request.mimeType } : {},
546
+ ...request.metadata === void 0 ? {} : { metadata: request.metadata }
547
+ });
520
548
  return {
521
549
  id: request.id,
522
550
  ok: true,
@@ -578,6 +606,8 @@ var ProcessSandboxExecutor = class {
578
606
  this.#options = options;
579
607
  this.#capabilities = {
580
608
  readReference: options.capabilities?.readReference ?? true,
609
+ readAsset: options.capabilities?.readAsset ?? true,
610
+ fetchData: options.capabilities?.fetchData ?? false,
581
611
  writeArtifact: options.capabilities?.writeArtifact ?? true,
582
612
  confirm: options.capabilities?.confirm ?? true
583
613
  };
@@ -858,6 +888,29 @@ var ProcessSandboxExecutor = class {
858
888
  value: await context.readReference(request.path)
859
889
  };
860
890
  }
891
+ case "readAsset":
892
+ case "readAssetBinary": {
893
+ const read = request.kind === "readAsset" ? context.readAsset : context.readAssetBinary;
894
+ if (!read) return bridgeError(request.id, "TOOL_UNSUPPORTED", "Capability \"readAsset\" is disabled");
895
+ const denied = await gate("readAsset", `Script "${context.skillName}" wants to read asset "${request.path}"`, { path: request.path });
896
+ if (denied) return denied;
897
+ const value = await read(request.path);
898
+ return {
899
+ id: request.id,
900
+ ok: true,
901
+ value: typeof value === "string" ? value : Array.from(value)
902
+ };
903
+ }
904
+ case "fetchData": {
905
+ if (!context.fetchData) return bridgeError(request.id, "TOOL_UNSUPPORTED", "Capability \"fetchData\" is disabled");
906
+ const denied = await gate("fetchData", `Script "${context.skillName}" wants to fetch data source "${request.sourceId}"`, { sourceId: request.sourceId });
907
+ if (denied) return denied;
908
+ return {
909
+ id: request.id,
910
+ ok: true,
911
+ value: await context.fetchData(request.sourceId, request.params)
912
+ };
913
+ }
861
914
  case "writeArtifact": {
862
915
  const denied = await gate("writeArtifact", `Script "${context.skillName}" wants to write artifact "${request.path}"`, {
863
916
  path: request.path,
@@ -865,7 +918,10 @@ var ProcessSandboxExecutor = class {
865
918
  });
866
919
  if (denied) return denied;
867
920
  const content = typeof request.content === "string" ? request.content : new Uint8Array(request.content);
868
- const artifact = await context.writeArtifact(request.path, content, { ...request.mimeType ? { mimeType: request.mimeType } : {} });
921
+ const artifact = await context.writeArtifact(request.path, content, {
922
+ ...request.mimeType ? { mimeType: request.mimeType } : {},
923
+ ...request.metadata === void 0 ? {} : { metadata: request.metadata }
924
+ });
869
925
  return {
870
926
  id: request.id,
871
927
  ok: true,
@@ -1,5 +1,5 @@
1
- import { ft as uiCatalog } from "./dist-1OFC-zax.js";
2
- import { t as CatalogNode } from "./catalogComponents-DTcYfpLQ-CcoOaz-Z.js";
1
+ import { Dt as uiCatalog } from "./dist-DqcL6jKO.js";
2
+ import { t as CatalogNode } from "./catalogComponents-BgAJN0p8-C3K8klJd.js";
3
3
  import { z } from "zod";
4
4
  import { Component, Fragment, createContext, useCallback, useContext, useEffect, useInsertionEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -3761,7 +3761,7 @@ function Renderer({ response, library, isStreaming = false, onAction, onStateUpd
3761
3761
  const FormValidationContext = createContext(null);
3762
3762
 
3763
3763
  //#endregion
3764
- //#region ../ui-react/dist/openUiLibrary-CIrV--Ad.js
3764
+ //#region ../ui-react/dist/openUiLibrary-BKXW7Iwx.js
3765
3765
  const propsFor = (props, container) => container ? props.extend({ children: z.array(z.any()).optional() }) : props;
3766
3766
  /**
3767
3767
  * catalog 的 OpenUI 投影:`defineComponent` 复用同一份 zod schema 与描述,
@@ -165,10 +165,17 @@ async function main(task) {
165
165
  skillName: task.skillName ?? "",
166
166
  runId: task.runId ?? "",
167
167
  readReference: (path) => callCapability("readReference", { path }),
168
+ readAsset: (path) => callCapability("readAsset", { path }),
169
+ fetchData: (sourceId, params) => callCapability("fetchData", {
170
+ sourceId,
171
+ params
172
+ }),
173
+ readAssetBinary: async (path) => new Uint8Array(await callCapability("readAssetBinary", { path })),
168
174
  writeArtifact: (path, content, options) => callCapability("writeArtifact", {
169
175
  path,
170
176
  content: typeof content === "string" ? content : Array.from(content ?? []),
171
- mimeType: options?.mimeType
177
+ mimeType: options?.mimeType,
178
+ metadata: options?.metadata
172
179
  }),
173
180
  confirm: (message) => callCapability("confirm", { message })
174
181
  };
@@ -226,10 +226,17 @@ async function main() {
226
226
  skillName: task.skillName ?? "",
227
227
  runId: task.runId ?? "",
228
228
  readReference: (path) => callCapability("readReference", { path }),
229
+ readAsset: (path) => callCapability("readAsset", { path }),
230
+ fetchData: (sourceId, params) => callCapability("fetchData", {
231
+ sourceId,
232
+ params
233
+ }),
234
+ readAssetBinary: async (path) => new Uint8Array(await callCapability("readAssetBinary", { path })),
229
235
  writeArtifact: (path, content, options) => callCapability("writeArtifact", {
230
236
  path,
231
237
  content: typeof content === "string" ? content : Array.from(content ?? []),
232
- mimeType: options?.mimeType
238
+ mimeType: options?.mimeType,
239
+ metadata: options?.metadata
233
240
  }),
234
241
  confirm: (message) => callCapability("confirm", { message })
235
242
  };
@@ -1,4 +1,4 @@
1
- import { R as FileSystemProvider, U as Page, W as PageQuery, dt as SkillManifest, it as SkillCatalogEntry } from "./types-CrRcT-LM-DZAp8sWv.js";
1
+ import { R as FileSystemProvider, U as Page, W as PageQuery, dt as SkillManifest, it as SkillCatalogEntry } from "./types-DLctJep_-B5G4uk2u.js";
2
2
  //#region ../governance/dist/skillVersionStore-D-qHk9ZE.d.ts
3
3
  //#region src/types.d.ts
4
4
  type CandidateStatus = 'draft' | 'pending-review' | 'approved' | 'published' | 'rejected';
package/dist/testing.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { S as UiBridge, c as InteractionResponse, l as LlmClient, m as LlmStreamEvent, n as ArtifactStore, p as LlmResponse, s as InteractionRequest, t as Artifact, u as LlmCompleteInput, v as MemoryStore } from "./types-CrRcT-LM-DZAp8sWv.js";
1
+ import { S as UiBridge, c as InteractionResponse, l as LlmClient, m as LlmStreamEvent, n as ArtifactStore, p as LlmResponse, s as InteractionRequest, t as Artifact, u as LlmCompleteInput, v as MemoryStore } from "./types-DLctJep_-B5G4uk2u.js";
2
2
  import { a as loadGoogleConfigFromEnv, i as loadAnthropicConfigFromEnv, n as LlmEnvConfig, o as loadLlmConfigFromEnv, r as ProviderEnvConfig } from "./env-AK3cSMEA-Dli6QU5E.js";
3
3
  //#region ../runtime/dist/testing.d.ts
4
4
  //#region src/llm/mockLlmClient.d.ts
@@ -2,7 +2,15 @@
2
2
  //#region src/errors.d.ts
3
3
  type WebSkillErrorCode = 'FS_NOT_FOUND' | 'FS_PATH_OUTSIDE_ROOT' | 'SKILL_NOT_FOUND' | 'SKILL_INVALID_METADATA' | 'SKILL_INVALID_NAME' | 'SKILL_DUPLICATE_NAME' | 'SKILL_UNSUPPORTED_SCRIPT' | 'SKILL_MANIFEST_PROTECTED' | 'VALIDATION_FAILED' | 'TOOL_NOT_FOUND' | 'TOOL_EXECUTION_FAILED' | 'NETWORK_BLOCKED' | 'TOOL_UNSUPPORTED' | 'TOOL_NOT_ALLOWED' | 'TOOL_SCHEMA_UNAVAILABLE' | 'TOOL_RESOLUTION_EXHAUSTED' | 'RUN_TIMEOUT' | 'RUN_MAX_TURNS_EXCEEDED' | 'RUN_FAILED' | 'RUN_CANCELLED' | 'RUN_INTERACTION_TIMEOUT' |
4
4
  /** 历史里有未应答的工具调用,但当初为何中断已无从得知(分册 11 读取侧补齐) */
5
- 'RUN_INTERRUPTED' | 'UI_UNAVAILABLE' | 'LLM_UNAVAILABLE' | 'LLM_REQUEST_FAILED' | 'INSTALL_FAILED' | 'UNINSTALL_FAILED' | 'EXPORT_FAILED' | 'INTEGRITY_FAILED' | 'FS_PERMISSION_DENIED' | 'MCP_ENDPOINT_UNAVAILABLE' | 'MCP_TOOL_NOT_FOUND' | 'CANDIDATE_INVALID' | 'APPROVAL_REQUIRED' | 'SKILL_QUARANTINED' | 'SKILL_DISABLED' | 'SKILL_UNKNOWN_ALLOWED_TOOL' | 'SKILL_UNKNOWN_DEPENDENCY' | 'SKILL_CIRCULAR_DEPENDENCY' | 'GOVERNANCE_FAILED' | 'RUN_SNAPSHOT_NOT_FOUND' | 'RUN_SNAPSHOT_EXPIRED' | 'RUN_SNAPSHOT_INCOMPATIBLE' | 'RUN_SNAPSHOT_SCHEMA_UNSUPPORTED' | 'RUN_TRACE_INCOMPATIBLE' | 'SESSION_INCOMPATIBLE' | 'SIGNATURE_MISSING' | 'SIGNATURE_MALFORMED' | 'SIGNATURE_UNTRUSTED_KEY' | 'SIGNATURE_MISMATCH' | 'SIGNATURE_UNSUPPORTED' | 'MCP_STDIO_SPAWN_FAILED' | 'MCP_STDIO_EXITED' | 'MCP_STDIO_TIMEOUT' | 'MCP_OAUTH_REQUIRED' | 'MCP_OAUTH_FAILED' | 'MCP_OAUTH_NOT_CONFIGURED' | 'PAGE_ACTION_OUT_OF_SCOPE' | 'PAGE_ACTION_STALE_REF' | 'PAGE_ACTION_DECLINED' | 'TS_RESOURCE_URL_REJECTED' | 'TS_TRANSPILER_UNAVAILABLE' | 'TS_TRANSPILE_FAILED' | 'TODO_LIST_INVALID' | 'TODO_ITEM_NOT_FOUND' | 'SKILL_GENERATION_DISABLED' | 'SKILL_GENERATION_LIMIT_EXCEEDED' | 'SKILL_GENERATION_VALIDATION_FAILED' | 'DELEGATION_UNAVAILABLE' | 'DELEGATION_IN_PROGRESS' | 'DELEGATION_BUDGET_EXCEEDED' | 'PROFILE_IMPORT_INVALID' | 'PROFILE_IMPORT_VERSION_UNSUPPORTED' | 'PROFILE_IMPORT_CREDENTIAL_REJECTED' | 'PROFILE_KEY_UNAVAILABLE' | 'DICTATION_UNAVAILABLE' | 'DICTATION_PERMISSION_DENIED' | 'DICTATION_FAILED' | 'PERCEPTION_NOT_ENABLED' | 'PERCEPTION_FAILED' | 'MODEL_IMAGE_UNSUPPORTED' | 'MODEL_TOOLS_UNSUPPORTED' | 'ATTACHMENT_TOO_LARGE' | 'ATTACHMENT_TYPE_REJECTED';
5
+ 'RUN_INTERRUPTED' | 'UI_UNAVAILABLE' | 'LLM_UNAVAILABLE' | 'LLM_REQUEST_FAILED' | 'INSTALL_FAILED' | 'UNINSTALL_FAILED' | 'EXPORT_FAILED' | 'INTEGRITY_FAILED' | 'FS_PERMISSION_DENIED' | 'MCP_ENDPOINT_UNAVAILABLE' | 'MCP_TOOL_NOT_FOUND' | 'CANDIDATE_INVALID' | 'APPROVAL_REQUIRED' | 'SKILL_QUARANTINED' | 'SKILL_DISABLED' | 'SKILL_UNKNOWN_ALLOWED_TOOL' | 'SKILL_UNKNOWN_DEPENDENCY' | 'SKILL_CIRCULAR_DEPENDENCY' | 'GOVERNANCE_FAILED' | 'RUN_SNAPSHOT_NOT_FOUND' | 'RUN_SNAPSHOT_EXPIRED' | 'RUN_SNAPSHOT_INCOMPATIBLE' | 'RUN_SNAPSHOT_SCHEMA_UNSUPPORTED' | 'RUN_TRACE_INCOMPATIBLE' | 'SESSION_INCOMPATIBLE' | 'SIGNATURE_MISSING' | 'SIGNATURE_MALFORMED' | 'SIGNATURE_UNTRUSTED_KEY' | 'SIGNATURE_MISMATCH' | 'SIGNATURE_UNSUPPORTED' | 'MCP_STDIO_SPAWN_FAILED' | 'MCP_STDIO_EXITED' | 'MCP_STDIO_TIMEOUT' | 'MCP_OAUTH_REQUIRED' | 'MCP_OAUTH_FAILED' | 'MCP_OAUTH_NOT_CONFIGURED' | 'PAGE_ACTION_OUT_OF_SCOPE' | 'PAGE_ACTION_STALE_REF' | 'PAGE_ACTION_DECLINED' |
6
+ /** 0.11.0 分册 18:用户拒绝把数据交给文档投放面 */
7
+ 'DOCUMENT_SURFACE_DECLINED' |
8
+ /** 0.11.0 分册 18:viewer 未在期限内回报就绪(路由挂了 / 外壳脚本没跑起来) */
9
+ 'DOCUMENT_SURFACE_UNAVAILABLE' | 'TS_RESOURCE_URL_REJECTED' | 'TS_TRANSPILER_UNAVAILABLE' | 'TS_TRANSPILE_FAILED' | 'TODO_LIST_INVALID' | 'TODO_ITEM_NOT_FOUND' | 'SKILL_GENERATION_DISABLED' | 'SKILL_GENERATION_LIMIT_EXCEEDED' | 'SKILL_GENERATION_VALIDATION_FAILED' | 'DELEGATION_UNAVAILABLE' | 'DELEGATION_IN_PROGRESS' | 'DELEGATION_BUDGET_EXCEEDED' | 'PROFILE_IMPORT_INVALID' | 'PROFILE_IMPORT_VERSION_UNSUPPORTED' | 'PROFILE_IMPORT_CREDENTIAL_REJECTED' | 'PROFILE_KEY_UNAVAILABLE' | 'DICTATION_UNAVAILABLE' | 'DICTATION_PERMISSION_DENIED' | 'DICTATION_FAILED' | 'PERCEPTION_NOT_ENABLED' | 'PERCEPTION_FAILED' | 'MODEL_IMAGE_UNSUPPORTED' | 'MODEL_DOCUMENT_UNSUPPORTED' | 'MODEL_TOOLS_UNSUPPORTED' | 'ATTACHMENT_TOO_LARGE' | 'ATTACHMENT_TYPE_REJECTED' |
10
+ /** 脚本取了宿主未声明的数据源;拒绝发生在发出任何请求之前(0.11.0 分册 16) */
11
+ 'DATA_SOURCE_NOT_FOUND' |
12
+ /** 取数结果超预算。与 ATTACHMENT_TOO_LARGE 同口径:拒绝而不截断 */
13
+ 'DATA_SOURCE_TOO_LARGE';
6
14
  /**
7
15
  * 所有公开 API 抛出的结构化错误,code 供上层可编程处理
8
16
  * @stable
@@ -629,7 +637,7 @@ declare function escapeXml(text: string): string;
629
637
  declare function renderAvailableSkillsXml(catalog: SkillCatalog): string;
630
638
  declare const xmlRenderer: CatalogRenderer;
631
639
  //#endregion
632
- //#region ../runtime/dist/types-CrRcT-LM.d.ts
640
+ //#region ../runtime/dist/types-DLctJep_.d.ts
633
641
  //#region src/llm/streamTypes.d.ts
634
642
  /** 流式 LLM 事件(OpenAI SSE / Vercel fullStream 统一映射) */
635
643
  type LlmStreamEvent = {
@@ -696,6 +704,14 @@ interface LlmToolCall {
696
704
  arguments: Record<string, unknown>;
697
705
  /** 流式拼接后的 arguments 不是合法 JSON 时的错误描述;设置时 arguments 不可信 */
698
706
  argumentsParseError?: string;
707
+ /**
708
+ * 供应商自己的不透明随车数据,原样回放给**同一家**供应商。
709
+ *
710
+ * Gemini 的 thinking 模型会随 `functionCall` 下发 `thoughtSignature`,
711
+ * 下一轮不带回去就直接 400——丢掉它的后果是多轮工具调用整条链跑不通(UI-UX8 D5)。
712
+ * 内容对引擎不透明,也不得跨供应商传递。
713
+ */
714
+ vendor?: Record<string, unknown>;
699
715
  }
700
716
  /**
701
717
  * 一次模型调用的 token 用量(0.10.0 UI-UX5 #47)。
@@ -842,7 +858,7 @@ type InteractionRequest = {
842
858
  */
843
859
  type: 'authorize';
844
860
  id: string;
845
- capability: 'readReference' | 'writeArtifact' | 'confirm' | 'pageAction';
861
+ capability: 'readReference' | 'readAsset' | 'writeArtifact' | 'confirm' | 'fetchData' | 'pageAction' | 'readLinkedDocument';
846
862
  message: string;
847
863
  details?: unknown;
848
864
  });
@@ -863,7 +879,8 @@ interface InteractionSuggestion {
863
879
  }
864
880
  /** 图表规格($chart 约定的校验后形态;渲染单一来源在 ui/chart/miniChart) */
865
881
  interface ChartSpec {
866
- kind: 'bar' | 'line' | 'pie';
882
+ /** 取值与 catalog `Chart` props 枚举逐字一致(`ui/catalog/uiCatalog.ts`) */
883
+ kind: 'bar' | 'line' | 'area' | 'pie' | 'scatter' | 'stacked-bar' | 'dual-axis';
867
884
  title?: string;
868
885
  labels: string[];
869
886
  series: Array<{
@@ -1008,7 +1025,7 @@ interface FormField {
1008
1025
  name: string;
1009
1026
  label: string;
1010
1027
  /** `password` 的值不进 paramHistory、不进行为记录、不落会话(FR-23.7) */
1011
- type: 'text' | 'number' | 'boolean' | 'select' | 'textarea' | 'file' | 'password';
1028
+ type: 'text' | 'number' | 'boolean' | 'select' | 'textarea' | 'file' | 'password' | 'date';
1012
1029
  required?: boolean;
1013
1030
  description?: string;
1014
1031
  defaultValue?: unknown;