@webskill/sdk 0.16.0 → 0.18.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 +17 -10
- package/dist/{approval-BnLLCOG0.js → approval-B7GW86u2.js} +58 -5
- package/dist/browser.d.ts +87 -5
- package/dist/browser.js +300 -21
- package/dist/governance.d.ts +3 -3
- package/dist/governance.js +1 -1
- package/dist/{index-DbVqg2V3.d.ts → index-BDyXe-a5.d.ts} +1 -1
- package/dist/{index-DeXgdtHa.d.ts → index-CaLsVI-m.d.ts} +7 -2
- package/dist/{index-BLfnO7sz.d.ts → index-DQ3-6GFu.d.ts} +32 -11
- package/dist/index.d.ts +3 -3
- package/dist/index.js +4 -4
- package/dist/{llm-B7lLH0ZI.js → llm-eIQNO9tr.js} +67 -12
- package/dist/mcp.d.ts +2 -2
- package/dist/node.d.ts +3 -3
- package/dist/node.js +13 -7
- package/dist/{openUiLibrary-BWEBU9P-.js → openUiLibrary-BJtCG5B1.js} +1 -1
- package/dist/{openUiSpecLang-BIK6CWlW.js → openUiSpecLang-B4QQ9Tfo.js} +3 -2
- package/dist/{skillVersionStore-B24Jjjry-CsbzF7Oe.d.ts → skillVersionStore-B24Jjjry-v2CCU0Xo.d.ts} +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1 -1
- package/dist/{types-C3V6lAeO-BUpcRLER.d.ts → types-Btpdd1y--BcxQ10Fa.d.ts} +9 -3
- package/dist/{types-BuacBov_.js → types-DOJI5YC3.js} +4 -3
- package/dist/ui-react.d.ts +3 -3
- package/dist/ui-react.js +2 -2
- package/dist/ui-vue.d.ts +1 -1
- package/dist/ui.d.ts +3 -3
- package/dist/ui.js +2 -2
- package/dist/{webSkillApi-DOOyz2G5.js → webSkillApi-DMENIqW0.js} +1 -1
- package/dist/{webskillLitCatalog-poL1qhBp.js → webskillLitCatalog-BBkQjKuN.js} +1 -1
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -2,11 +2,11 @@ import { n as messageOf, t as WebSkillError } from "./errors-BDZNpC13.js";
|
|
|
2
2
|
import { A as SKILL_MANIFEST_FILE, D as verifySkillSignature, M as buildManifest, O as MANIFEST_EXCLUDED_FILES, P as verifyManifest, b as parseSkillMarkdown, c as unzipWithLimits, f as SKILL_PACK_FILE, i as buildCatalog, k as SKILLS_LOCKFILE, m as parseSkillPackManifest, n as SkillDiscovery, o as readResponseWithLimit, p as exportSkills, t as validateSkills, u as detectSkillArchiveShapeFromFs, w as readSkillSignature, y as isValidSkillName } from "./skill-CAJMsLod.js";
|
|
3
3
|
import { a as atomicWriteText, o as isAtomicTempPath, r as resolveInsideRoot } from "./pathSecurity-B1owvJAF.js";
|
|
4
4
|
import { t as assertRemoteUrlAllowed } from "./urlSafety-CiSuCJvX.js";
|
|
5
|
-
import { a as networkPolicyLibSource, c as bridgeError, d as FsMemoryStore, g as FsRunSnapshotStore, l as parseBridgeRequest, nt as ProgressiveRouter, p as AgentLoop, r as normalizeToolError, s as UPLOAD_FILES_UNAVAILABLE, t as CapabilityApproval, u as FsArtifactStore } from "./approval-
|
|
6
|
-
import { a as GoogleGenAiClient, o as AnthropicClient, s as OpenAiCompatibleClient, t as MockLlmClient } from "./llm-
|
|
5
|
+
import { a as networkPolicyLibSource, c as bridgeError, d as FsMemoryStore, g as FsRunSnapshotStore, l as parseBridgeRequest, nt as ProgressiveRouter, p as AgentLoop, r as normalizeToolError, s as UPLOAD_FILES_UNAVAILABLE, t as CapabilityApproval, u as FsArtifactStore } from "./approval-B7GW86u2.js";
|
|
6
|
+
import { a as GoogleGenAiClient, o as AnthropicClient, s as OpenAiCompatibleClient, t as MockLlmClient } from "./llm-eIQNO9tr.js";
|
|
7
7
|
import { n as normalizeToolContent, t as mergeCatalogEntries } from "./external-_ZRQe-V9.js";
|
|
8
|
-
import { t as createWebSkillApi } from "./webSkillApi-
|
|
9
|
-
import { a as frameLabel, i as toFrameScopes, o as frameSteps, r as toActionFrameScopes } from "./types-
|
|
8
|
+
import { t as createWebSkillApi } from "./webSkillApi-DMENIqW0.js";
|
|
9
|
+
import { a as frameLabel, i as toFrameScopes, o as frameSteps, r as toActionFrameScopes } from "./types-DOJI5YC3.js";
|
|
10
10
|
|
|
11
11
|
//#region ../browser/src/fs/featureDetection.ts
|
|
12
12
|
/** 检测当前环境是否可用 OPFS(navigator.storage.getDirectory) */
|
|
@@ -1355,13 +1355,16 @@ var BrowserWorkerScriptExecutor = class {
|
|
|
1355
1355
|
}
|
|
1356
1356
|
/** 能力桥宿主侧处理:能力关闭/授权拒绝即 TOOL_UNSUPPORTED;判定逻辑共用 runtime/sandbox/approval */
|
|
1357
1357
|
async #handleBridge(request, context) {
|
|
1358
|
-
const gate = async (capability, message, details) => {
|
|
1358
|
+
const gate = async (capability, message, details = {}) => {
|
|
1359
1359
|
const decision = await this.#approval.authorize({
|
|
1360
1360
|
runId: context.runId,
|
|
1361
1361
|
capability,
|
|
1362
1362
|
mode: this.#capabilities[capability],
|
|
1363
1363
|
message,
|
|
1364
|
-
|
|
1364
|
+
details: {
|
|
1365
|
+
skill: context.skillName,
|
|
1366
|
+
...details
|
|
1367
|
+
}
|
|
1365
1368
|
});
|
|
1366
1369
|
if (decision === "allowed") return void 0;
|
|
1367
1370
|
return bridgeError(request.id, "TOOL_UNSUPPORTED", decision === "disabled" ? `Capability "${capability}" is disabled by the sandbox capability settings` : `Capability "${capability}" was denied by the user`);
|
|
@@ -1419,7 +1422,7 @@ var BrowserWorkerScriptExecutor = class {
|
|
|
1419
1422
|
}
|
|
1420
1423
|
case "confirm": {
|
|
1421
1424
|
if (!context.confirm) return bridgeError(request.id, "TOOL_UNSUPPORTED", "Capability \"confirm\" is disabled");
|
|
1422
|
-
const denied = await gate("confirm", `Script "${context.skillName}" asks for confirmation: ${request.message}
|
|
1425
|
+
const denied = await gate("confirm", `Script "${context.skillName}" asks for confirmation: ${request.message}`, { question: request.message });
|
|
1423
1426
|
if (denied) return denied;
|
|
1424
1427
|
return {
|
|
1425
1428
|
id: request.id,
|
|
@@ -1677,7 +1680,7 @@ function checkDictationAvailability() {
|
|
|
1677
1680
|
return { available: true };
|
|
1678
1681
|
}
|
|
1679
1682
|
/** 浏览器的 error 码 → 稳定错误码;权限被拒要单独区分,UI 的降级提示不一样(FR-7.6) */
|
|
1680
|
-
function toError(code, message) {
|
|
1683
|
+
function toError$1(code, message) {
|
|
1681
1684
|
if (code === "not-allowed" || code === "service-not-allowed") return new WebSkillError("DICTATION_PERMISSION_DENIED", "Microphone access was denied. Voice input is unavailable until you allow it in the browser.", { reason: code });
|
|
1682
1685
|
return new WebSkillError("DICTATION_FAILED", message ?? `Speech recognition failed: ${code}`, { reason: code });
|
|
1683
1686
|
}
|
|
@@ -1713,7 +1716,7 @@ function startDictation(options) {
|
|
|
1713
1716
|
recognition.onerror = (event) => {
|
|
1714
1717
|
if (stopped) return;
|
|
1715
1718
|
if (event.error === "no-speech" || event.error === "aborted") return;
|
|
1716
|
-
options.onError(toError(event.error, event.message));
|
|
1719
|
+
options.onError(toError$1(event.error, event.message));
|
|
1717
1720
|
};
|
|
1718
1721
|
try {
|
|
1719
1722
|
recognition.start();
|
|
@@ -1730,6 +1733,107 @@ function startDictation(options) {
|
|
|
1730
1733
|
} };
|
|
1731
1734
|
}
|
|
1732
1735
|
|
|
1736
|
+
//#endregion
|
|
1737
|
+
//#region ../browser/src/media/camera.ts
|
|
1738
|
+
/**
|
|
1739
|
+
* 默认最长边:宿主要「最大分辨率」,给一个远超当前消费级摄像头的 ideal 让浏览器自己贴顶
|
|
1740
|
+
* @experimental
|
|
1741
|
+
*/
|
|
1742
|
+
const DEFAULT_CAMERA_MAX_DIMENSION = 5e3;
|
|
1743
|
+
function mediaDevices() {
|
|
1744
|
+
return globalThis.navigator?.mediaDevices;
|
|
1745
|
+
}
|
|
1746
|
+
/**
|
|
1747
|
+
* 渲染期调用(FR-14.2):不可用时按钮置灰并说明原因。
|
|
1748
|
+
*
|
|
1749
|
+
* 顺序与语音一致——`getUserMedia` 压根不存在时谈安全上下文没有意义;
|
|
1750
|
+
* API 在但站点是 http,取流一定会被浏览器拒绝,这条原因用户能自己解决。
|
|
1751
|
+
* @experimental
|
|
1752
|
+
*/
|
|
1753
|
+
function checkCameraAvailability() {
|
|
1754
|
+
if (typeof mediaDevices()?.getUserMedia !== "function") return {
|
|
1755
|
+
available: false,
|
|
1756
|
+
reason: "api-missing"
|
|
1757
|
+
};
|
|
1758
|
+
if (globalThis.isSecureContext === false) return {
|
|
1759
|
+
available: false,
|
|
1760
|
+
reason: "insecure-context"
|
|
1761
|
+
};
|
|
1762
|
+
return { available: true };
|
|
1763
|
+
}
|
|
1764
|
+
/** DOMException 的 name → 稳定错误码;权限被拒要单独区分,UI 的降级提示不一样(FR-14.6) */
|
|
1765
|
+
function toError(e) {
|
|
1766
|
+
const raw = e?.name;
|
|
1767
|
+
const name = typeof raw === "string" ? raw : "";
|
|
1768
|
+
if (name === "NotAllowedError" || name === "SecurityError") return new WebSkillError("CAMERA_PERMISSION_DENIED", "Camera access was denied. Photo capture is unavailable until you allow it in the browser.", { reason: name });
|
|
1769
|
+
const message = e?.message;
|
|
1770
|
+
return new WebSkillError("CAMERA_UNAVAILABLE", `The camera could not be opened: ${typeof message === "string" && message !== "" ? message : String(e)}`, { ...name !== "" ? { reason: name } : {} });
|
|
1771
|
+
}
|
|
1772
|
+
/**
|
|
1773
|
+
* 打开摄像头取景(FR-14.1)。
|
|
1774
|
+
*
|
|
1775
|
+
* **只能由用户手势调用**(FR-14.4)。设计上的保证是它不进工具列表:
|
|
1776
|
+
* agent 拿不到「打开摄像头」这个动作,因此不存在自主开摄像头的路径。
|
|
1777
|
+
* @experimental
|
|
1778
|
+
*/
|
|
1779
|
+
async function openCamera(options = {}) {
|
|
1780
|
+
const devices = mediaDevices();
|
|
1781
|
+
if (typeof devices?.getUserMedia !== "function") throw new WebSkillError("CAMERA_UNAVAILABLE", "Camera capture is not available in this browser.");
|
|
1782
|
+
const max = options.maxDimension ?? 5e3;
|
|
1783
|
+
let stream;
|
|
1784
|
+
try {
|
|
1785
|
+
stream = await devices.getUserMedia({
|
|
1786
|
+
video: {
|
|
1787
|
+
width: { ideal: max },
|
|
1788
|
+
height: { ideal: max },
|
|
1789
|
+
...options.facingMode !== void 0 ? { facingMode: options.facingMode } : {}
|
|
1790
|
+
},
|
|
1791
|
+
audio: false
|
|
1792
|
+
});
|
|
1793
|
+
} catch (e) {
|
|
1794
|
+
throw toError(e);
|
|
1795
|
+
}
|
|
1796
|
+
return {
|
|
1797
|
+
stream,
|
|
1798
|
+
resolution() {
|
|
1799
|
+
const settings = stream.getVideoTracks()[0]?.getSettings();
|
|
1800
|
+
return {
|
|
1801
|
+
width: settings?.width ?? 0,
|
|
1802
|
+
height: settings?.height ?? 0
|
|
1803
|
+
};
|
|
1804
|
+
},
|
|
1805
|
+
close() {
|
|
1806
|
+
for (const track of stream.getTracks()) track.stop();
|
|
1807
|
+
}
|
|
1808
|
+
};
|
|
1809
|
+
}
|
|
1810
|
+
/**
|
|
1811
|
+
* 把取景元素的**当前一帧**编码成文件(FR-14.5)。
|
|
1812
|
+
*
|
|
1813
|
+
* 尺寸取 `videoWidth`/`videoHeight`(轨道原生分辨率),不取 CSS 尺寸——
|
|
1814
|
+
* 预览区被布局缩到 320px 宽,照着画出来的就是 320px 的照片。
|
|
1815
|
+
* 编码交给平台的 canvas,不手写编码器(AGENTS.md §6)。
|
|
1816
|
+
* @experimental
|
|
1817
|
+
*/
|
|
1818
|
+
async function capturePhoto(video, options = {}) {
|
|
1819
|
+
const width = video.videoWidth;
|
|
1820
|
+
const height = video.videoHeight;
|
|
1821
|
+
if (width === 0 || height === 0) throw new WebSkillError("CAMERA_CAPTURE_FAILED", "The camera has not produced a frame yet.");
|
|
1822
|
+
const type = options.type ?? "image/jpeg";
|
|
1823
|
+
const canvas = document.createElement("canvas");
|
|
1824
|
+
canvas.width = width;
|
|
1825
|
+
canvas.height = height;
|
|
1826
|
+
const context = canvas.getContext("2d");
|
|
1827
|
+
if (context === null) throw new WebSkillError("CAMERA_CAPTURE_FAILED", "This browser did not provide a 2D canvas context.");
|
|
1828
|
+
context.drawImage(video, 0, 0, width, height);
|
|
1829
|
+
const blob = await new Promise((resolve) => {
|
|
1830
|
+
canvas.toBlob(resolve, type, options.quality ?? .92);
|
|
1831
|
+
});
|
|
1832
|
+
if (blob === null) throw new WebSkillError("CAMERA_CAPTURE_FAILED", `The captured frame could not be encoded as ${type}.`);
|
|
1833
|
+
const name = options.fileName ?? `photo-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.jpg`;
|
|
1834
|
+
return new File([blob], name, { type: blob.type === "" ? type : blob.type });
|
|
1835
|
+
}
|
|
1836
|
+
|
|
1733
1837
|
//#endregion
|
|
1734
1838
|
//#region ../browser/src/media/compressImage.ts
|
|
1735
1839
|
/** 动图无法在不丢帧的前提下走单帧编码管线,超限直接拒绝(裁决 D-2) */
|
|
@@ -2013,6 +2117,17 @@ function isAnimatedWebp(bytes) {
|
|
|
2013
2117
|
].every((byte, index) => bytes[12 + index] === byte) && ((bytes[20] ?? 0) & 2) !== 0;
|
|
2014
2118
|
}
|
|
2015
2119
|
/**
|
|
2120
|
+
* APNG:`acTL` 块。规范要求它排在第一个 `IDAT` 之前,所以嗅探头部就够。
|
|
2121
|
+
* 魔数与静态 PNG 完全相同,只看魔数会让加载动画这类素材当作静态图原样发出去。
|
|
2122
|
+
*/
|
|
2123
|
+
function isAnimatedPng(bytes) {
|
|
2124
|
+
for (let i = 8; i + 4 <= bytes.length; i += 1) {
|
|
2125
|
+
if (bytes[i] === 73 && bytes[i + 1] === 68 && bytes[i + 2] === 65 && bytes[i + 3] === 84) return false;
|
|
2126
|
+
if (bytes[i] === 97 && bytes[i + 1] === 99 && bytes[i + 2] === 84 && bytes[i + 3] === 76) return true;
|
|
2127
|
+
}
|
|
2128
|
+
return false;
|
|
2129
|
+
}
|
|
2130
|
+
/**
|
|
2016
2131
|
* 按魔数认图片类型(服务端声明只作兜底)。
|
|
2017
2132
|
*
|
|
2018
2133
|
* 图片接口常年是「无扩展名 + `application/octet-stream`」这种组合(查询串带 file id 的尤其多),
|
|
@@ -2065,7 +2180,7 @@ async function rasterizeToPng(blob) {
|
|
|
2065
2180
|
* 照抄声明会让端点解码失败并连累整次请求(一张图 400,37 张全废)。
|
|
2066
2181
|
*
|
|
2067
2182
|
* 魔数对得上也不等于发得出去,还有两类会被端点整次拒收,必须重编码成单帧位图:
|
|
2068
|
-
* - **动图**(GIF 天然多帧,WebP 看 `VP8X`
|
|
2183
|
+
* - **动图**(GIF 天然多帧,WebP 看 `VP8X` 的动画位,PNG 看 `acTL` 块):图片通道普遍只收静态图;
|
|
2069
2184
|
* - **超长边**:横幅类素材常见 7680×120 这种尺寸,字节数却很小,
|
|
2070
2185
|
* 纯按字节压缩的预算根本不会触发,原样发出去就撞上端点的边长上限。
|
|
2071
2186
|
*
|
|
@@ -2077,7 +2192,7 @@ async function toDeliverableBlob(blob, oversized = false) {
|
|
|
2077
2192
|
const sniffed = sniffImageMime(head);
|
|
2078
2193
|
if (sniffed !== void 0 && DELIVERABLE_IMAGE_MIME_TYPES.has(sniffed)) {
|
|
2079
2194
|
const typed = sniffed === declared ? blob : new Blob([blob], { type: sniffed });
|
|
2080
|
-
const animated = sniffed === "image/gif" || sniffed === "image/webp" && isAnimatedWebp(head);
|
|
2195
|
+
const animated = sniffed === "image/gif" || sniffed === "image/webp" && isAnimatedWebp(head) || sniffed === "image/png" && isAnimatedPng(head);
|
|
2081
2196
|
return oversized || animated ? await rasterizeToPng(typed) : typed;
|
|
2082
2197
|
}
|
|
2083
2198
|
const mimeType = sniffed ?? (declared.startsWith("image/") ? declared : void 0);
|
|
@@ -2158,11 +2273,20 @@ const ROUTE_ATTRIBUTES = [
|
|
|
2158
2273
|
"data-href",
|
|
2159
2274
|
"data-url"
|
|
2160
2275
|
];
|
|
2161
|
-
/**
|
|
2276
|
+
/**
|
|
2277
|
+
* 可被启发式信号提升的角色:其余角色要么本就能发句柄,要么带着不该被覆盖的语义(D-15-3)。
|
|
2278
|
+
*
|
|
2279
|
+
* `listitem` 在列表里本该只是结构,但 `<ul><li>` 是自绘下拉 / 菜单的主流写法,
|
|
2280
|
+
* 选项往往就是不带 role 的 `<li>`(0.17.0 分册 11)。它与另外三个一样受
|
|
2281
|
+
* 「有可操作后代就不提升」约束,所以真正的语义列表不会被误伤。
|
|
2282
|
+
*
|
|
2283
|
+
* 这张白名单**只约束启发式信号**。宿主探针点名的元素走另一条路(分册 12)。
|
|
2284
|
+
*/
|
|
2162
2285
|
const PROMOTABLE_ROLES = /* @__PURE__ */ new Set([
|
|
2163
2286
|
"generic",
|
|
2164
2287
|
"img",
|
|
2165
|
-
"cell"
|
|
2288
|
+
"cell",
|
|
2289
|
+
"listitem"
|
|
2166
2290
|
]);
|
|
2167
2291
|
/** 合成名的前缀,必须让模型看得出「这不是页面上的字,别拿它去搜」(FR-15.4 第 3 级) */
|
|
2168
2292
|
const SYNTHETIC_NAME_PREFIX = "unlabeled control";
|
|
@@ -2264,10 +2388,11 @@ function synthesizeName(element, nameOf) {
|
|
|
2264
2388
|
}
|
|
2265
2389
|
/** 提升后的角色与导航目标;未提升时返回 undefined */
|
|
2266
2390
|
function promoteRole(input) {
|
|
2267
|
-
const { element, role, doc, hasActionableDescendant, context } = input;
|
|
2391
|
+
const { element, role, doc, hasActionableDescendant, selfActionable, context } = input;
|
|
2268
2392
|
const hinted = hintedRoleOf(element, context.roleHints);
|
|
2269
2393
|
if (hinted !== void 0) return { role: hinted };
|
|
2270
|
-
if (
|
|
2394
|
+
if (selfActionable) return void 0;
|
|
2395
|
+
if (!(context.interactiveHint?.(element) === true) && !PROMOTABLE_ROLES.has(role)) return void 0;
|
|
2271
2396
|
if (hasActionableDescendant && role !== "img") return void 0;
|
|
2272
2397
|
if (!looksInteractive(element, context)) return void 0;
|
|
2273
2398
|
const href = navigationTargetOf(element, doc);
|
|
@@ -2495,6 +2620,7 @@ function describe(element, excluded, doc, view, capture, handles, frame, provena
|
|
|
2495
2620
|
role,
|
|
2496
2621
|
doc,
|
|
2497
2622
|
hasActionableDescendant: children.some((child) => child.ref !== void 0 && handles?.isAction(child.ref) === true),
|
|
2623
|
+
selfActionable: ACTIONABLE_ROLES.has(role),
|
|
2498
2624
|
context: promotion
|
|
2499
2625
|
});
|
|
2500
2626
|
if (promoted !== void 0) {
|
|
@@ -3072,6 +3198,31 @@ function documentKey(view) {
|
|
|
3072
3198
|
//#endregion
|
|
3073
3199
|
//#region ../browser/src/dom/pageAction.ts
|
|
3074
3200
|
const FILLABLE_TAGS = /* @__PURE__ */ new Set(["INPUT", "TEXTAREA"]);
|
|
3201
|
+
/**
|
|
3202
|
+
* 滚动稳定化的等待边界(毫秒);宿主注入值被夹在这之间。
|
|
3203
|
+
* 刻意**不导出**:本册只登记了一处新增公开契约(`scrollSettleMs`),
|
|
3204
|
+
* 多导出一个常量就是多一处要维护的公开面,而宿主注入超界值本来就会被夹住。
|
|
3205
|
+
*/
|
|
3206
|
+
const SCROLL_SETTLE_BOUNDS = {
|
|
3207
|
+
min: 300,
|
|
3208
|
+
max: 5e3,
|
|
3209
|
+
default: 800
|
|
3210
|
+
};
|
|
3211
|
+
/**
|
|
3212
|
+
* 滚动后等待渲染的两个时长。
|
|
3213
|
+
*
|
|
3214
|
+
* 只有「静默窗口」是不够的,而且这里的顺序容易搞反:虚拟列表在 `scroll` 事件后要经过
|
|
3215
|
+
* 一次 rAF、甚至一段节流才**开始**重渲染,那之前观察器一直是静默的。
|
|
3216
|
+
* 若把「一直没动静」直接判成「渲染完了」,就会在渲染开始之前返回,读到滚动前的旧行——
|
|
3217
|
+
* 而且页面越慢越容易中招,正好是最需要滚动的那类页面。
|
|
3218
|
+
*
|
|
3219
|
+
* 所以两段分开:**还没见过任何变更**时按「等首次变更」的宽限期算,
|
|
3220
|
+
* 见过之后才按静默窗口算。宽限期取 250ms 是为了盖住常见的 100ms 节流加一帧渲染。
|
|
3221
|
+
*/
|
|
3222
|
+
const SCROLL_SETTLE_FIRST_CHANGE_MS = 250;
|
|
3223
|
+
const SCROLL_SETTLE_QUIET_MS = 80;
|
|
3224
|
+
/** 两屏之间的重叠身位(像素)。必须大于 0,否则横跨视口边界的那一行会在两次感知之间消失 */
|
|
3225
|
+
const SCROLL_OVERLAP_PX = 64;
|
|
3075
3226
|
/** 只看显式声明,不看尺寸:jsdom 有 getComputedStyle 但没有布局 */
|
|
3076
3227
|
function hidden(element) {
|
|
3077
3228
|
if (element.hasAttribute("hidden")) return true;
|
|
@@ -3154,6 +3305,19 @@ function fillValue(element, value) {
|
|
|
3154
3305
|
}
|
|
3155
3306
|
const norm = (text) => (text ?? "").replace(/\s+/g, " ").trim().toLowerCase();
|
|
3156
3307
|
/**
|
|
3308
|
+
* 激活一个元素。
|
|
3309
|
+
*
|
|
3310
|
+
* `click()` 只定义在 `HTMLElement` 上:内联 `<svg>`(以及其它外来命名空间的元素)
|
|
3311
|
+
* 拿到的是 `undefined`,直接调会抛 `TypeError`,整次操作倒在最后一步。
|
|
3312
|
+
* 图标把监听器挂在 `<svg>` 本体上是常见写法,所以这条路径必须通。
|
|
3313
|
+
* 退路是派发一个真正的 `click` 事件:它照样冒泡,祖先 `<a>` 的激活行为也照样跑。
|
|
3314
|
+
*/
|
|
3315
|
+
function activate(element, init) {
|
|
3316
|
+
const native = element.click;
|
|
3317
|
+
if (typeof native === "function") native.call(element);
|
|
3318
|
+
else element.dispatchEvent(new MouseEvent("click", init));
|
|
3319
|
+
}
|
|
3320
|
+
/**
|
|
3157
3321
|
* 一次「像人一样」的点击。
|
|
3158
3322
|
*
|
|
3159
3323
|
* `HTMLElement.click()` **只**派发 `click`,不派发指针/鼠标序列,也不移动焦点。
|
|
@@ -3199,7 +3363,7 @@ function press(element) {
|
|
|
3199
3363
|
...base,
|
|
3200
3364
|
buttons: 0
|
|
3201
3365
|
}));
|
|
3202
|
-
element
|
|
3366
|
+
activate(element, base);
|
|
3203
3367
|
}
|
|
3204
3368
|
/** 轮询等待,上限固定:等不到就失败,不能无限挂着一次工具调用 */
|
|
3205
3369
|
async function waitFor(probe, timeoutMs = 2e3) {
|
|
@@ -3244,7 +3408,13 @@ async function selectOption(element, value) {
|
|
|
3244
3408
|
if (listbox === null || listbox === void 0) return fail("The options panel did not open.");
|
|
3245
3409
|
const option = [...listbox.querySelectorAll("[role=option], [role=gridcell], [role=menuitem], option")].find((candidate) => norm(accessibleName(candidate)) === norm(value));
|
|
3246
3410
|
if (option === void 0) return fail(`No option named "${value}" is available.`);
|
|
3247
|
-
option
|
|
3411
|
+
activate(option, {
|
|
3412
|
+
bubbles: true,
|
|
3413
|
+
cancelable: true,
|
|
3414
|
+
composed: true,
|
|
3415
|
+
detail: 1,
|
|
3416
|
+
button: 0
|
|
3417
|
+
});
|
|
3248
3418
|
return await waitFor(() => {
|
|
3249
3419
|
const shown = `${accessibleName(element) ?? ""} ${element.value ?? ""}`;
|
|
3250
3420
|
return norm(shown).includes(norm(value)) ? true : void 0;
|
|
@@ -3300,6 +3470,75 @@ function attachFiles(input, files) {
|
|
|
3300
3470
|
input.dispatchEvent(new Event("input", { bubbles: true }));
|
|
3301
3471
|
input.dispatchEvent(new Event("change", { bubbles: true }));
|
|
3302
3472
|
}
|
|
3473
|
+
const scrolls = (overflow) => overflow === "auto" || overflow === "scroll" || overflow === "overlay";
|
|
3474
|
+
/**
|
|
3475
|
+
* 滚动落点(FR-10.3):从被指认元素**自身**起沿祖先链上溯,取第一个真正能滚的容器。
|
|
3476
|
+
*
|
|
3477
|
+
* 判据是两个条件的**合取**,第二个不能省:现代布局里 `overflow-y: auto` 的祖先
|
|
3478
|
+
* 常有好几层(卡片、面板、栅格),其中绝大多数内容并没有溢出。只看 overflow 会命中
|
|
3479
|
+
* 最近的那个 `auto`,往它的 `scrollTop` 写值没有任何效果——表现是操作报成功、
|
|
3480
|
+
* 页面没动、也没有新行,即向模型报了一次假成功。
|
|
3481
|
+
*
|
|
3482
|
+
* 判据里不含任何组件库特征(class 名、data 属性、组件实例):这是「通用」二字的判据。
|
|
3483
|
+
*
|
|
3484
|
+
* 根滚动容器单独兜底而不是靠链上命中:`documentElement` 的 `overflow-y` 计算值
|
|
3485
|
+
* 通常是 `visible`(滚动被传播到视口),不会被上面的判据命中,但文档确实可滚。
|
|
3486
|
+
* 顺序必须是先链后兜底——嵌套场景下先命中的必须是内层列表。
|
|
3487
|
+
*/
|
|
3488
|
+
function scrollTargetOf(element) {
|
|
3489
|
+
const doc = element.ownerDocument;
|
|
3490
|
+
const view = doc.defaultView;
|
|
3491
|
+
if (view === null) return void 0;
|
|
3492
|
+
for (let node = element; node !== null; node = node.parentElement) {
|
|
3493
|
+
const style = view.getComputedStyle(node);
|
|
3494
|
+
if (scrolls(style.overflowY) && node.scrollHeight > node.clientHeight) return {
|
|
3495
|
+
container: node,
|
|
3496
|
+
isRoot: false
|
|
3497
|
+
};
|
|
3498
|
+
}
|
|
3499
|
+
const root = doc.scrollingElement ?? doc.documentElement;
|
|
3500
|
+
if (root !== null && root.scrollHeight > root.clientHeight) return {
|
|
3501
|
+
container: root,
|
|
3502
|
+
isRoot: true
|
|
3503
|
+
};
|
|
3504
|
+
}
|
|
3505
|
+
function clampScrollSettleMs(value) {
|
|
3506
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return SCROLL_SETTLE_BOUNDS.default;
|
|
3507
|
+
return Math.min(Math.max(Math.round(value), SCROLL_SETTLE_BOUNDS.min), SCROLL_SETTLE_BOUNDS.max);
|
|
3508
|
+
}
|
|
3509
|
+
/**
|
|
3510
|
+
* 等落点容器的子树安静下来(FR-10.6)。
|
|
3511
|
+
*
|
|
3512
|
+
* 观察器必须在**写 `scrollTop` 之前**挂上:写值到第一次变更之间不能有空档,
|
|
3513
|
+
* 否则渲染快的页面会在挂上观察器之前就完成变更,然后被静默窗口判成「没动静」。
|
|
3514
|
+
*
|
|
3515
|
+
* 只观察落点子树,不观察整个文档:ERP 页面上到处是无关的轮询与徽标刷新,
|
|
3516
|
+
* 观察全文档等于永远等不到静默。
|
|
3517
|
+
*/
|
|
3518
|
+
function watchQuiescence(container) {
|
|
3519
|
+
const Observer = container.ownerDocument.defaultView?.MutationObserver;
|
|
3520
|
+
let lastChange;
|
|
3521
|
+
const observer = Observer === void 0 ? void 0 : new Observer(() => lastChange = Date.now());
|
|
3522
|
+
observer?.observe(container, {
|
|
3523
|
+
childList: true,
|
|
3524
|
+
subtree: true
|
|
3525
|
+
});
|
|
3526
|
+
return { settle: async (budgetMs) => {
|
|
3527
|
+
const started = Date.now();
|
|
3528
|
+
try {
|
|
3529
|
+
for (;;) {
|
|
3530
|
+
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
3531
|
+
const now = Date.now();
|
|
3532
|
+
if (now - started >= budgetMs) return;
|
|
3533
|
+
if (lastChange === void 0) {
|
|
3534
|
+
if (now - started >= SCROLL_SETTLE_FIRST_CHANGE_MS) return;
|
|
3535
|
+
} else if (now - lastChange >= SCROLL_SETTLE_QUIET_MS) return;
|
|
3536
|
+
}
|
|
3537
|
+
} finally {
|
|
3538
|
+
observer?.disconnect();
|
|
3539
|
+
}
|
|
3540
|
+
} };
|
|
3541
|
+
}
|
|
3303
3542
|
/** @experimental */
|
|
3304
3543
|
function createDomPageActionExecutor(options) {
|
|
3305
3544
|
const { reader } = options;
|
|
@@ -3356,6 +3595,40 @@ function createDomPageActionExecutor(options) {
|
|
|
3356
3595
|
documentUrl: view.location.href
|
|
3357
3596
|
};
|
|
3358
3597
|
};
|
|
3598
|
+
/**
|
|
3599
|
+
* 滚动一屏(0.18.0 分册 10)。
|
|
3600
|
+
*
|
|
3601
|
+
* 不走 `done()`:滚动不会导航、也不会打开模态,套那段等待只是白等一个预算。
|
|
3602
|
+
* 稳定化是滚动自己的收尾,见 `watchQuiescence`。
|
|
3603
|
+
*/
|
|
3604
|
+
const scrollRegion = async (element, target, direction) => {
|
|
3605
|
+
const found = scrollTargetOf(element);
|
|
3606
|
+
if (found === void 0) return {
|
|
3607
|
+
ok: false,
|
|
3608
|
+
target,
|
|
3609
|
+
reason: "This area cannot be scrolled: nothing around this element has a scrollable region."
|
|
3610
|
+
};
|
|
3611
|
+
const { container, isRoot } = found;
|
|
3612
|
+
if (!isRoot && !reader.inActionScope(container)) return {
|
|
3613
|
+
ok: false,
|
|
3614
|
+
target,
|
|
3615
|
+
reason: "The scrollable region around this element is outside the actionable scope."
|
|
3616
|
+
};
|
|
3617
|
+
const step = Math.max(container.clientHeight - SCROLL_OVERLAP_PX, Math.round(container.clientHeight / 2), 1);
|
|
3618
|
+
const before = container.scrollTop;
|
|
3619
|
+
const watch = watchQuiescence(container);
|
|
3620
|
+
container.scrollTop = direction === "down" ? before + step : before - step;
|
|
3621
|
+
await watch.settle(clampScrollSettleMs(options.scrollSettleMs?.()));
|
|
3622
|
+
const after = container.scrollTop;
|
|
3623
|
+
return {
|
|
3624
|
+
ok: true,
|
|
3625
|
+
target,
|
|
3626
|
+
scrolled: {
|
|
3627
|
+
atEnd: direction === "down" ? after >= container.scrollHeight - container.clientHeight - 1 : after <= 0,
|
|
3628
|
+
movedBy: Math.abs(after - before)
|
|
3629
|
+
}
|
|
3630
|
+
};
|
|
3631
|
+
};
|
|
3359
3632
|
const execute = async (request) => {
|
|
3360
3633
|
if (request.action === "back") return await goBack();
|
|
3361
3634
|
const element = reader.resolve(request.ref);
|
|
@@ -3370,7 +3643,7 @@ function createDomPageActionExecutor(options) {
|
|
|
3370
3643
|
target,
|
|
3371
3644
|
reason
|
|
3372
3645
|
});
|
|
3373
|
-
if (reader.handleKindOf(request.ref) === "anchor") return fail("That reference points at a container, which cannot be acted on. Use it with perceive_page to read inside it, then act on an element
|
|
3646
|
+
if (reader.handleKindOf(request.ref) === "anchor") return fail("That reference points at a container, which cannot be acted on. Use it with perceive_page to read inside it, then act on an element that carries its own reference. If nothing inside it has one, this part of the page offers no action and retrying here will not help.");
|
|
3374
3647
|
if (reader.modalStateOf(element) === "unelevated") return fail("That dialog is not in the authorized scope because it was opened manually. Ask me to open it, or add it to the host allowlist.");
|
|
3375
3648
|
if (reader.modalStateOf(element) !== "elevated" && !reader.inActionScope(element)) return fail("The element is no longer inside the actionable scope.");
|
|
3376
3649
|
if (hidden(element)) return fail("The element is not visible.");
|
|
@@ -3426,6 +3699,10 @@ function createDomPageActionExecutor(options) {
|
|
|
3426
3699
|
};
|
|
3427
3700
|
}
|
|
3428
3701
|
if (request.action === "set") return await done(setToggle(element, request.value ?? "", target));
|
|
3702
|
+
if (request.action === "scroll") {
|
|
3703
|
+
if (request.value !== "down" && request.value !== "up") return fail("Use \"down\" or \"up\".");
|
|
3704
|
+
return await scrollRegion(element, target, request.value);
|
|
3705
|
+
}
|
|
3429
3706
|
if (request.action === "attach") {
|
|
3430
3707
|
const files = await options.pickFiles?.();
|
|
3431
3708
|
if (files === void 0 || files.length === 0) return {
|
|
@@ -3463,8 +3740,10 @@ function createDomPageActionExecutor(options) {
|
|
|
3463
3740
|
* 它**不是** FR-11.5 那个容量闸门:那一条管的是「同时有几个**标签页**可操作」,
|
|
3464
3741
|
* 触顶硬拒绝,落在 `TabWorksetPolicy`。这里管的是同一个标签页里连续跳页攒下的历史分片,
|
|
3465
3742
|
* 那些本来就该失效,按最久未使用逐出即可,逐出不构成对模型的拒绝。
|
|
3743
|
+
* 软上限必须宽于 `TAB_WORKSET_MAX_MAX`(分册 18),否则工作集里**还活着**的页
|
|
3744
|
+
* 会因为别的页新发分片而被逐出;64 = 天花板 32 × 每页两代历史。
|
|
3466
3745
|
*/
|
|
3467
|
-
const SHARD_SOFT_LIMIT =
|
|
3746
|
+
const SHARD_SOFT_LIMIT = 64;
|
|
3468
3747
|
/** 不给 `shard` 时用的分片键;单分片宿主全程待在这一个分片里 */
|
|
3469
3748
|
const DEFAULT_SHARD = "";
|
|
3470
3749
|
/**
|
|
@@ -3486,7 +3765,7 @@ function explainResolution(resolution) {
|
|
|
3486
3765
|
}
|
|
3487
3766
|
/** @experimental */
|
|
3488
3767
|
function createRemoteTargetRegistry(options = {}) {
|
|
3489
|
-
const maxShards = Math.max(1, Math.trunc(options.maxShards ??
|
|
3768
|
+
const maxShards = Math.max(1, Math.trunc(options.maxShards ?? 64));
|
|
3490
3769
|
let shards = /* @__PURE__ */ new Map();
|
|
3491
3770
|
let refIndex = /* @__PURE__ */ new Map();
|
|
3492
3771
|
let focused = DEFAULT_SHARD;
|
|
@@ -5444,4 +5723,4 @@ function originOf(blockedURI) {
|
|
|
5444
5723
|
}
|
|
5445
5724
|
|
|
5446
5725
|
//#endregion
|
|
5447
|
-
export { BrowserSkillManager, BrowserWorkerScriptExecutor, ChromeBuiltinLlmClient, DEFAULT_FRAME_BUDGET, DEFAULT_MAX_VIEWER_PAYLOAD_BYTES, DOCUMENT_SURFACE_AUDIT_EVENT, DOCX_UNEXTRACTED, HOST_PORT_MATRIX, IframeWorkerLike, OpfsProvider, SANDBOX_PAGE_SCRIPT_SOURCE, SHARD_SOFT_LIMIT, TsTranspiler, VIEWER_SANDBOX_TOKENS, WORKER_BOOTSTRAP_SOURCE, WorkerRuntimeClient, WorkerUiBridge, XLSX_UNEXTRACTED, blockedMessage, bridgeError, captureElementImage, checkDictationAvailability, compressImageToBudget, createBrowserChatbotHost, createDocumentSurfaceHost, createDomPageActionExecutor, createDomPerceptionReader, createEncryptedMemoryStore, createFetchLinkedDocumentReader, createFrameRouter, createIframeWorker, createLlmClient, createPageAgentHandler, createRemotePageActionExecutor, createRemotePerceptionReader, createRemoteTargetRegistry, deleteMemoryEncryptionKey, documentKey, explainResolution, extractDocxText, extractXlsxText, extractZipWeb, generateMemoryEncryptionKey, inspectHostWiring, installWebSkillNavigator, isCapturableElement, isCaptureFailure, isEncryptedMemoryValue, isOpfsAvailable, missingPorts, openDocumentSurface, openMemoryEncryptionKey, parseBridgeRequest, parseMainMessage, parseWorkerEvent, probeChromeBuiltinAvailability, sha256HexWeb, startDictation, startViewerShell, startWorkerRuntimeHost, viewerCspHeader, watchBlockedResources };
|
|
5726
|
+
export { BrowserSkillManager, BrowserWorkerScriptExecutor, ChromeBuiltinLlmClient, DEFAULT_CAMERA_MAX_DIMENSION, DEFAULT_FRAME_BUDGET, DEFAULT_MAX_VIEWER_PAYLOAD_BYTES, DOCUMENT_SURFACE_AUDIT_EVENT, DOCX_UNEXTRACTED, HOST_PORT_MATRIX, IframeWorkerLike, OpfsProvider, SANDBOX_PAGE_SCRIPT_SOURCE, SHARD_SOFT_LIMIT, TsTranspiler, VIEWER_SANDBOX_TOKENS, WORKER_BOOTSTRAP_SOURCE, WorkerRuntimeClient, WorkerUiBridge, XLSX_UNEXTRACTED, blockedMessage, bridgeError, captureElementImage, capturePhoto, checkCameraAvailability, checkDictationAvailability, compressImageToBudget, createBrowserChatbotHost, createDocumentSurfaceHost, createDomPageActionExecutor, createDomPerceptionReader, createEncryptedMemoryStore, createFetchLinkedDocumentReader, createFrameRouter, createIframeWorker, createLlmClient, createPageAgentHandler, createRemotePageActionExecutor, createRemotePerceptionReader, createRemoteTargetRegistry, deleteMemoryEncryptionKey, documentKey, explainResolution, extractDocxText, extractXlsxText, extractZipWeb, generateMemoryEncryptionKey, inspectHostWiring, installWebSkillNavigator, isCapturableElement, isCaptureFailure, isEncryptedMemoryValue, isOpfsAvailable, missingPorts, openCamera, openDocumentSurface, openMemoryEncryptionKey, parseBridgeRequest, parseMainMessage, parseWorkerEvent, probeChromeBuiltinAvailability, sha256HexWeb, startDictation, startViewerShell, startWorkerRuntimeHost, viewerCspHeader, watchBlockedResources };
|
package/dist/governance.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { S as UiBridge, U as FileSystemProvider, X as PageQuery, Y as Page, f as LlmMessage, ft as SkillDocument, gt as SkillManagerPort, l as LlmClient, ut as SkillCatalogEntry } from "./types-
|
|
2
|
-
import { $ as IntegrityVerdict, Wn as WebSkillRuntime, cn as SkillStateGuard, in as SkillOutcomeReporter, rn as SkillIntegrityGuard, zt as RuntimeRun } from "./index-
|
|
3
|
-
import { _ as SkillState, a as AuditLog, b as SkillVersionStore, c as CandidateFile, d as CandidateSkill, f as CandidateSource, g as SKILL_VERSION_PAGE_SIZE, h as CompositeApprovalPolicy, i as AuditEvent, l as CandidatePage, m as CandidateStore, n as ApprovalDecision, o as AuditQueryFilter, p as CandidateStatus, r as ApprovalPolicy, s as CANDIDATE_PAGE_SIZE, t as AlwaysHumanApprovalPolicy, u as CandidateRisk, v as SkillVersion, x as candidateToCatalogEntry, y as SkillVersionPage } from "./skillVersionStore-B24Jjjry-
|
|
1
|
+
import { S as UiBridge, U as FileSystemProvider, X as PageQuery, Y as Page, f as LlmMessage, ft as SkillDocument, gt as SkillManagerPort, l as LlmClient, ut as SkillCatalogEntry } from "./types-Btpdd1y--BcxQ10Fa.js";
|
|
2
|
+
import { $ as IntegrityVerdict, Wn as WebSkillRuntime, cn as SkillStateGuard, in as SkillOutcomeReporter, rn as SkillIntegrityGuard, zt as RuntimeRun } from "./index-BDyXe-a5.js";
|
|
3
|
+
import { _ as SkillState, a as AuditLog, b as SkillVersionStore, c as CandidateFile, d as CandidateSkill, f as CandidateSource, g as SKILL_VERSION_PAGE_SIZE, h as CompositeApprovalPolicy, i as AuditEvent, l as CandidatePage, m as CandidateStore, n as ApprovalDecision, o as AuditQueryFilter, p as CandidateStatus, r as ApprovalPolicy, s as CANDIDATE_PAGE_SIZE, t as AlwaysHumanApprovalPolicy, u as CandidateRisk, v as SkillVersion, x as candidateToCatalogEntry, y as SkillVersionPage } from "./skillVersionStore-B24Jjjry-v2CCU0Xo.js";
|
|
4
4
|
//#region ../governance/dist/index.d.ts
|
|
5
5
|
//#region src/candidate/candidateNormalizer.d.ts
|
|
6
6
|
/** 剥 markdown fence 与 <think> 块、截取首尾 {};非对象 → CANDIDATE_INVALID */
|
package/dist/governance.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as messageOf, t as WebSkillError } from "./errors-BDZNpC13.js";
|
|
2
2
|
import { y as isValidSkillName } from "./skill-CAJMsLod.js";
|
|
3
3
|
import { a as atomicWriteText, t as assertSafePathSegment } from "./pathSecurity-B1owvJAF.js";
|
|
4
|
-
import { d as partsToText, p as textParts } from "./llm-
|
|
4
|
+
import { d as partsToText, p as textParts } from "./llm-eIQNO9tr.js";
|
|
5
5
|
import { n as AUDIT_EVENT_TYPE_LIST, t as AUDIT_EVENT_TYPES } from "./eventTypes-CwciaqCU.js";
|
|
6
6
|
|
|
7
7
|
//#region ../governance/src/candidate/candidateNormalizer.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { At as ValidationReport, B as DiscoveryResult, K as JsonSchema, Nt as WebSkillErrorCode, O as UiSurfaceActionRequest, Ot as UiSpecNode, S as UiBridge, T as UiSpecEvent, U as FileSystemProvider, X as PageQuery, Y as Page, Z as RemoteUrlPolicy, _ as LlmToolSpec, _t as SkillManifest, b as RenderResultRequest, d as LlmContentPart, dt as SkillDiscovery, f as LlmMessage, ft as SkillDocument, g as LlmToolCall, h as LlmTokenUsage, i as FormField, l as LlmClient, lt as SkillCatalog, m as LlmStreamEvent, n as ArtifactStore, o as InteractionPolicy, p as LlmResponse, pt as SkillInstallSource, r as ChartSpec, s as InteractionRequest, t as Artifact, u as LlmCompleteInput, ut as SkillCatalogEntry, v as MemoryStore, w as UiSpecDrafts, y as RenderBlock } from "./types-
|
|
1
|
+
import { At as ValidationReport, B as DiscoveryResult, K as JsonSchema, Nt as WebSkillErrorCode, O as UiSurfaceActionRequest, Ot as UiSpecNode, S as UiBridge, T as UiSpecEvent, U as FileSystemProvider, X as PageQuery, Y as Page, Z as RemoteUrlPolicy, _ as LlmToolSpec, _t as SkillManifest, b as RenderResultRequest, d as LlmContentPart, dt as SkillDiscovery, f as LlmMessage, ft as SkillDocument, g as LlmToolCall, h as LlmTokenUsage, i as FormField, l as LlmClient, lt as SkillCatalog, m as LlmStreamEvent, n as ArtifactStore, o as InteractionPolicy, p as LlmResponse, pt as SkillInstallSource, r as ChartSpec, s as InteractionRequest, t as Artifact, u as LlmCompleteInput, ut as SkillCatalogEntry, v as MemoryStore, w as UiSpecDrafts, y as RenderBlock } from "./types-Btpdd1y--BcxQ10Fa.js";
|
|
2
2
|
//#region ../runtime/dist/index.d.ts
|
|
3
3
|
//#region src/llm/parts.d.ts
|
|
4
4
|
/** 纯文本消息内容的构造快捷方式(引擎内部绝大多数消息仍是纯文本) */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as UiSpecActionCapability, D as UiSpecSnapshot, K as JsonSchema, Ot as UiSpecNode, S as UiBridge, b as RenderResultRequest, c as InteractionResponse, r as ChartSpec, s as InteractionRequest, y as RenderBlock } from "./types-
|
|
2
|
-
import { z as ExternalToolSource } from "./index-
|
|
1
|
+
import { C as UiSpecActionCapability, D as UiSpecSnapshot, K as JsonSchema, Ot as UiSpecNode, S as UiBridge, b as RenderResultRequest, c as InteractionResponse, r as ChartSpec, s as InteractionRequest, y as RenderBlock } from "./types-Btpdd1y--BcxQ10Fa.js";
|
|
2
|
+
import { z as ExternalToolSource } from "./index-BDyXe-a5.js";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { ComponentType, ReactNode } from "react";
|
|
5
5
|
//#region ../ui/dist/index.d.ts
|
|
@@ -668,6 +668,11 @@ interface InteractionSpecLabels {
|
|
|
668
668
|
title?: string;
|
|
669
669
|
submitLabel?: string;
|
|
670
670
|
cancelLabel?: string;
|
|
671
|
+
/**
|
|
672
|
+
* 正文覆写(分册 19 FR-19.1)。runtime 拼的英文原句是无字典层的正确产物,
|
|
673
|
+
* 但持有字典的宿主要能把它换成本地化文案;空串表示不渲染正文(同 `title`)。
|
|
674
|
+
*/
|
|
675
|
+
message?: string;
|
|
671
676
|
}
|
|
672
677
|
/**
|
|
673
678
|
* 五类 `InteractionRequest` → catalog 声明树。
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { I as ChatAttachmentKind, Nt as WebSkillErrorCode, S as UiBridge, Z as RemoteUrlPolicy, a as InteractionOrigin, c as InteractionResponse, s as InteractionRequest } from "./types-
|
|
2
|
-
import { Kn as XlsxTextExtractor, P as DocxTextExtractor, bn as ToolStepReader, j as DataSourceInfo, z as ExternalToolSource } from "./index-
|
|
1
|
+
import { I as ChatAttachmentKind, Nt as WebSkillErrorCode, S as UiBridge, Z as RemoteUrlPolicy, a as InteractionOrigin, c as InteractionResponse, s as InteractionRequest } from "./types-Btpdd1y--BcxQ10Fa.js";
|
|
2
|
+
import { Kn as XlsxTextExtractor, P as DocxTextExtractor, bn as ToolStepReader, j as DataSourceInfo, z as ExternalToolSource } from "./index-BDyXe-a5.js";
|
|
3
3
|
//#region ../agent/dist/index.d.ts
|
|
4
4
|
//#region src/todo/types.d.ts
|
|
5
5
|
/** 待办条目状态:未开始 / 进行中 / 已完成(FR-3.1) */
|
|
@@ -1119,15 +1119,15 @@ type PageActionScopeInput = PageActionScope | {
|
|
|
1119
1119
|
*/
|
|
1120
1120
|
declare function toActionFrameScopes(scope: PageActionScopeInput): readonly ActionFrameScope[];
|
|
1121
1121
|
/**
|
|
1122
|
-
* 本版的操作集(FR-25.1 / 0.16.0 FR-13.6
|
|
1122
|
+
* 本版的操作集(FR-25.1 / 0.16.0 FR-13.6 / 0.18.0 FR-10.1)。拖拽仍不在内(D64);
|
|
1123
1123
|
* 导航只有 `back` 一个,且它**不接受地址**——可达面被浏览器历史封死(SC-1)。
|
|
1124
1124
|
*
|
|
1125
|
-
* `select`/`set`/`attach`
|
|
1125
|
+
* `select`/`set`/`attach`/`scroll` 与既有几个走**同一条** policy 路径,
|
|
1126
1126
|
* 范围白名单、逐次确认、审计三条硬约束因此天然覆盖到它们——
|
|
1127
|
-
* 前提是新动作不绕过 policy
|
|
1127
|
+
* 前提是新动作不绕过 policy 直调执行器(AC-25.4 守这一点)。
|
|
1128
1128
|
* @experimental
|
|
1129
1129
|
*/
|
|
1130
|
-
declare const PAGE_ACTION_KINDS: readonly ["click", "fill", "submit", "select", "set", "attach", "back"];
|
|
1130
|
+
declare const PAGE_ACTION_KINDS: readonly ["click", "fill", "submit", "select", "set", "attach", "scroll", "back"];
|
|
1131
1131
|
type PageActionKind = (typeof PAGE_ACTION_KINDS)[number];
|
|
1132
1132
|
/**
|
|
1133
1133
|
* `back` 的目标占位(0.16.0 分册 13 §4.1)。
|
|
@@ -1145,8 +1145,8 @@ interface PageActionRequest {
|
|
|
1145
1145
|
action: PageActionKind;
|
|
1146
1146
|
/**
|
|
1147
1147
|
* `fill` 填入的文本;`select` 要选中的选项可访问名;
|
|
1148
|
-
* `set` 的目标态(`'true'` | `'false'
|
|
1149
|
-
*
|
|
1148
|
+
* `set` 的目标态(`'true'` | `'false'`);`scroll` 的方向(`'down'` | `'up'`)。
|
|
1149
|
+
* `attach` 不用它——文件**始终由用户在确认卡里选**,Agent 传不进本地路径(FR-25.5)。
|
|
1150
1150
|
*/
|
|
1151
1151
|
value?: string;
|
|
1152
1152
|
}
|
|
@@ -1197,6 +1197,17 @@ interface PageActionOutcome {
|
|
|
1197
1197
|
* 带 `admitted: false` 即开出来了但没接进来(例如工作集触顶)。
|
|
1198
1198
|
*/
|
|
1199
1199
|
openedTab?: OpenedTabSignal;
|
|
1200
|
+
/**
|
|
1201
|
+
* 本次滚动的位移与边界状态(0.18.0 分册 10 · FR-10.7)。
|
|
1202
|
+
* 非 `scroll` 动作**不带**该字段,与 `navigated` 同口径。
|
|
1203
|
+
*
|
|
1204
|
+
* 两个值都在**稳定化之后**回读:虚拟列表加载新行会改变 `scrollHeight`,
|
|
1205
|
+
* 用滚动前的值算 `atEnd` 会提前报到底,模型于是停在半路。
|
|
1206
|
+
*/
|
|
1207
|
+
scrolled?: {
|
|
1208
|
+
atEnd: boolean;
|
|
1209
|
+
movedBy: number;
|
|
1210
|
+
};
|
|
1200
1211
|
/** 失败原因(英文) */
|
|
1201
1212
|
reason?: string;
|
|
1202
1213
|
}
|
|
@@ -1247,6 +1258,16 @@ interface PageActionRecord {
|
|
|
1247
1258
|
noop?: boolean;
|
|
1248
1259
|
/** 非密码类控件填入的值;密码类控件**整个字段不存在** */
|
|
1249
1260
|
value?: string;
|
|
1261
|
+
/**
|
|
1262
|
+
* 本次滚动的方向与实际位移(0.18.0 FR-10.8);非 `scroll` 动作不带。
|
|
1263
|
+
* 位移要进留痕:只记「滚了」而不记「滚了多少」,事后分不出
|
|
1264
|
+
* 「滚到底了」与「根本没滚动」。
|
|
1265
|
+
*/
|
|
1266
|
+
scrolled?: {
|
|
1267
|
+
direction: 'down' | 'up';
|
|
1268
|
+
movedBy: number;
|
|
1269
|
+
atEnd: boolean;
|
|
1270
|
+
};
|
|
1250
1271
|
reason?: string;
|
|
1251
1272
|
}
|
|
1252
1273
|
//#endregion
|
|
@@ -1464,11 +1485,11 @@ declare function createPageActionToolSource(options: PageActionToolSourceOptions
|
|
|
1464
1485
|
declare const PAGE_ACTION_SYSTEM_PROMPT: string;
|
|
1465
1486
|
//#endregion
|
|
1466
1487
|
//#region src/tabs/policy.d.ts
|
|
1467
|
-
/**
|
|
1468
|
-
declare const TAB_WORKSET_DEFAULT_MAX =
|
|
1488
|
+
/** 工作集容量缺省(分册 18);一屏索引视图的行数就是它要盖住的量,撞 `workset-full` 时模型没有任何入口能要更多 */
|
|
1489
|
+
declare const TAB_WORKSET_DEFAULT_MAX = 32;
|
|
1469
1490
|
/** 地板:2 的含义是「起点页 + 至少一个详情页」,低于它工作集这个概念就没有意义 */
|
|
1470
1491
|
declare const TAB_WORKSET_MIN_MAX = 2;
|
|
1471
|
-
/** 天花板:宿主写错一个 0
|
|
1492
|
+
/** 天花板:宿主写错一个 0 不该让一轮任务铺开几百个标签页。与缺省同值,宿主只调得低不调得高 */
|
|
1472
1493
|
declare const TAB_WORKSET_MAX_MAX = 32;
|
|
1473
1494
|
/**
|
|
1474
1495
|
* 夹取工作集容量(FR-11.5 / D-11-3)。
|