@webskill/sdk 0.5.0 → 0.6.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.
- package/dist/agent.d.ts +2 -2
- package/dist/agent.js +57 -15
- package/dist/browser.d.ts +101 -5
- package/dist/browser.js +421 -11
- package/dist/{catalogComponents-DV7cPpUm-C77AEEx9.js → catalogComponents-Dr5dFMAb-Dacibl1e.js} +126 -44
- package/dist/{dist-bewtXYlO.js → dist-DnYG2-eY.js} +53 -14
- package/dist/{dist-6C03DShK.js → dist-DusANsrn.js} +981 -185
- package/dist/{env--jJB-TSX-04klhTYi.js → env-8cY40DXB-CGnEVZby.js} +7 -6
- package/dist/{env-BPUBZCwJ-4jat_SVG.d.ts → env-AK3cSMEA-Dli6QU5E.d.ts} +4 -3
- package/dist/governance.d.ts +3 -3
- package/dist/governance.js +1 -1
- package/dist/{index-Bsqg4ftU.d.ts → index-BMocOEi0.d.ts} +13 -7
- package/dist/{index-D_7ZZjkl.d.ts → index-BuTpBMzr.d.ts} +69 -6
- package/dist/{index-vBz_FC9w.d.ts → index-C-KFAZoF.d.ts} +298 -52
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/mcp.d.ts +39 -8
- package/dist/mcp.js +53 -19
- package/dist/{memoryArtifactStore-BtOeB_hm-tj3fC5ip.js → memoryArtifactStore-52Zn9npI-BMPYwvoy.js} +10 -2
- package/dist/node.d.ts +4 -4
- package/dist/node.js +9 -2
- package/dist/{openUiLibrary-W3Ce896k-ClFTRZFs.js → openUiLibrary-Bdrji9qK-DzAxRlTY.js} +3 -3
- package/dist/{skillVersionStore-BzLbzFOL-CxwIewHJ.d.ts → skillVersionStore-BzLbzFOL-CxdAFWO2.d.ts} +1 -1
- package/dist/{testing-DDCJWvgA.js → testing-CYTFqkDm.js} +1 -1
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +3 -3
- package/dist/{types-D_hoCri8-BnNPiZCi.d.ts → types-4pg-qp_I-Gq63X8Oa.d.ts} +33 -8
- package/dist/ui-react.d.ts +2 -2
- package/dist/ui-react.js +66 -23
- package/dist/ui-vue.d.ts +1 -1
- package/dist/ui-vue.js +13 -8
- package/dist/ui.d.ts +3 -3
- package/dist/ui.js +2 -2
- package/dist/{webskillLitCatalog-_mugzRHx-DiuJpCuf.js → webskillLitCatalog-_mugzRHx-B_54vxum.js} +1 -1
- package/package.json +1 -1
package/dist/mcp.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { I as JsonSchema, Q as SkillCatalogEntry, et as SkillDocument, g as LlmToolSpec } from "./types-
|
|
2
|
-
import {
|
|
1
|
+
import { I as JsonSchema, Q as SkillCatalogEntry, et as SkillDocument, g as LlmToolSpec } from "./types-4pg-qp_I-Gq63X8Oa.js";
|
|
2
|
+
import { D as ExternalSkillProvider, O as ExternalToolSource, Tn as mergeCatalogEntries, Ut as ToolResult } from "./index-C-KFAZoF.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";
|
|
@@ -192,15 +192,46 @@ declare function serveSkillAsMcp(server: McpServer, skill: ServedSkill): Promise
|
|
|
192
192
|
declare const catalogMerge: typeof mergeCatalogEntries;
|
|
193
193
|
//#endregion
|
|
194
194
|
//#region src/webmcp/experimentalWebMcpAdapter.d.ts
|
|
195
|
-
/**
|
|
195
|
+
/**
|
|
196
|
+
* WebMCP 命令式 API 的工具形状(Chrome 150+)。
|
|
197
|
+
* `getTools()` 返回的工具含 `inputSchema`(JSON 字符串)、`origin`、`window`、`annotations`。
|
|
198
|
+
* 参考 https://developer.chrome.com/docs/ai/webmcp/imperative-api
|
|
199
|
+
*/
|
|
200
|
+
interface WebMcpToolLike {
|
|
201
|
+
name: string;
|
|
202
|
+
description?: string;
|
|
203
|
+
/** getTools() 返回的 inputSchema 是 JSON 字符串(非对象) */
|
|
204
|
+
inputSchema?: string;
|
|
205
|
+
origin?: string;
|
|
206
|
+
window?: unknown;
|
|
207
|
+
annotations?: {
|
|
208
|
+
readOnlyHint?: boolean;
|
|
209
|
+
untrustedContentHint?: boolean;
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* document.modelContext 鸭子类型(对齐 Chrome 150+ 的 WebMCP 命令式 API)。
|
|
214
|
+
* - 旧版(Chrome <150):navigator.modelContext.listTools() / executeTool(name, argsJson)
|
|
215
|
+
* - 新版(Chrome 150+):document.modelContext.getTools() / executeTool(tool, argsJson, { signal? })
|
|
216
|
+
* executeTool 的第一参在两种版本都能接受:新版传 tool 对象,旧版传 name 字符串。
|
|
217
|
+
*/
|
|
196
218
|
interface BrowserModelContextLike {
|
|
197
|
-
|
|
198
|
-
executeTool?: (
|
|
219
|
+
getTools?: () => Promise<unknown>;
|
|
220
|
+
executeTool?: (tool: WebMcpToolLike | string, argsJson: string, options?: {
|
|
221
|
+
signal?: AbortSignal;
|
|
222
|
+
}) => Promise<unknown>;
|
|
199
223
|
}
|
|
200
224
|
interface WebMcpToolDescriptor {
|
|
201
225
|
name: string;
|
|
202
226
|
description?: string;
|
|
203
227
|
inputSchema?: unknown;
|
|
228
|
+
origin?: string;
|
|
229
|
+
annotations?: {
|
|
230
|
+
readOnlyHint?: boolean;
|
|
231
|
+
untrustedContentHint?: boolean;
|
|
232
|
+
};
|
|
233
|
+
/** getTools() 返回的原始 tool 对象:executeTool 第一参须透传原对象(含 inputSchema JSON 字符串、window 等) */
|
|
234
|
+
raw?: unknown;
|
|
204
235
|
}
|
|
205
236
|
/**
|
|
206
237
|
* Experimental WebMCP Adapter(mcp# 分支):默认关闭显式启用;
|
|
@@ -214,9 +245,9 @@ declare class ExperimentalWebMcpAdapter {
|
|
|
214
245
|
enabled?: boolean;
|
|
215
246
|
});
|
|
216
247
|
isAvailable(): boolean;
|
|
217
|
-
/** 工具清单(
|
|
248
|
+
/** 工具清单(getTools 缺失时返回 undefined;调用失败时告警后返回 undefined) */
|
|
218
249
|
listTools(): Promise<WebMcpToolDescriptor[] | undefined>;
|
|
219
|
-
/** 工具名清单(
|
|
250
|
+
/** 工具名清单(getTools 缺失/失败时返回 undefined) */
|
|
220
251
|
listToolNames(): Promise<string[] | undefined>;
|
|
221
252
|
call(toolName: string, args: Record<string, unknown>): Promise<ToolResult>;
|
|
222
253
|
}
|
|
@@ -269,4 +300,4 @@ declare function connectRemoteEndpoint(registry: EndpointRegistry<McpClientLike>
|
|
|
269
300
|
close(): Promise<void>;
|
|
270
301
|
}>;
|
|
271
302
|
//#endregion
|
|
272
|
-
export { type BrowserModelContextLike, EndpointRegistry, ExperimentalWebMcpAdapter, type McpClientLike, McpRuntimePlugin, McpToolResolver, MessageChannelTransport, type MessageChannelTransportOptions, type MessagePortLike, type RemoteEndpointConfig, type ServedSkill, TemporarySkillProvider, type TransportState, type WebMcpToolDescriptor, catalogMerge, connectRemoteEndpoint, endpointToolLlmName, parseEndpointToolLlmName, parseWebMcpToolLlmName, serveSkillAsMcp, validateJsonRpcMessage, webMcpToolLlmName };
|
|
303
|
+
export { type BrowserModelContextLike, EndpointRegistry, ExperimentalWebMcpAdapter, type McpClientLike, McpRuntimePlugin, McpToolResolver, MessageChannelTransport, type MessageChannelTransportOptions, type MessagePortLike, type RemoteEndpointConfig, type ServedSkill, TemporarySkillProvider, type TransportState, type WebMcpToolDescriptor, type WebMcpToolLike, catalogMerge, connectRemoteEndpoint, endpointToolLlmName, parseEndpointToolLlmName, parseWebMcpToolLlmName, serveSkillAsMcp, validateJsonRpcMessage, webMcpToolLlmName };
|
package/dist/mcp.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { O as messageOf, h as assertRemoteUrlAllowed, m as WebSkillError } from "./dist-8oQRa8Xz.js";
|
|
2
|
-
import {
|
|
2
|
+
import { at as normalizeToolContent, et as mergeCatalogEntries } from "./dist-DusANsrn.js";
|
|
3
3
|
|
|
4
4
|
//#region ../mcp/dist/index.js
|
|
5
5
|
/**
|
|
@@ -392,15 +392,39 @@ const failure = (code, message) => ({
|
|
|
392
392
|
message
|
|
393
393
|
}
|
|
394
394
|
});
|
|
395
|
-
/**
|
|
395
|
+
/** getTools() 返回的工具 → 描述符:inputSchema 为 JSON 字符串时解析为对象,并保留原始对象 */
|
|
396
|
+
function toDescriptor(raw) {
|
|
397
|
+
if (typeof raw !== "object" || raw === null) return void 0;
|
|
398
|
+
const t = raw;
|
|
399
|
+
const name = String(t["name"] ?? "");
|
|
400
|
+
if (name === "") return void 0;
|
|
401
|
+
const descriptor = {
|
|
402
|
+
name,
|
|
403
|
+
raw
|
|
404
|
+
};
|
|
405
|
+
if (typeof t["description"] === "string") descriptor.description = t["description"];
|
|
406
|
+
if (typeof t["origin"] === "string") descriptor.origin = t["origin"];
|
|
407
|
+
if (typeof t["annotations"] === "object" && t["annotations"] !== null) {
|
|
408
|
+
const annotations = t["annotations"];
|
|
409
|
+
descriptor.annotations = {
|
|
410
|
+
...typeof annotations["readOnlyHint"] === "boolean" ? { readOnlyHint: annotations["readOnlyHint"] } : {},
|
|
411
|
+
...typeof annotations["untrustedContentHint"] === "boolean" ? { untrustedContentHint: annotations["untrustedContentHint"] } : {}
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
const schema = t["inputSchema"];
|
|
415
|
+
if (typeof schema === "string" && schema.trim() !== "") try {
|
|
416
|
+
descriptor.inputSchema = JSON.parse(schema);
|
|
417
|
+
} catch {
|
|
418
|
+
descriptor.inputSchema = schema;
|
|
419
|
+
}
|
|
420
|
+
else if (typeof schema === "object" && schema !== null) descriptor.inputSchema = schema;
|
|
421
|
+
return descriptor;
|
|
422
|
+
}
|
|
423
|
+
/** 从 getTools 返回值提取工具描述(容忍数组或 {tools:[]} 两种形状) */
|
|
396
424
|
function extractToolDescriptors(raw) {
|
|
397
425
|
const list = Array.isArray(raw) ? raw : typeof raw === "object" && raw !== null && Array.isArray(raw.tools) ? raw.tools : void 0;
|
|
398
426
|
if (!list) return void 0;
|
|
399
|
-
return list.filter((
|
|
400
|
-
name: String(t["name"] ?? ""),
|
|
401
|
-
...typeof t["description"] === "string" ? { description: t["description"] } : {},
|
|
402
|
-
...typeof t["inputSchema"] === "object" && t["inputSchema"] !== null ? { inputSchema: t["inputSchema"] } : {}
|
|
403
|
-
})).filter((t) => t.name !== "");
|
|
427
|
+
return list.map(toDescriptor).filter((d) => d !== void 0);
|
|
404
428
|
}
|
|
405
429
|
/**
|
|
406
430
|
* Experimental WebMCP Adapter(mcp# 分支):默认关闭显式启用;
|
|
@@ -416,35 +440,45 @@ var ExperimentalWebMcpAdapter = class {
|
|
|
416
440
|
this.#enabled = options?.enabled ?? false;
|
|
417
441
|
}
|
|
418
442
|
isAvailable() {
|
|
419
|
-
|
|
443
|
+
const api = this.#resolveApi();
|
|
444
|
+
return this.#enabled && typeof api?.executeTool === "function";
|
|
420
445
|
}
|
|
421
|
-
/** 工具清单(
|
|
446
|
+
/** 工具清单(getTools 缺失时返回 undefined;调用失败时告警后返回 undefined) */
|
|
422
447
|
async listTools() {
|
|
423
448
|
const api = this.#resolveApi();
|
|
424
|
-
if (typeof api?.
|
|
449
|
+
if (typeof api?.getTools !== "function") return void 0;
|
|
425
450
|
try {
|
|
426
|
-
return extractToolDescriptors(await api.
|
|
451
|
+
return extractToolDescriptors(await api.getTools());
|
|
427
452
|
} catch (e) {
|
|
428
|
-
console.warn(`[webskill]
|
|
453
|
+
console.warn(`[webskill] document.modelContext.getTools() failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
429
454
|
return;
|
|
430
455
|
}
|
|
431
456
|
}
|
|
432
|
-
/** 工具名清单(
|
|
457
|
+
/** 工具名清单(getTools 缺失/失败时返回 undefined) */
|
|
433
458
|
async listToolNames() {
|
|
434
459
|
return (await this.listTools())?.map((t) => t.name);
|
|
435
460
|
}
|
|
436
461
|
async call(toolName, args) {
|
|
437
462
|
if (!this.#enabled) return failure("TOOL_UNSUPPORTED", "WebMCP adapter is disabled (enable it explicitly to use mcp# tools)");
|
|
438
463
|
const api = this.#resolveApi();
|
|
439
|
-
if (typeof api?.executeTool !== "function") return failure("TOOL_UNSUPPORTED", "
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
464
|
+
if (typeof api?.executeTool !== "function") return failure("TOOL_UNSUPPORTED", "document.modelContext is not available");
|
|
465
|
+
const argsJson = JSON.stringify(args);
|
|
466
|
+
if (typeof api.getTools === "function") try {
|
|
467
|
+
const descriptors = extractToolDescriptors(await api.getTools());
|
|
468
|
+
const match = descriptors?.find((t) => t.name === toolName);
|
|
469
|
+
if (descriptors !== void 0 && match === void 0) return failure("MCP_TOOL_NOT_FOUND", `WebMCP tool "${toolName}" not found`);
|
|
470
|
+
const tool = match?.raw ?? { name: toolName };
|
|
471
|
+
return {
|
|
472
|
+
ok: true,
|
|
473
|
+
content: normalizeToolContent(await api.executeTool(tool, argsJson))
|
|
474
|
+
};
|
|
475
|
+
} catch (e) {
|
|
476
|
+
return failure("TOOL_EXECUTION_FAILED", `WebMCP tool "${toolName}" failed: ${messageOf(e)}`);
|
|
477
|
+
}
|
|
444
478
|
try {
|
|
445
479
|
return {
|
|
446
480
|
ok: true,
|
|
447
|
-
content: normalizeToolContent(await api.executeTool(toolName,
|
|
481
|
+
content: normalizeToolContent(await api.executeTool(toolName, argsJson))
|
|
448
482
|
};
|
|
449
483
|
} catch (e) {
|
|
450
484
|
return failure("TOOL_EXECUTION_FAILED", `WebMCP tool "${toolName}" failed: ${messageOf(e)}`);
|
package/dist/{memoryArtifactStore-BtOeB_hm-tj3fC5ip.js → memoryArtifactStore-52Zn9npI-BMPYwvoy.js}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { m as WebSkillError } from "./dist-8oQRa8Xz.js";
|
|
2
2
|
|
|
3
|
-
//#region ../runtime/dist/memoryArtifactStore-
|
|
3
|
+
//#region ../runtime/dist/memoryArtifactStore-52Zn9npI.js
|
|
4
4
|
/** 纯文本消息内容的构造快捷方式(引擎内部绝大多数消息仍是纯文本) */
|
|
5
5
|
const textParts = (text) => [{
|
|
6
6
|
type: "text",
|
|
@@ -8,6 +8,14 @@ const textParts = (text) => [{
|
|
|
8
8
|
}];
|
|
9
9
|
/** 取出 parts 中的文本(非文本分片在纯文本语境下无法表达,此处按丢弃处理——调用方须先校验) */
|
|
10
10
|
const partsToText = (parts) => (parts ?? []).reduce((acc, part) => part.type === "text" ? acc + part.text : acc, "");
|
|
11
|
+
/**
|
|
12
|
+
* run 的提示词文本投影:`RuntimeRun.userPrompt` 与快照都是字符串字段,
|
|
13
|
+
* 而多模态提示词里的图片/文件分片没有文本形态,用占位符标注,避免记录成空串。
|
|
14
|
+
*/
|
|
15
|
+
const promptText = (prompt) => {
|
|
16
|
+
if (typeof prompt === "string") return prompt;
|
|
17
|
+
return prompt.map((part) => part.type === "text" ? part.text : `[${part.type}: ${part.mimeType}]`).join("\n");
|
|
18
|
+
};
|
|
11
19
|
const isContentPart = (value) => {
|
|
12
20
|
if (typeof value !== "object" || value === null) return false;
|
|
13
21
|
const part = value;
|
|
@@ -75,4 +83,4 @@ var MemoryArtifactStore = class {
|
|
|
75
83
|
};
|
|
76
84
|
|
|
77
85
|
//#endregion
|
|
78
|
-
export {
|
|
86
|
+
export { textParts as a, rejectUnsupportedPart as i, partsToText as n, validateLlmMessages as o, promptText as r, MemoryArtifactStore as t };
|
package/dist/node.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { I as JsonSchema, N as FileStat, O as ArchiveLimits, P as FileSystemProvider, U as SKILLS_LOCKFILE, W as SKILL_MANIFEST_FILE, Y as SignatureAuditSink, _t as VerifyResult, at as SkillManifest, b as UiBridge, c as InteractionResponse, dt as SkillsLockfile, ht as UnsignedPolicy, it as SkillManagerPort, pt as TrustedKeyStore, s as InteractionRequest, tt as SkillInstallSource, y as RenderResultRequest } from "./types-
|
|
2
|
-
import {
|
|
3
|
-
import { a as AuditLog, p as CandidateStore, r as ApprovalPolicy, u as CandidateSkill, v as SkillVersionStore } from "./skillVersionStore-BzLbzFOL-
|
|
4
|
-
import { n as LlmEnvConfig, s as probeLlmCapabilities, t as LlmCapabilities } from "./env-
|
|
1
|
+
import { I as JsonSchema, N as FileStat, O as ArchiveLimits, P as FileSystemProvider, U as SKILLS_LOCKFILE, W as SKILL_MANIFEST_FILE, Y as SignatureAuditSink, _t as VerifyResult, at as SkillManifest, b as UiBridge, c as InteractionResponse, dt as SkillsLockfile, ht as UnsignedPolicy, it as SkillManagerPort, pt as TrustedKeyStore, s as InteractionRequest, tt as SkillInstallSource, y as RenderResultRequest } from "./types-4pg-qp_I-Gq63X8Oa.js";
|
|
2
|
+
import { A as FsArtifactStore, Ct as ScriptExecutionContext, J as NetworkPolicy, St as SchemaInferer, Ut as ToolResult, Vt as ToolDefinition, _ as BridgeCapabilities, f as ApprovalScope, fn as createScriptContext, j as FsMemoryStore, on as WebSkillRuntime, sn as WebSkillRuntimeDeps, wt as ScriptExecutor } from "./index-C-KFAZoF.js";
|
|
3
|
+
import { a as AuditLog, p as CandidateStore, r as ApprovalPolicy, u as CandidateSkill, v as SkillVersionStore } from "./skillVersionStore-BzLbzFOL-CxdAFWO2.js";
|
|
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
|
|
7
7
|
//#region src/fs/nodeFs.d.ts
|
package/dist/node.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { A as parseSkillMarkdown, B as unzipWithLimits, H as verifyManifest, I as resolveArchiveLimits, L as resolveInsideRoot, M as readResponseWithLimit, N as readSkillSignature, O as messageOf, T as isValidSkillName, U as verifySkillSignature, V as validateSkills, _ as atomicWriteText, g as assertSafePathSegment, h as assertRemoteUrlAllowed, j as parseSkillPackManifest, m as WebSkillError, o as SKILLS_LOCKFILE, r as MANIFEST_EXCLUDED_FILES, s as SKILL_MANIFEST_FILE, u as SKILL_PACK_FILE, w as exportSkills, y as buildManifest } from "./dist-8oQRa8Xz.js";
|
|
2
|
-
import {
|
|
3
|
-
import { i as probeLlmCapabilities } from "./env
|
|
2
|
+
import { I as WebSkillRuntime, V as createScriptContext, at as normalizeToolContent, c as CapabilityApproval, m as FsMemoryStore, nt as networkPolicyLibSource, ot as normalizeToolError, p as FsArtifactStore, st as parseBridgeRequest, z as bridgeError } from "./dist-DusANsrn.js";
|
|
3
|
+
import { i as probeLlmCapabilities } from "./env-8cY40DXB-CGnEVZby.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import { unzipSync, zipSync } from "fflate";
|
|
6
6
|
import { existsSync, promises, realpathSync } from "node:fs";
|
|
@@ -1148,6 +1148,13 @@ var CliUiBridge = class {
|
|
|
1148
1148
|
value: answer === "y" || answer === "yes"
|
|
1149
1149
|
};
|
|
1150
1150
|
}
|
|
1151
|
+
case "file-pick": {
|
|
1152
|
+
const answer = (await this.#question(`${input.message}\nLocal file path (empty to decline): `)).trim();
|
|
1153
|
+
return answer === "" ? { id: input.id } : {
|
|
1154
|
+
id: input.id,
|
|
1155
|
+
value: { path: answer }
|
|
1156
|
+
};
|
|
1157
|
+
}
|
|
1151
1158
|
}
|
|
1152
1159
|
}
|
|
1153
1160
|
async progress(input) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { nt as uiCatalog } from "./dist-
|
|
2
|
-
import { t as CatalogNode } from "./catalogComponents-
|
|
1
|
+
import { nt as uiCatalog } from "./dist-DnYG2-eY.js";
|
|
2
|
+
import { t as CatalogNode } from "./catalogComponents-Dr5dFMAb-Dacibl1e.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-
|
|
3764
|
+
//#region ../ui-react/dist/openUiLibrary-Bdrji9qK.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 与描述,
|
package/dist/{skillVersionStore-BzLbzFOL-CxwIewHJ.d.ts → skillVersionStore-BzLbzFOL-CxdAFWO2.d.ts}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as PageQuery, P as FileSystemProvider, Q as SkillCatalogEntry, at as SkillManifest, z as Page } from "./types-
|
|
1
|
+
import { B as PageQuery, P as FileSystemProvider, Q as SkillCatalogEntry, at as SkillManifest, z as Page } from "./types-4pg-qp_I-Gq63X8Oa.js";
|
|
2
2
|
//#region ../governance/dist/skillVersionStore-BzLbzFOL.d.ts
|
|
3
3
|
//#region src/types.d.ts
|
|
4
4
|
type CandidateStatus = 'draft' | 'pending-review' | 'approved' | 'published' | 'rejected';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { m as WebSkillError } from "./dist-8oQRa8Xz.js";
|
|
2
|
-
import {
|
|
2
|
+
import { a as textParts, n as partsToText } from "./memoryArtifactStore-52Zn9npI-BMPYwvoy.js";
|
|
3
3
|
|
|
4
4
|
//#region ../runtime/dist/testing.js
|
|
5
5
|
/**
|
package/dist/testing.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { _ as MemoryStore, b 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 } from "./types-
|
|
2
|
-
import { a as loadGoogleConfigFromEnv, i as loadAnthropicConfigFromEnv, n as LlmEnvConfig, o as loadLlmConfigFromEnv, r as ProviderEnvConfig } from "./env-
|
|
1
|
+
import { _ as MemoryStore, b 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 } from "./types-4pg-qp_I-Gq63X8Oa.js";
|
|
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
|
|
5
5
|
type MockLlmHandler = (input: LlmCompleteInput) => LlmResponse | Promise<LlmResponse>;
|
package/dist/testing.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as MemoryArtifactStore } from "./memoryArtifactStore-
|
|
2
|
-
import { n as loadGoogleConfigFromEnv, r as loadLlmConfigFromEnv, t as loadAnthropicConfigFromEnv } from "./env
|
|
3
|
-
import { n as MockLlmClient, r as MockUiBridge, t as InMemoryStore } from "./testing-
|
|
1
|
+
import { t as MemoryArtifactStore } from "./memoryArtifactStore-52Zn9npI-BMPYwvoy.js";
|
|
2
|
+
import { n as loadGoogleConfigFromEnv, r as loadLlmConfigFromEnv, t as loadAnthropicConfigFromEnv } from "./env-8cY40DXB-CGnEVZby.js";
|
|
3
|
+
import { n as MockLlmClient, r as MockUiBridge, t as InMemoryStore } from "./testing-CYTFqkDm.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_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' | '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' | '
|
|
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' | 'TOOL_RESOLUTION_EXHAUSTED' | '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' | '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';
|
|
4
4
|
/**
|
|
5
5
|
* 所有公开 API 抛出的结构化错误,code 供上层可编程处理
|
|
6
6
|
* @stable
|
|
@@ -582,7 +582,7 @@ declare function escapeXml(text: string): string;
|
|
|
582
582
|
declare function renderAvailableSkillsXml(catalog: SkillCatalog): string;
|
|
583
583
|
declare const xmlRenderer: CatalogRenderer;
|
|
584
584
|
//#endregion
|
|
585
|
-
//#region ../runtime/dist/types-
|
|
585
|
+
//#region ../runtime/dist/types-4pg-qp_I.d.ts
|
|
586
586
|
//#region src/llm/streamTypes.d.ts
|
|
587
587
|
/** 流式 LLM 事件(OpenAI SSE / Vercel fullStream 统一映射) */
|
|
588
588
|
type LlmStreamEvent = {
|
|
@@ -701,6 +701,7 @@ type InteractionRequest = {
|
|
|
701
701
|
id: string;
|
|
702
702
|
message: string;
|
|
703
703
|
schema?: JsonSchema;
|
|
704
|
+
suggestion?: InteractionSuggestion;
|
|
704
705
|
} | {
|
|
705
706
|
type: 'confirm';
|
|
706
707
|
id: string;
|
|
@@ -719,6 +720,22 @@ type InteractionRequest = {
|
|
|
719
720
|
label: string;
|
|
720
721
|
value: unknown;
|
|
721
722
|
}>;
|
|
723
|
+
suggestion?: InteractionSuggestion;
|
|
724
|
+
} | {
|
|
725
|
+
/**
|
|
726
|
+
* 打开本地文件选择(FR-11.1)。与 `confirm` 分开:浏览器要求
|
|
727
|
+
* `input[type=file].click()` 处于用户手势的调用栈内,渲染层必须能识别
|
|
728
|
+
* 出“这个确认按钮点下去要同步打开选择器”,光看文案分辨不出。
|
|
729
|
+
* @experimental
|
|
730
|
+
*/
|
|
731
|
+
type: 'file-pick';
|
|
732
|
+
id: string;
|
|
733
|
+
message: string;
|
|
734
|
+
/** 传给 `input.accept` 的 MIME / 扩展名列表 */
|
|
735
|
+
accept?: readonly string[];
|
|
736
|
+
multiple?: boolean;
|
|
737
|
+
/** 该文件要填的表单字段名 */
|
|
738
|
+
field?: string;
|
|
722
739
|
} | {
|
|
723
740
|
/**
|
|
724
741
|
* 能力强制授权(require-approval):与脚本自发 confirm 区分,UI 渲染为授权样式
|
|
@@ -735,6 +752,16 @@ interface InteractionResponse {
|
|
|
735
752
|
value?: unknown;
|
|
736
753
|
cancelled?: boolean;
|
|
737
754
|
}
|
|
755
|
+
/**
|
|
756
|
+
* 依据用户画像给出的建议值(FR-19.4)。**不会预填进控件**:
|
|
757
|
+
* 渲染器只能展示它并提供「采纳」入口,用户确认后才算填写。
|
|
758
|
+
* @experimental
|
|
759
|
+
*/
|
|
760
|
+
interface InteractionSuggestion {
|
|
761
|
+
value: unknown;
|
|
762
|
+
/** 建议依据,展示给用户判断是否采纳 */
|
|
763
|
+
reason?: string;
|
|
764
|
+
}
|
|
738
765
|
/** 图表规格($chart 约定的校验后形态;渲染单一来源在 ui/chart/miniChart) */
|
|
739
766
|
interface ChartSpec {
|
|
740
767
|
kind: 'bar' | 'line' | 'pie';
|
|
@@ -873,7 +900,7 @@ interface UiBridge {
|
|
|
873
900
|
interface FormField {
|
|
874
901
|
name: string;
|
|
875
902
|
label: string;
|
|
876
|
-
type: 'text' | 'number' | 'boolean' | 'select' | 'textarea';
|
|
903
|
+
type: 'text' | 'number' | 'boolean' | 'select' | 'textarea' | 'file';
|
|
877
904
|
required?: boolean;
|
|
878
905
|
description?: string;
|
|
879
906
|
defaultValue?: unknown;
|
|
@@ -881,16 +908,14 @@ interface FormField {
|
|
|
881
908
|
label: string;
|
|
882
909
|
value: unknown;
|
|
883
910
|
}>;
|
|
884
|
-
/** 跨会话稳定的字段标识 `<skillName>#<fieldName>`(FR-5.6);缺省表示该字段不参与召回 */
|
|
885
|
-
fieldKey?: string;
|
|
886
911
|
/**
|
|
887
|
-
*
|
|
888
|
-
*
|
|
912
|
+
* 建议值(FR-19.4)。**刻意不叫 defaultValue**:渲染器会把 defaultValue 直接填进控件,
|
|
913
|
+
* 而建议值来自对用户过往行为的推断,可能过时或不适用,必须由用户看到后主动采纳。
|
|
889
914
|
* @experimental
|
|
890
915
|
*/
|
|
891
916
|
suggestion?: {
|
|
892
917
|
value: unknown;
|
|
893
|
-
|
|
918
|
+
reason?: string;
|
|
894
919
|
};
|
|
895
920
|
}
|
|
896
921
|
interface InteractionPolicy {
|
package/dist/ui-react.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as UiSpecEvent, D as UiSurfaceActionResponse, E as UiSurfaceActionRequest, S as UiSpecDrafts, T as UiSpecSnapshot, b as UiBridge, c as InteractionResponse, mt as UiSpecNode, s as InteractionRequest, x as UiSpecActionCapability, y as RenderResultRequest } from "./types-
|
|
2
|
-
import { b as InteractionSpecLabels } from "./index-
|
|
1
|
+
import { C as UiSpecEvent, D as UiSurfaceActionResponse, E as UiSurfaceActionRequest, S as UiSpecDrafts, T as UiSpecSnapshot, b as UiBridge, c as InteractionResponse, mt as UiSpecNode, s as InteractionRequest, x as UiSpecActionCapability, y as RenderResultRequest } from "./types-4pg-qp_I-Gq63X8Oa.js";
|
|
2
|
+
import { b as InteractionSpecLabels } from "./index-BMocOEi0.js";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { ComponentType, ReactNode } from "react";
|
|
5
5
|
import "react/jsx-runtime";
|
package/dist/ui-react.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { r as __exportAll$1 } from "./rolldown-runtime-BOF7iYI8.js";
|
|
2
2
|
import { m as WebSkillError } from "./dist-8oQRa8Xz.js";
|
|
3
|
-
import {
|
|
4
|
-
import { B as toOpenUiSpecLang, I as shapeInteractionValue, O as interactionToFormModel, P as renderMiniChart, Q as chartSpecFromProps, g as applySuggestion, k as interactionToUiSpec, nt as uiCatalog, tt as renderMiniMarkdown, x as collectValues, z as toJsonRenderSpec } from "./dist-
|
|
5
|
-
import { C as Input, S as DropdownMenuTrigger, T as Separator, _ as Checkbox, a as SpecProgress, b as DropdownMenuCheckboxItem, c as SurfaceButton, d as catalogComponentImpls, f as str, g as Button, h as Badge, i as SpecGrid, l as SurfaceField, m as useSurfaceForm, n as CatalogSurfaceProvider, o as SpecTabs, p as useCatalogSurfaceForm, r as EChart, s as SpecTimeline, u as SurfaceFormButtons, v as DataTable, w as Markdown, x as DropdownMenuContent, y as DropdownMenu } from "./catalogComponents-
|
|
3
|
+
import { Ct as validateUiSpecEvent, wt as validateUiSpecNode } from "./dist-DusANsrn.js";
|
|
4
|
+
import { B as toOpenUiSpecLang, I as shapeInteractionValue, O as interactionToFormModel, P as renderMiniChart, Q as chartSpecFromProps, g as applySuggestion, k as interactionToUiSpec, nt as uiCatalog, tt as renderMiniMarkdown, x as collectValues, z as toJsonRenderSpec } from "./dist-DnYG2-eY.js";
|
|
5
|
+
import { C as Input, S as DropdownMenuTrigger, T as Separator, _ as Checkbox, a as SpecProgress, b as DropdownMenuCheckboxItem, c as SurfaceButton, d as catalogComponentImpls, f as str, g as Button, h as Badge, i as SpecGrid, l as SurfaceField, m as useSurfaceForm, n as CatalogSurfaceProvider, o as SpecTabs, p as useCatalogSurfaceForm, r as EChart, s as SpecTimeline, u as SurfaceFormButtons, v as DataTable, w as Markdown, x as DropdownMenuContent, y as DropdownMenu } from "./catalogComponents-Dr5dFMAb-Dacibl1e.js";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import * as React$1 from "react";
|
|
8
8
|
import React, { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
@@ -6367,9 +6367,19 @@ function applyPatch(node, patch) {
|
|
|
6367
6367
|
}
|
|
6368
6368
|
return copy;
|
|
6369
6369
|
}
|
|
6370
|
+
/** 键序无关的序列化:同一份内容不能因写入顺序不同而算两个 surface(FR-21.5) */
|
|
6371
|
+
function stableStringify(value) {
|
|
6372
|
+
if (Array.isArray(value)) return `[${value.map(stableStringify).join(",")}]`;
|
|
6373
|
+
if (isRecord(value)) return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(value[key])}`).join(",")}}`;
|
|
6374
|
+
return JSON.stringify(value) ?? "null";
|
|
6375
|
+
}
|
|
6370
6376
|
/** Observable, revision-checked snapshot store for framework-neutral UI surfaces. @experimental */
|
|
6371
6377
|
var UiSurfaceStore = class {
|
|
6372
6378
|
#entries = /* @__PURE__ */ new Map();
|
|
6379
|
+
/** 内容指纹 → 首次开的 surface id;仅在同一 runId 内合并 */
|
|
6380
|
+
#fingerprints = /* @__PURE__ */ new Map();
|
|
6381
|
+
/** 后到的重复 id → 已存在的 surface id,让后续 patch/complete 仍然寻址得到 */
|
|
6382
|
+
#aliases = /* @__PURE__ */ new Map();
|
|
6373
6383
|
#listeners = /* @__PURE__ */ new Set();
|
|
6374
6384
|
#snapshots = [];
|
|
6375
6385
|
#patchEmitTimer;
|
|
@@ -6383,23 +6393,36 @@ var UiSurfaceStore = class {
|
|
|
6383
6393
|
apply(event) {
|
|
6384
6394
|
event = validateUiSpecEvent(event);
|
|
6385
6395
|
switch (event.type) {
|
|
6386
|
-
case "open":
|
|
6387
|
-
|
|
6396
|
+
case "open": {
|
|
6397
|
+
const snapshot = {
|
|
6388
6398
|
id: event.id,
|
|
6389
6399
|
node: structuredClone(event.node),
|
|
6390
6400
|
...event.actions ? { actions: structuredClone(event.actions) } : {},
|
|
6391
6401
|
revision: 0,
|
|
6392
6402
|
status: "active",
|
|
6393
6403
|
...event.runId ? { runId: event.runId } : {}
|
|
6394
|
-
}
|
|
6404
|
+
};
|
|
6405
|
+
const fingerprint = this.#fingerprint(event);
|
|
6406
|
+
const merged = fingerprint === void 0 ? void 0 : this.#fingerprints.get(fingerprint);
|
|
6407
|
+
if (merged !== void 0 && this.#entries.has(merged)) {
|
|
6408
|
+
this.#aliases.set(event.id, merged);
|
|
6409
|
+
this.#entries.set(merged, {
|
|
6410
|
+
...snapshot,
|
|
6411
|
+
id: merged
|
|
6412
|
+
});
|
|
6413
|
+
} else {
|
|
6414
|
+
if (fingerprint !== void 0) this.#fingerprints.set(fingerprint, event.id);
|
|
6415
|
+
this.#entries.set(event.id, snapshot);
|
|
6416
|
+
}
|
|
6395
6417
|
break;
|
|
6418
|
+
}
|
|
6396
6419
|
case "patch": {
|
|
6397
6420
|
const current = this.#entry(event.id);
|
|
6398
6421
|
this.#assertRunId(current, event.runId);
|
|
6399
6422
|
if (current.status !== "active" || event.revision !== current.revision + 1) throw new WebSkillError("VALIDATION_FAILED", `Surface patch revision is invalid for "${event.id}"`);
|
|
6400
6423
|
let node = current.node;
|
|
6401
6424
|
for (const operation of event.operations) node = applyPatch(node, operation);
|
|
6402
|
-
this.#entries.set(
|
|
6425
|
+
this.#entries.set(current.id, {
|
|
6403
6426
|
...current,
|
|
6404
6427
|
node: validateUiSpecNode(node),
|
|
6405
6428
|
revision: event.revision
|
|
@@ -6410,7 +6433,7 @@ var UiSurfaceStore = class {
|
|
|
6410
6433
|
const current = this.#entry(event.id);
|
|
6411
6434
|
this.#assertRunId(current, event.runId);
|
|
6412
6435
|
if (event.revision !== current.revision) throw new WebSkillError("VALIDATION_FAILED", `Surface completion revision is invalid for "${event.id}"`);
|
|
6413
|
-
this.#entries.set(
|
|
6436
|
+
this.#entries.set(current.id, {
|
|
6414
6437
|
...current,
|
|
6415
6438
|
status: "complete"
|
|
6416
6439
|
});
|
|
@@ -6419,7 +6442,7 @@ var UiSurfaceStore = class {
|
|
|
6419
6442
|
case "error": {
|
|
6420
6443
|
const current = this.#entry(event.id);
|
|
6421
6444
|
this.#assertRunId(current, event.runId);
|
|
6422
|
-
this.#entries.set(
|
|
6445
|
+
this.#entries.set(current.id, {
|
|
6423
6446
|
...current,
|
|
6424
6447
|
status: "error",
|
|
6425
6448
|
error: {
|
|
@@ -6432,7 +6455,7 @@ var UiSurfaceStore = class {
|
|
|
6432
6455
|
case "cancel": {
|
|
6433
6456
|
const current = this.#entry(event.id);
|
|
6434
6457
|
this.#assertRunId(current, event.runId);
|
|
6435
|
-
this.#entries.set(
|
|
6458
|
+
this.#entries.set(current.id, {
|
|
6436
6459
|
...current,
|
|
6437
6460
|
status: "cancelled"
|
|
6438
6461
|
});
|
|
@@ -6446,8 +6469,16 @@ var UiSurfaceStore = class {
|
|
|
6446
6469
|
this.#emit();
|
|
6447
6470
|
}
|
|
6448
6471
|
}
|
|
6472
|
+
/** 跨 run 的相同界面是合法重复(用户又问了一次),所以无 runId 时不合并 */
|
|
6473
|
+
#fingerprint(event) {
|
|
6474
|
+
if (event.runId === void 0) return void 0;
|
|
6475
|
+
return `${event.runId}\u0000${stableStringify({
|
|
6476
|
+
node: event.node,
|
|
6477
|
+
actions: event.actions ?? null
|
|
6478
|
+
})}`;
|
|
6479
|
+
}
|
|
6449
6480
|
#entry(id) {
|
|
6450
|
-
const entry = this.#entries.get(id);
|
|
6481
|
+
const entry = this.#entries.get(this.#aliases.get(id) ?? id);
|
|
6451
6482
|
if (!entry) throw new WebSkillError("VALIDATION_FAILED", `Unknown UI surface "${id}"`);
|
|
6452
6483
|
return entry;
|
|
6453
6484
|
}
|
|
@@ -6625,25 +6656,37 @@ var ReactBridgeState = class {
|
|
|
6625
6656
|
}
|
|
6626
6657
|
};
|
|
6627
6658
|
/**
|
|
6628
|
-
*
|
|
6659
|
+
* 建议值以**建议**形态出现(FR-19.4):控件初始值仍为空,
|
|
6629
6660
|
* 用户点「使用」才写入。切勿改成 defaultValue。
|
|
6630
6661
|
*/
|
|
6631
6662
|
function Suggestion({ control, onUse }) {
|
|
6632
6663
|
if (control.suggestion === void 0) return null;
|
|
6633
6664
|
const preview = String(control.suggestion.value);
|
|
6665
|
+
const reason = control.suggestion.reason;
|
|
6634
6666
|
return /* @__PURE__ */ jsxs("div", {
|
|
6635
6667
|
className: "webskill-form__suggestion",
|
|
6636
6668
|
"data-webskill-suggestion": control.name,
|
|
6637
|
-
children: [
|
|
6638
|
-
|
|
6639
|
-
|
|
6640
|
-
|
|
6641
|
-
|
|
6642
|
-
|
|
6643
|
-
|
|
6644
|
-
|
|
6645
|
-
|
|
6646
|
-
|
|
6669
|
+
children: [
|
|
6670
|
+
/* @__PURE__ */ jsxs("span", {
|
|
6671
|
+
className: "webskill-form__suggestion-value",
|
|
6672
|
+
children: ["Suggested: ", preview]
|
|
6673
|
+
}),
|
|
6674
|
+
reason ? /* @__PURE__ */ jsxs("span", {
|
|
6675
|
+
className: "webskill-form__suggestion-reason",
|
|
6676
|
+
children: [
|
|
6677
|
+
"(",
|
|
6678
|
+
reason,
|
|
6679
|
+
")"
|
|
6680
|
+
]
|
|
6681
|
+
}) : null,
|
|
6682
|
+
/* @__PURE__ */ jsx("button", {
|
|
6683
|
+
type: "button",
|
|
6684
|
+
className: "webskill-form__suggestion-use",
|
|
6685
|
+
"data-webskill-suggestion-use": control.name,
|
|
6686
|
+
onClick: onUse,
|
|
6687
|
+
children: "Use"
|
|
6688
|
+
})
|
|
6689
|
+
]
|
|
6647
6690
|
});
|
|
6648
6691
|
}
|
|
6649
6692
|
function Control({ control, invalid }) {
|
|
@@ -7493,7 +7536,7 @@ function OpenUiSpecSurface({ spec, surfaceId, actions, onAction }) {
|
|
|
7493
7536
|
const [unavailable, setUnavailable] = useState(false);
|
|
7494
7537
|
useEffect(() => {
|
|
7495
7538
|
let cancelled = false;
|
|
7496
|
-
import("./openUiLibrary-
|
|
7539
|
+
import("./openUiLibrary-Bdrji9qK-DzAxRlTY.js").then((loaded) => {
|
|
7497
7540
|
if (!cancelled) setModule(loaded);
|
|
7498
7541
|
}).catch(() => {
|
|
7499
7542
|
if (!cancelled) setUnavailable(true);
|
package/dist/ui-vue.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as UiBridge, c as InteractionResponse, s as InteractionRequest, y as RenderResultRequest } from "./types-
|
|
1
|
+
import { b as UiBridge, c as InteractionResponse, s as InteractionRequest, y as RenderResultRequest } from "./types-4pg-qp_I-Gq63X8Oa.js";
|
|
2
2
|
import { PropType } from "vue";
|
|
3
3
|
//#region ../ui-vue/dist/index.d.ts
|
|
4
4
|
//#region src/bridgeState.d.ts
|