@webskill/sdk 0.3.0 → 0.4.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 (32) hide show
  1. package/dist/browser.d.ts +2 -2
  2. package/dist/browser.js +2 -6
  3. package/dist/{catalogComponents-C_V39rbF-BOHveMWa.js → catalogComponents-KsujmL4b-Clx1kCnU.js} +278 -122
  4. package/dist/{dist-rorEJsNi.js → dist-C-Sh0MDU.js} +498 -282
  5. package/dist/{dist-ZKaM8j06.js → dist-D9Lcn5Pp.js} +527 -837
  6. package/dist/governance.d.ts +45 -10
  7. package/dist/governance.js +151 -24
  8. package/dist/{index-wiV5X8Rz.d.ts → index-CHXxDccV.d.ts} +62 -144
  9. package/dist/{index-8d-oEDww.d.ts → index-DLfR2Y6I.d.ts} +215 -23
  10. package/dist/index.d.ts +3 -3
  11. package/dist/index.js +3 -2
  12. package/dist/mcp.d.ts +2 -2
  13. package/dist/mcp.js +1 -1
  14. package/dist/memoryArtifactStore-BtOeB_hm-tj3fC5ip.js +78 -0
  15. package/dist/node.d.ts +8 -4
  16. package/dist/node.js +1 -1
  17. package/dist/{openUiLibrary-B8-Cvou9-BbpNTXS3.js → openUiLibrary-YLS-cxyT-C96jWDQq.js} +6 -5
  18. package/dist/{skillVersionStore-DOEI9ptb-BxbYL70B.d.ts → skillVersionStore-uyefLPR1-DXOzbksv.d.ts} +41 -10
  19. package/dist/{testing-CsrG3XLz.js → testing-DDCJWvgA.js} +7 -5
  20. package/dist/testing.d.ts +1 -1
  21. package/dist/testing.js +2 -2
  22. package/dist/{types-AmKCKJn_-VGabeXK4.d.ts → types-7Wcg--Vh-1YlQ4jF9.d.ts} +85 -71
  23. package/dist/ui-react.d.ts +329 -18
  24. package/dist/ui-react.js +3714 -3463
  25. package/dist/ui-vue.d.ts +1 -1
  26. package/dist/ui-vue.js +1 -1
  27. package/dist/ui.d.ts +4 -3
  28. package/dist/ui.js +3 -3
  29. package/dist/{webskillLitCatalog-CNaUpasU-BslMcxRZ.js → webskillLitCatalog-CSTbhBe_-CYIs5BX8.js} +312 -122
  30. package/package.json +1 -1
  31. package/dist/jsonRenderRegistry-9GrWP_hE-U6Do3Kid.js +0 -2468
  32. package/dist/memoryArtifactStore-C9lFVqPF-yFz6yJj0.js +0 -48
@@ -1,5 +1,5 @@
1
- import { ft as uiCatalog } from "./dist-ZKaM8j06.js";
2
- import { n as catalogComponentImpls } from "./catalogComponents-C_V39rbF-BOHveMWa.js";
1
+ import { q as uiCatalog } from "./dist-D9Lcn5Pp.js";
2
+ import { t as CatalogNode } from "./catalogComponents-KsujmL4b-Clx1kCnU.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-B8-Cvou9.js
3764
+ //#region ../ui-react/dist/openUiLibrary-YLS-cxyT.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 与描述,
@@ -3773,10 +3773,11 @@ const webskillOpenUiLibrary = createLibrary({
3773
3773
  name: def.name,
3774
3774
  description: def.description,
3775
3775
  props: propsFor(def.props, def.children !== void 0),
3776
- component: ((input) => catalogComponentImpls[def.name]?.({
3776
+ component: ((input) => /* @__PURE__ */ jsx(CatalogNode, {
3777
+ name: def.name,
3777
3778
  props: input.props,
3778
3779
  children: input.renderNode(input.props["children"])
3779
- }) ?? null)
3780
+ }))
3780
3781
  }))
3781
3782
  });
3782
3783
  const OPEN_UI_COMPONENTS = Object.keys(webskillOpenUiLibrary.components);
@@ -1,5 +1,5 @@
1
- import { P as FileSystemProvider, X as SkillCatalogEntry, rt as SkillManifest } from "./types-AmKCKJn_-VGabeXK4.js";
2
- //#region ../governance/dist/skillVersionStore-DOEI9ptb.d.ts
1
+ import { N as FileSystemProvider, R as Page, Z as SkillCatalogEntry, it as SkillManifest, z as PageQuery } from "./types-7Wcg--Vh-1YlQ4jF9.js";
2
+ //#region ../governance/dist/skillVersionStore-uyefLPR1.d.ts
3
3
  //#region src/types.d.ts
4
4
  type CandidateStatus = 'draft' | 'pending-review' | 'approved' | 'published' | 'rejected';
5
5
  type CandidateSource = 'runtime-miss' | 'document' | 'manual';
@@ -35,16 +35,32 @@ interface AuditEvent {
35
35
  /** 本事件规范化载荷 + prevHash 的 sha256 */
36
36
  hash?: string;
37
37
  }
38
+ /**
39
+ * 审计查询的筛选条件。刻意是**具名字段**而不是谓词函数:
40
+ * 谓词无法被存储层用索引优化,下推一个谓词等于把 `.filter()` 换了个位置。
41
+ * @stable
42
+ */
43
+ interface AuditQueryFilter {
44
+ target?: string;
45
+ type?: string;
46
+ actor?: string;
47
+ /** 含端点(`ts >= since`) */
48
+ since?: string;
49
+ /** 含端点(`ts <= until`) */
50
+ until?: string;
51
+ }
38
52
  interface AuditLog {
39
53
  append(event: Omit<AuditEvent, 'id' | 'ts'> & {
40
54
  id?: string;
41
55
  ts?: string;
42
56
  }): Promise<AuditEvent>;
43
- query(filter: {
44
- target?: string;
45
- type?: string;
46
- since?: string;
47
- }): Promise<AuditEvent[]>;
57
+ /**
58
+ * 分页查询。方向与会话消息一致:无游标给**最新**一页,`nextCursor` 指向更早的历史。
59
+ *
60
+ * 分页是性能优化,不是绕过完整性检查的通道:本页范围内的 hash 链断裂
61
+ * 必须以 `GOVERNANCE_FAILED` 报出,不得安静地把那一页返回。
62
+ */
63
+ query(filter?: AuditQueryFilter & PageQuery): Promise<Page<AuditEvent>>;
48
64
  }
49
65
  interface SkillVersion {
50
66
  versionId: string;
@@ -59,6 +75,8 @@ interface SkillVersion {
59
75
  type SkillState = 'active' | 'quarantined' | 'deprecated' | 'disabled';
60
76
  //#endregion
61
77
  //#region src/candidate/candidateStore.d.ts
78
+ /** 候选列表的缺省页长。缺省属于实现,不属于调用方 */
79
+ declare const CANDIDATE_PAGE_SIZE = 50;
62
80
  /** 逐文件持久化的候选存储:<managedRoot>/.webskill/candidates/<id>.json */
63
81
  declare class CandidateStore {
64
82
  #private;
@@ -68,7 +86,14 @@ declare class CandidateStore {
68
86
  });
69
87
  save(candidate: CandidateSkill): Promise<void>;
70
88
  get(id: string): Promise<CandidateSkill>;
71
- list(): Promise<CandidateSkill[]>;
89
+ /**
90
+ * 候选(= 审批队列)分页。`status` 是端口参数而不是上层 `.filter()`:
91
+ * 审批页面只看 `pending-review`,没理由把已发布的候选全部拉过端口。
92
+ * 目录扫描仍是逐文件读(备案 D25),但返回量已由 `limit` 封顶。
93
+ */
94
+ list(options?: {
95
+ status?: CandidateStatus;
96
+ } & PageQuery): Promise<Page<CandidateSkill>>;
72
97
  updateStatus(id: string, status: CandidateStatus, now?: string): Promise<CandidateSkill>;
73
98
  }
74
99
  /** 硬门禁:仅 published 可转换为 Catalog 条目,否则 APPROVAL_REQUIRED */
@@ -94,6 +119,8 @@ declare class CompositeApprovalPolicy implements ApprovalPolicy {
94
119
  }
95
120
  //#endregion
96
121
  //#region src/versioning/skillVersionStore.d.ts
122
+ /** 版本列表的缺省页长。缺省属于实现,不属于调用方 */
123
+ declare const SKILL_VERSION_PAGE_SIZE = 20;
97
124
  /** 版本存储:manifest 快照 + parentVersionId 链;回滚 = 追加新版本(谱系不断)。
98
125
  * 保留策略:maxArchivesPerSkill(默认 5)超出时清理最旧版本(json + zip 归档一并删除)。 */
99
126
  declare class SkillVersionStore {
@@ -115,7 +142,11 @@ declare class SkillVersionStore {
115
142
  }): Promise<SkillVersion>;
116
143
  /** 读取版本归档字节(applyRollback 用;未捕获归档的旧版本 → GOVERNANCE_FAILED) */
117
144
  readArchive(skillName: string, versionId: string): Promise<Uint8Array>;
118
- list(skillName: string): Promise<SkillVersion[]>;
145
+ /**
146
+ * 版本列表分页(方向同 C1:无游标给**最新**一页)。
147
+ * 保留策略与谱系构建走 `#readAll`:它们必须看到全量,不能被分页截断。
148
+ */
149
+ list(skillName: string, options?: PageQuery): Promise<Page<SkillVersion>>;
119
150
  get(skillName: string, versionId: string): Promise<SkillVersion>;
120
151
  /** 回滚:基于旧 manifest 追加新版本 + skill.rolled_back 审计 */
121
152
  rollback(skillName: string, targetVersionId: string, input: {
@@ -124,4 +155,4 @@ declare class SkillVersionStore {
124
155
  }): Promise<SkillVersion>;
125
156
  }
126
157
  //#endregion
127
- export { AuditLog as a, CandidateSkill as c, CandidateStore as d, CompositeApprovalPolicy as f, candidateToCatalogEntry as g, SkillVersionStore as h, AuditEvent as i, CandidateSource as l, SkillVersion as m, ApprovalDecision as n, CandidateFile as o, SkillState as p, ApprovalPolicy as r, CandidateRisk as s, AlwaysHumanApprovalPolicy as t, CandidateStatus as u };
158
+ export { SkillVersion as _, AuditLog as a, CandidateFile as c, CandidateSource as d, CandidateStatus as f, SkillState as g, SKILL_VERSION_PAGE_SIZE as h, AuditEvent as i, CandidateRisk as l, CompositeApprovalPolicy as m, ApprovalDecision as n, AuditQueryFilter as o, CandidateStore as p, ApprovalPolicy as r, CANDIDATE_PAGE_SIZE as s, AlwaysHumanApprovalPolicy as t, CandidateSkill as u, SkillVersionStore as v, candidateToCatalogEntry as y };
@@ -1,4 +1,5 @@
1
1
  import { m as WebSkillError } from "./dist-8oQRa8Xz.js";
2
+ import { i as textParts, n as partsToText } from "./memoryArtifactStore-BtOeB_hm-tj3fC5ip.js";
2
3
 
3
4
  //#region ../runtime/dist/testing.js
4
5
  /**
@@ -27,7 +28,7 @@ var MockLlmClient = class {
27
28
  else if (event.type === "tool-calls") toolCalls = event.toolCalls;
28
29
  else if (event.type === "done" && event.content !== void 0) content = event.content;
29
30
  return {
30
- content,
31
+ content: content === "" ? void 0 : textParts(content),
31
32
  toolCalls
32
33
  };
33
34
  }
@@ -43,11 +44,12 @@ var MockLlmClient = class {
43
44
  return;
44
45
  }
45
46
  const response = typeof next === "function" ? await next(input) : next;
46
- if (response.content) {
47
- const chunkSize = Math.max(1, Math.ceil(response.content.length / 3));
48
- for (let i = 0; i < response.content.length; i += chunkSize) yield {
47
+ const text = partsToText(response.content);
48
+ if (text !== "") {
49
+ const chunkSize = Math.max(1, Math.ceil(text.length / 3));
50
+ for (let i = 0; i < text.length; i += chunkSize) yield {
49
51
  type: "text-delta",
50
- delta: response.content.slice(i, i + chunkSize)
52
+ delta: text.slice(i, i + chunkSize)
51
53
  };
52
54
  }
53
55
  if (response.toolCalls?.length) yield {
package/dist/testing.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { c as LlmClient, d as LlmResponse, f as LlmStreamEvent, h as MemoryStore, l as LlmCompleteInput, n as ArtifactStore, o as InteractionRequest, s as InteractionResponse, t as Artifact, v as UiBridge } from "./types-AmKCKJn_-VGabeXK4.js";
1
+ import { c as LlmClient, f as LlmResponse, g as MemoryStore, l as LlmCompleteInput, n as ArtifactStore, o as InteractionRequest, p as LlmStreamEvent, s as InteractionResponse, t as Artifact, y as UiBridge } from "./types-7Wcg--Vh-1YlQ4jF9.js";
2
2
  import { a as loadGoogleConfigFromEnv, i as loadAnthropicConfigFromEnv, n as LlmEnvConfig, o as loadLlmConfigFromEnv, r as ProviderEnvConfig } from "./env-BPUBZCwJ-4jat_SVG.js";
3
3
  //#region ../runtime/dist/testing.d.ts
4
4
  //#region src/llm/mockLlmClient.d.ts
package/dist/testing.js CHANGED
@@ -1,5 +1,5 @@
1
- import { t as MemoryArtifactStore } from "./memoryArtifactStore-C9lFVqPF-yFz6yJj0.js";
1
+ import { t as MemoryArtifactStore } from "./memoryArtifactStore-BtOeB_hm-tj3fC5ip.js";
2
2
  import { n as loadGoogleConfigFromEnv, r as loadLlmConfigFromEnv, t as loadAnthropicConfigFromEnv } from "./env--jJB-TSX-04klhTYi.js";
3
- import { n as MockLlmClient, r as MockUiBridge, t as InMemoryStore } from "./testing-CsrG3XLz.js";
3
+ import { n as MockLlmClient, r as MockUiBridge, t as InMemoryStore } from "./testing-DDCJWvgA.js";
4
4
 
5
5
  export { InMemoryStore, MemoryArtifactStore, MockLlmClient, MockUiBridge, loadAnthropicConfigFromEnv, loadGoogleConfigFromEnv, loadLlmConfigFromEnv };
@@ -1,6 +1,6 @@
1
1
  //#region ../core/dist/index.d.ts
2
2
  //#region src/errors.d.ts
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' | 'VALIDATION_FAILED' | 'TOOL_NOT_FOUND' | 'TOOL_EXECUTION_FAILED' | 'NETWORK_BLOCKED' | 'TOOL_UNSUPPORTED' | 'TOOL_SCHEMA_UNAVAILABLE' | 'RUN_TIMEOUT' | 'RUN_MAX_TURNS_EXCEEDED' | 'RUN_FAILED' | 'RUN_CANCELLED' | 'RUN_INTERACTION_TIMEOUT' | '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_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';
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' | 'VALIDATION_FAILED' | 'TOOL_NOT_FOUND' | 'TOOL_EXECUTION_FAILED' | 'NETWORK_BLOCKED' | 'TOOL_UNSUPPORTED' | 'TOOL_NOT_ALLOWED' | 'TOOL_SCHEMA_UNAVAILABLE' | 'RUN_TIMEOUT' | 'RUN_MAX_TURNS_EXCEEDED' | 'RUN_FAILED' | 'RUN_CANCELLED' | 'RUN_INTERACTION_TIMEOUT' | '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';
4
4
  /**
5
5
  * 所有公开 API 抛出的结构化错误,code 供上层可编程处理
6
6
  * @stable
@@ -29,6 +29,27 @@ interface JsonSchema {
29
29
  [key: string]: unknown;
30
30
  }
31
31
  //#endregion
32
+ //#region src/contracts/pagination.d.ts
33
+ /**
34
+ * 全仓统一的游标分页形状。会话、消息、治理列表共用同一套,
35
+ * 不为每个存储端口各造一种(形状一多,调用方就得为每个端口重写一遍翻页逻辑)。
36
+ */
37
+ interface PageQuery {
38
+ /**
39
+ * 不透明续读位置,只能来自上一页的 `nextCursor`。
40
+ * 刻意不是数字 offset:追加型存储上并发追加会让 offset 错位,
41
+ * 而不透明串让实现方自己决定编码。
42
+ */
43
+ cursor?: string;
44
+ /** 本页最多返回多少条;缺省值由**存储实现**决定,不由调用方兜底 */
45
+ limit?: number;
46
+ }
47
+ /** 一页结果。`nextCursor` 缺席即已到末页,不用额外的 `hasMore` 布尔 */
48
+ interface Page<T> {
49
+ items: T[];
50
+ nextCursor?: string;
51
+ }
52
+ //#endregion
32
53
  //#region src/skill/manifest.d.ts
33
54
  type SkillInstallSource = {
34
55
  type: 'local';
@@ -181,7 +202,12 @@ interface SkillSignature {
181
202
  signature: string;
182
203
  signedAt: string;
183
204
  }
184
- /** 未签名包的处置策略;0.3.0 默认 `warn`,0.4.0 与 D10 一起收紧 */
205
+ /**
206
+ * 未签名包的处置策略。默认是 `warn`,0.4.0(D2)复核后维持不变:
207
+ * 默认信任库是空的,`deny` 之下未签名包报 `SIGNATURE_MISSING`、签名再正确也报
208
+ * `SIGNATURE_UNTRUSTED_KEY`——接受集为空,那不是更严的默认值而是恒失败的安装。
209
+ * `deny` 必须与装配好的 `TrustedKeyStore` 成对启用。
210
+ */
185
211
  type UnsignedPolicy = 'allow' | 'warn' | 'deny';
186
212
  interface TrustedKey {
187
213
  keyId: string;
@@ -342,6 +368,22 @@ interface RemoteUrlPolicy {
342
368
  */
343
369
  declare function assertRemoteUrlAllowed(rawUrl: string, policy?: RemoteUrlPolicy): URL;
344
370
  //#endregion
371
+ //#region src/ui/types.d.ts
372
+ /**
373
+ * 声明式 UI 的节点:框架无关,技能脚本与 LLM 产出同一形状。
374
+ *
375
+ * 定义放在 core 而不是 ui/runtime:runtime 要用它做结构校验,ui 要用它做 catalog
376
+ * 语义校验,两者互不依赖。`@webskill/ui` 以同名 re-export,公开名不变。
377
+ */
378
+ interface UiSpecNode {
379
+ /** catalog 中声明过的组件名 */
380
+ component: string;
381
+ props?: Record<string, unknown>;
382
+ children?: UiSpecNode[];
383
+ /** 稳定 id(回放与 action 关联用;交互节点以此作为 actionId) */
384
+ id?: string;
385
+ }
386
+ //#endregion
345
387
  //#region src/skill/types.d.ts
346
388
  type SkillSource = 'local' | 'mcp' | 'generated' | 'installed';
347
389
  /**
@@ -540,7 +582,7 @@ declare function escapeXml(text: string): string;
540
582
  declare function renderAvailableSkillsXml(catalog: SkillCatalog): string;
541
583
  declare const xmlRenderer: CatalogRenderer;
542
584
  //#endregion
543
- //#region ../runtime/dist/types-AmKCKJn_.d.ts
585
+ //#region ../runtime/dist/types-7Wcg--Vh.d.ts
544
586
  //#region src/llm/streamTypes.d.ts
545
587
  /** 流式 LLM 事件(OpenAI SSE / Vercel fullStream 统一映射) */
546
588
  type LlmStreamEvent = {
@@ -555,9 +597,26 @@ type LlmStreamEvent = {
555
597
  };
556
598
  //#endregion
557
599
  //#region src/llm/types.d.ts
600
+ /**
601
+ * 消息内容分片。二进制一律 base64 内联:引用形态(URL / 句柄)需要生命周期管理,
602
+ * 不属于本批。代价是快照体积。
603
+ */
604
+ type LlmContentPart = {
605
+ type: 'text';
606
+ text: string;
607
+ } | {
608
+ type: 'image';
609
+ mimeType: string;
610
+ data: string;
611
+ } | {
612
+ type: 'file';
613
+ mimeType: string;
614
+ data: string;
615
+ name?: string;
616
+ };
558
617
  interface LlmMessage {
559
618
  role: 'system' | 'user' | 'assistant' | 'tool';
560
- content: string;
619
+ content: LlmContentPart[];
561
620
  /** role=tool 时必填 */
562
621
  toolCallId?: string;
563
622
  /** role=assistant 发起工具调用时携带 */
@@ -576,7 +635,7 @@ interface LlmToolCall {
576
635
  argumentsParseError?: string;
577
636
  }
578
637
  interface LlmResponse {
579
- content?: string;
638
+ content?: LlmContentPart[];
580
639
  toolCalls?: LlmToolCall[];
581
640
  raw?: unknown;
582
641
  }
@@ -703,14 +762,16 @@ interface RenderResultRequest {
703
762
  artifacts?: Artifact[];
704
763
  }
705
764
  /** A user action exposed by a generative UI surface. @experimental */
706
- interface UiSurfaceAction {
765
+ interface UiSpecActionCapability {
766
+ /** Matches the `id` of the interactive node that declares the action. */
707
767
  id: string;
708
- label: string;
709
768
  intent: 'submit' | 'cancel' | 'select' | 'download' | 'refresh';
710
- disabled?: boolean;
711
769
  /** Requests that the producing run waits for this action before continuing. @experimental */
712
770
  awaitResponse?: boolean;
713
- /** Runtime-generated action capability; model-provided values are never trusted. @experimental */
771
+ /**
772
+ * Runtime-generated action capability. Kept out of the node tree on purpose:
773
+ * the tree is model-writable, so a nonce carried inside it would be forgeable.
774
+ */
714
775
  nonce?: string;
715
776
  }
716
777
  /** A runtime-owned request for a user action on a rendered UI surface. @experimental */
@@ -718,7 +779,7 @@ interface UiSurfaceActionRequest {
718
779
  runId: string;
719
780
  surfaceId: string;
720
781
  actionId: string;
721
- intent: UiSurfaceAction['intent'];
782
+ intent: UiSpecActionCapability['intent'];
722
783
  nonce: string;
723
784
  }
724
785
  /** A structured action returned by a renderer to the waiting run. @experimental */
@@ -727,75 +788,26 @@ interface UiSurfaceActionResponse extends UiSurfaceActionRequest {
727
788
  cancelled?: boolean;
728
789
  }
729
790
  /** Serializable draft values for forms that belong to one interrupted run. @experimental */
730
- type UiSurfaceDrafts = Record<string, Record<string, unknown>>;
731
- /** A structured form field rendered inside a generative UI surface. @experimental */
732
- interface UiSurfaceFormField {
733
- name: string;
734
- label: string;
735
- type: 'text' | 'number' | 'date' | 'textarea' | 'select' | 'multi-select' | 'toggle' | 'file';
736
- required?: boolean;
737
- description?: string;
738
- defaultValue?: unknown;
739
- options?: Array<{
740
- label: string;
741
- value: unknown;
742
- }>;
743
- }
744
- /** Framework-neutral generative UI surface. @experimental */
745
- type UiSurface = {
746
- kind: 'form';
747
- id: string;
748
- title?: string;
749
- fields: UiSurfaceFormField[];
750
- actions: UiSurfaceAction[];
751
- } | {
752
- kind: 'chart';
753
- id: string;
754
- chart: ChartSpec;
755
- actions?: UiSurfaceAction[];
756
- } | {
757
- kind: 'table';
758
- id: string;
759
- columns: string[];
760
- rows: unknown[][];
761
- actions?: UiSurfaceAction[];
762
- } | {
763
- kind: 'metric';
764
- id: string;
765
- label: string;
766
- value: string | number;
767
- trend?: 'up' | 'down' | 'neutral';
768
- } | {
769
- kind: 'file';
770
- id: string;
771
- path: string;
772
- mimeType?: string;
773
- size?: number;
774
- actions?: UiSurfaceAction[];
775
- } | {
776
- kind: 'custom';
777
- id: string;
778
- component: string;
779
- props: unknown;
780
- actions?: UiSurfaceAction[];
781
- };
782
- /** A bounded mutation applied to an existing UI surface. @experimental */
783
- interface UiSurfacePatch {
791
+ type UiSpecDrafts = Record<string, Record<string, unknown>>;
792
+ /** A bounded mutation applied to an existing UI spec tree. @experimental */
793
+ interface UiSpecPatch {
784
794
  op: 'replace' | 'merge' | 'append';
785
795
  path: string;
786
796
  value: unknown;
787
797
  }
788
798
  /** Incremental lifecycle event for a framework-neutral generative UI surface. @experimental */
789
- type UiSurfaceEvent = {
799
+ type UiSpecEvent = {
790
800
  runId?: string;
791
801
  } & ({
792
802
  type: 'open';
793
- surface: UiSurface;
803
+ id: string;
804
+ node: UiSpecNode;
805
+ actions?: UiSpecActionCapability[];
794
806
  } | {
795
807
  type: 'patch';
796
808
  id: string;
797
809
  revision: number;
798
- operations: UiSurfacePatch[];
810
+ operations: UiSpecPatch[];
799
811
  } | {
800
812
  type: 'complete';
801
813
  id: string;
@@ -810,8 +822,10 @@ type UiSurfaceEvent = {
810
822
  id: string;
811
823
  });
812
824
  /** Persisted state of a generative UI surface. @experimental */
813
- interface UiSurfaceSnapshot {
814
- surface: UiSurface;
825
+ interface UiSpecSnapshot {
826
+ id: string;
827
+ node: UiSpecNode;
828
+ actions?: UiSpecActionCapability[];
815
829
  revision: number;
816
830
  status: 'active' | 'complete' | 'error' | 'cancelled';
817
831
  /** Immutable producing run; supplied on open to support session persistence and replay. */
@@ -834,7 +848,7 @@ interface UiBridge {
834
848
  /** 定义即可,阶段 7 消费 */
835
849
  renderResult?(input: RenderResultRequest): Promise<void>;
836
850
  /** Framework-neutral generative UI surface stream. @experimental */
837
- renderSurface?(event: UiSurfaceEvent): Promise<void>;
851
+ renderSurface?(event: UiSpecEvent): Promise<void>;
838
852
  /** Waits for an action declared with awaitResponse; optional for compatibility with legacy bridges. @experimental */
839
853
  requestSurfaceAction?(input: UiSurfaceActionRequest): Promise<UiSurfaceActionResponse>;
840
854
  /** Best-effort cleanup when a surface action wait times out or is cancelled. @experimental */
@@ -878,4 +892,4 @@ interface MemoryStore {
878
892
  transaction?<T>(scope: string, fn: (inner: MemoryStore) => Promise<T>): Promise<T>;
879
893
  }
880
894
  //#endregion
881
- export { SkillInstallSource as $, CryptoKeyLike as A, messageOf as At, SIGNATURE_SCHEMA_VERSION as B, signSkill as Bt, UiSurfaceDrafts as C, checkSkillRules as Ct, UiSurfaceSnapshot as D, isValidSkillName as Dt, UiSurfacePatch as E, exportSkills as Et, FsTrustedKeyStore as F, readSkillSignature as Ft, SKILL_PACK_FILE as G, verifySkillSignature as Gt, SKILL_MANIFEST_FILE as H, unzipWithLimits as Ht, JsonSchema as I, renderAvailableSkillsXml as It, SignatureVerdict as J, SKILL_SIGNATURE_FILE as K, xmlRenderer as Kt, MANIFEST_EXCLUDED_FILES as L, renderCatalogJson as Lt, DiscoveryResult as M, parseSkillMarkdown as Mt, FileStat as N, parseSkillPackManifest as Nt, ArchiveLimits as O, jsonRenderer as Ot, FileSystemProvider as P, readResponseWithLimit as Pt, SkillDocument as Q, MemoryFS as R, resolveArchiveLimits as Rt, UiSurfaceActionResponse as S, checkDependencyCycles as St, UiSurfaceFormField as T, escapeXml as Tt, SKILL_NAME_MAX_LENGTH as U, validateSkills as Ut, SKILLS_LOCKFILE as V, signaturePayloadBytes as Vt, SKILL_NAME_PATTERN as W, verifyManifest as Wt, SkillCatalogEntry as X, SkillCatalog as Y, SkillDiscovery as Z, RenderResultRequest as _, assertRemoteUrlAllowed as _t, InteractionPolicy as a, SkillPackManifest as at, UiSurfaceAction as b, buildCatalog as bt, LlmClient as c, SkillSource as ct, LlmResponse as d, TrustedKeyStore as dt, SkillIssue as et, LlmStreamEvent as f, UnsignedPolicy as ft, RenderBlock as g, WebSkillErrorCode as gt, MemoryStore as h, WebSkillError as ht, FormField as i, SkillMetadata as it, DEFAULT_ARCHIVE_LIMITS as j, normalizePath as jt, CatalogRenderer as k, keyIdOf as kt, LlmCompleteInput as l, SkillsLockfile as lt, LlmToolSpec as m, VerifyResult as mt, ArtifactStore as n, SkillManagerPort as nt, InteractionRequest as o, SkillReader as ot, LlmToolCall as p, ValidationReport as pt, SignatureAuditSink as q, ChartSpec as r, SkillManifest as rt, InteractionResponse as s, SkillSignature as st, Artifact as t, SkillLocation as tt, LlmMessage as u, TrustedKey as ut, UiBridge as v, assertSafePathSegment as vt, UiSurfaceEvent as w, computeDigest as wt, UiSurfaceActionRequest as x, buildManifest as xt, UiSurface as y, atomicWriteText as yt, RemoteUrlPolicy as z, resolveInsideRoot as zt };
895
+ export { SkillDocument as $, DEFAULT_ARCHIVE_LIMITS as A, jsonRenderer as At, RemoteUrlPolicy as B, resolveArchiveLimits as Bt, UiSpecPatch as C, buildManifest as Ct, ArchiveLimits as D, escapeXml as Dt, UiSurfaceActionResponse as E, computeDigest as Et, JsonSchema as F, parseSkillPackManifest as Ft, SKILL_NAME_PATTERN as G, validateSkills as Gt, SKILLS_LOCKFILE as H, signSkill as Ht, MANIFEST_EXCLUDED_FILES as I, readResponseWithLimit as It, SignatureAuditSink as J, xmlRenderer as Jt, SKILL_PACK_FILE as K, verifyManifest as Kt, MemoryFS as L, readSkillSignature as Lt, FileStat as M, messageOf as Mt, FileSystemProvider as N, normalizePath as Nt, CatalogRenderer as O, exportSkills as Ot, FsTrustedKeyStore as P, parseSkillMarkdown as Pt, SkillDiscovery as Q, Page as R, renderAvailableSkillsXml as Rt, UiSpecEvent as S, buildCatalog as St, UiSurfaceActionRequest as T, checkSkillRules as Tt, SKILL_MANIFEST_FILE as U, signaturePayloadBytes as Ut, SIGNATURE_SCHEMA_VERSION as V, resolveInsideRoot as Vt, SKILL_NAME_MAX_LENGTH as W, unzipWithLimits as Wt, SkillCatalog as X, SignatureVerdict as Y, SkillCatalogEntry as Z, RenderBlock as _, WebSkillError as _t, InteractionPolicy as a, SkillMetadata as at, UiSpecActionCapability as b, assertSafePathSegment as bt, LlmClient as c, SkillSignature as ct, LlmMessage as d, TrustedKey as dt, SkillInstallSource as et, LlmResponse as f, TrustedKeyStore as ft, MemoryStore as g, VerifyResult as gt, LlmToolSpec as h, ValidationReport as ht, FormField as i, SkillManifest as it, DiscoveryResult as j, keyIdOf as jt, CryptoKeyLike as k, isValidSkillName as kt, LlmCompleteInput as l, SkillSource as lt, LlmToolCall as m, UnsignedPolicy as mt, ArtifactStore as n, SkillLocation as nt, InteractionRequest as o, SkillPackManifest as ot, LlmStreamEvent as p, UiSpecNode as pt, SKILL_SIGNATURE_FILE as q, verifySkillSignature as qt, ChartSpec as r, SkillManagerPort as rt, InteractionResponse as s, SkillReader as st, Artifact as t, SkillIssue as tt, LlmContentPart as u, SkillsLockfile as ut, RenderResultRequest as v, WebSkillErrorCode as vt, UiSpecSnapshot as w, checkDependencyCycles as wt, UiSpecDrafts as x, atomicWriteText as xt, UiBridge as y, assertRemoteUrlAllowed as yt, PageQuery as z, renderCatalogJson as zt };