@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/{catalogComponents-DV7cPpUm-C77AEEx9.js → catalogComponents-Dr5dFMAb-Dacibl1e.js}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as __require, i as __reExport, n as __esmMin, o as __toCommonJS, r as __exportAll$2, s as __toESM$1, t as __commonJSMin$1 } from "./rolldown-runtime-BOF7iYI8.js";
|
|
2
2
|
import { m as WebSkillError } from "./dist-8oQRa8Xz.js";
|
|
3
|
-
import { M as qualifyFieldName, Q as chartSpecFromProps, et as mountEchart, v as collectFormScopes, y as collectScopedValues } from "./dist-
|
|
3
|
+
import { M as qualifyFieldName, Q as chartSpecFromProps, et as mountEchart, v as collectFormScopes, y as collectScopedValues } from "./dist-DnYG2-eY.js";
|
|
4
4
|
import minpath$1 from "node:path";
|
|
5
5
|
import { fileURLToPath as urlToPath$1 } from "node:url";
|
|
6
6
|
import * as React$10 from "react";
|
|
@@ -3407,11 +3407,49 @@ const getDefaultConfig = () => {
|
|
|
3407
3407
|
const twMerge = /*#__PURE__*/ createTailwindMerge(getDefaultConfig);
|
|
3408
3408
|
|
|
3409
3409
|
//#endregion
|
|
3410
|
-
//#region ../ui-kit/dist/
|
|
3410
|
+
//#region ../ui-kit/dist/useDarkAncestor-D41bzGNA.js
|
|
3411
3411
|
/** shadcn 约定的类名合并:后写的 Tailwind 类覆盖先写的同族类。 */
|
|
3412
3412
|
function cn(...inputs) {
|
|
3413
3413
|
return twMerge(clsx(inputs));
|
|
3414
3414
|
}
|
|
3415
|
+
/**
|
|
3416
|
+
* 声明了主题的祖先:`data-theme` 由 ThemeScope 挂(亮暗都挂),`.dark` 是宿主页面惯用的暗色类名。
|
|
3417
|
+
* 两者一起选,`closest` 才会停在**最近**的那一层,而不是越过亮色实例去命中外层的暗色宿主。
|
|
3418
|
+
*/
|
|
3419
|
+
const THEME_ANCESTOR = "[data-theme], .dark";
|
|
3420
|
+
/**
|
|
3421
|
+
* 判定挂载点**最近的**主题祖先是否处于暗色(0.6.0 FR-20.4)。
|
|
3422
|
+
*
|
|
3423
|
+
* 不用 `document.querySelector('.dark')`:那是全局查询,宿主页面是暗色时,
|
|
3424
|
+
* 嵌在暗色宿主里的亮色 SDK 实例也会被判成暗色(反之亦然)。
|
|
3425
|
+
*
|
|
3426
|
+
* 返回 ref 回调而不是接受 ref 对象:ref 对象的赋值不触发渲染,拿不到「已挂载」这个时机。
|
|
3427
|
+
*/
|
|
3428
|
+
function useDarkAncestor() {
|
|
3429
|
+
const [node, setNode] = useState(null);
|
|
3430
|
+
const [dark, setDark] = useState(false);
|
|
3431
|
+
useEffect(() => {
|
|
3432
|
+
if (!node) return;
|
|
3433
|
+
const update = () => {
|
|
3434
|
+
const scope = node.closest(THEME_ANCESTOR);
|
|
3435
|
+
if (!scope) {
|
|
3436
|
+
setDark(false);
|
|
3437
|
+
return;
|
|
3438
|
+
}
|
|
3439
|
+
const declared = scope.getAttribute("data-theme");
|
|
3440
|
+
setDark(declared === null ? true : declared === "dark");
|
|
3441
|
+
};
|
|
3442
|
+
update();
|
|
3443
|
+
const observer = new MutationObserver(update);
|
|
3444
|
+
observer.observe(document.documentElement, {
|
|
3445
|
+
attributes: true,
|
|
3446
|
+
attributeFilter: ["class", "data-theme"],
|
|
3447
|
+
subtree: true
|
|
3448
|
+
});
|
|
3449
|
+
return () => observer.disconnect();
|
|
3450
|
+
}, [node]);
|
|
3451
|
+
return [dark, setNode];
|
|
3452
|
+
}
|
|
3415
3453
|
|
|
3416
3454
|
//#endregion
|
|
3417
3455
|
//#region ../../node_modules/.pnpm/@radix-ui+react-compose-refs@1.1.5_@types+react@19.2.17_react@19.2.8/node_modules/@radix-ui/react-compose-refs/dist/index.mjs
|
|
@@ -99560,6 +99598,19 @@ const PanelLeft = createLucideIcon("panel-left", [["rect", {
|
|
|
99560
99598
|
* This source code is licensed under the ISC license.
|
|
99561
99599
|
* See the LICENSE file in the root directory of this source tree.
|
|
99562
99600
|
*/
|
|
99601
|
+
const Plus = createLucideIcon("plus", [["path", {
|
|
99602
|
+
d: "M5 12h14",
|
|
99603
|
+
key: "1ays0h"
|
|
99604
|
+
}], ["path", {
|
|
99605
|
+
d: "M12 5v14",
|
|
99606
|
+
key: "s699le"
|
|
99607
|
+
}]]);
|
|
99608
|
+
/**
|
|
99609
|
+
* @license lucide-react v1.27.0 - ISC
|
|
99610
|
+
*
|
|
99611
|
+
* This source code is licensed under the ISC license.
|
|
99612
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
99613
|
+
*/
|
|
99563
99614
|
const Search = createLucideIcon("search", [["path", {
|
|
99564
99615
|
d: "m21 21-4.34-4.34",
|
|
99565
99616
|
key: "14j7rj"
|
|
@@ -99672,6 +99723,26 @@ function Switch({ className = "", label, ...props }) {
|
|
|
99672
99723
|
})]
|
|
99673
99724
|
});
|
|
99674
99725
|
}
|
|
99726
|
+
/**
|
|
99727
|
+
* 一个 SDK 实例的主题作用域(0.6.0 FR-20.4)。
|
|
99728
|
+
*
|
|
99729
|
+
* 解决两件事:
|
|
99730
|
+
* 1. Radix 的 Portal 默认渲染到 `document.body`,会逃出主题子树 —— 这里在作用域**内部**
|
|
99731
|
+
* 提供一个 Portal 容器,浮层因此仍处在带主题类名的祖先链下;
|
|
99732
|
+
* 2. 原生 `<select>` 的下拉由浏览器按 `color-scheme` 绘制,类名管不到 —— 容器上的
|
|
99733
|
+
* `data-webskill-theme` 属性在 base.css 里显式声明了 `color-scheme`。
|
|
99734
|
+
*
|
|
99735
|
+
* 宿主页面自身的类名不被改动:作用域只作用于自己的子树。
|
|
99736
|
+
*/
|
|
99737
|
+
const PortalContainerContext = createContext(void 0);
|
|
99738
|
+
/**
|
|
99739
|
+
* 当前实例的 Portal 容器;不在 `ThemeScope` 内时返回 `undefined`,
|
|
99740
|
+
* 调用方据此回落到 Radix 默认的 `document.body`。
|
|
99741
|
+
* @experimental
|
|
99742
|
+
*/
|
|
99743
|
+
function usePortalContainer() {
|
|
99744
|
+
return useContext(PortalContainerContext);
|
|
99745
|
+
}
|
|
99675
99746
|
const DropdownMenu = Root2;
|
|
99676
99747
|
function DropdownMenuTrigger({ children, className = "", asChild, ...props }) {
|
|
99677
99748
|
const triggerClass = asChild ? className : `inline-flex h-9 items-center justify-center rounded-md border border-border bg-surface px-3 text-sm font-medium text-ink shadow-xs outline-none transition-colors hover:bg-subtle focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/20 ${className}`;
|
|
@@ -99683,12 +99754,15 @@ function DropdownMenuTrigger({ children, className = "", asChild, ...props }) {
|
|
|
99683
99754
|
});
|
|
99684
99755
|
}
|
|
99685
99756
|
function DropdownMenuContent({ children, className = "", sideOffset = 6, ...props }) {
|
|
99686
|
-
return /* @__PURE__ */ jsx(Portal2, {
|
|
99687
|
-
|
|
99688
|
-
|
|
99689
|
-
|
|
99690
|
-
|
|
99691
|
-
|
|
99757
|
+
return /* @__PURE__ */ jsx(Portal2, {
|
|
99758
|
+
container: usePortalContainer(),
|
|
99759
|
+
children: /* @__PURE__ */ jsx(Content2, {
|
|
99760
|
+
sideOffset,
|
|
99761
|
+
className: `z-50 min-w-40 rounded-md border border-border bg-surface p-1 text-sm text-ink shadow-pop outline-none ${className}`,
|
|
99762
|
+
...props,
|
|
99763
|
+
children
|
|
99764
|
+
})
|
|
99765
|
+
});
|
|
99692
99766
|
}
|
|
99693
99767
|
function DropdownMenuCheckboxItem({ children, className = "", ...props }) {
|
|
99694
99768
|
return /* @__PURE__ */ jsxs(CheckboxItem2, {
|
|
@@ -119889,29 +119963,11 @@ function resolveLanguage(raw) {
|
|
|
119889
119963
|
if (raw in languages) return raw;
|
|
119890
119964
|
return languageAliases[raw];
|
|
119891
119965
|
}
|
|
119892
|
-
/** 探测 .dark 祖先(class 策略):监听 documentElement/body 的 class 变化 */
|
|
119893
|
-
function useDarkClass() {
|
|
119894
|
-
const [dark, setDark] = useState(() => typeof document !== "undefined" && document.querySelector(".dark") !== null);
|
|
119895
|
-
useEffect(() => {
|
|
119896
|
-
const update = () => setDark(document.querySelector(".dark") !== null);
|
|
119897
|
-
const observer = new MutationObserver(update);
|
|
119898
|
-
observer.observe(document.documentElement, {
|
|
119899
|
-
attributes: true,
|
|
119900
|
-
attributeFilter: ["class"]
|
|
119901
|
-
});
|
|
119902
|
-
if (document.body) observer.observe(document.body, {
|
|
119903
|
-
attributes: true,
|
|
119904
|
-
attributeFilter: ["class"]
|
|
119905
|
-
});
|
|
119906
|
-
update();
|
|
119907
|
-
return () => observer.disconnect();
|
|
119908
|
-
}, []);
|
|
119909
|
-
return dark;
|
|
119910
|
-
}
|
|
119911
119966
|
function CodeBlock({ node: _node, className, children, ...rest }) {
|
|
119912
|
-
const dark =
|
|
119967
|
+
const [dark, themeRef] = useDarkAncestor();
|
|
119913
119968
|
const language = resolveLanguage(/language-(\w+)/.exec(className ?? "")?.[1]);
|
|
119914
119969
|
if (language) return /* @__PURE__ */ jsxs("div", {
|
|
119970
|
+
ref: themeRef,
|
|
119915
119971
|
className: "my-3 overflow-hidden rounded-card border border-border",
|
|
119916
119972
|
children: [/* @__PURE__ */ jsx("div", {
|
|
119917
119973
|
className: "border-b border-border bg-subtle px-3 py-1.5 font-mono text-xs text-muted",
|
|
@@ -120084,9 +120140,27 @@ const MarkdownText = memo(function MarkdownText({ className }) {
|
|
|
120084
120140
|
defer: true
|
|
120085
120141
|
});
|
|
120086
120142
|
});
|
|
120143
|
+
/**
|
|
120144
|
+
* provider 相关的默认值与切换规则(0.6.0 FR-13.1)。
|
|
120145
|
+
* chatbot 设置面板与 console 的 `connections.models` 共用这一份——
|
|
120146
|
+
* 0.5.x 时两处各自硬编码,改一处漏一处。
|
|
120147
|
+
*/
|
|
120148
|
+
/**
|
|
120149
|
+
* 各 provider 的官方默认端点。取值必须与客户端内部的 fallback 一致(T-03-2 断言):
|
|
120150
|
+
* 客户端的 fallback 保证「用户没填也能跑」,这张表只服务 UI 预填,两者说的是同一件事。
|
|
120151
|
+
* `openai-compatible` 与 `chrome-builtin` 无默认——前者端点任意,后者根本不走 HTTP。
|
|
120152
|
+
* @experimental
|
|
120153
|
+
*/
|
|
120154
|
+
const PROVIDER_DEFAULT_BASE_URL = {
|
|
120155
|
+
"openai-compatible": void 0,
|
|
120156
|
+
anthropic: "https://api.anthropic.com",
|
|
120157
|
+
google: "https://generativelanguage.googleapis.com",
|
|
120158
|
+
"chrome-builtin": void 0
|
|
120159
|
+
};
|
|
120160
|
+
const KNOWN_DEFAULT_BASE_URLS = new Set(Object.values(PROVIDER_DEFAULT_BASE_URL).filter((url) => url !== void 0));
|
|
120087
120161
|
|
|
120088
120162
|
//#endregion
|
|
120089
|
-
//#region ../ui-react/dist/catalogComponents-
|
|
120163
|
+
//#region ../ui-react/dist/catalogComponents-Dr5dFMAb.js
|
|
120090
120164
|
/** echarts 挂载点:surface 图表与 catalog 声明树的 Chart 节点共用,实现在 `@webskill/ui`,与 A2UI 档同一份 */
|
|
120091
120165
|
function EChart({ chart }) {
|
|
120092
120166
|
const containerRef = useRef(null);
|
|
@@ -120302,13 +120376,21 @@ function SurfaceField({ form, props, scope }) {
|
|
|
120302
120376
|
suggestion !== void 0 && isBlank(value) ? /* @__PURE__ */ jsxs("span", {
|
|
120303
120377
|
"data-webskill-suggestion": key,
|
|
120304
120378
|
className: "flex items-center gap-2 text-xs text-muted",
|
|
120305
|
-
children: [
|
|
120306
|
-
|
|
120307
|
-
|
|
120308
|
-
|
|
120309
|
-
|
|
120310
|
-
|
|
120311
|
-
|
|
120379
|
+
children: [
|
|
120380
|
+
/* @__PURE__ */ jsxs("span", { children: ["Suggested: ", String(suggestion.value)] }),
|
|
120381
|
+
suggestion.reason ? /* @__PURE__ */ jsxs("span", { children: [
|
|
120382
|
+
"(",
|
|
120383
|
+
suggestion.reason,
|
|
120384
|
+
")"
|
|
120385
|
+
] }) : null,
|
|
120386
|
+
/* @__PURE__ */ jsx("button", {
|
|
120387
|
+
type: "button",
|
|
120388
|
+
"data-webskill-suggestion-use": key,
|
|
120389
|
+
onClick: () => form.setValue(key, suggestion.value),
|
|
120390
|
+
className: "rounded-md border border-border px-2 py-0.5 text-ink transition-colors hover:bg-accent",
|
|
120391
|
+
children: "Use"
|
|
120392
|
+
})
|
|
120393
|
+
]
|
|
120312
120394
|
}) : null,
|
|
120313
120395
|
props["description"] ? /* @__PURE__ */ jsx("span", {
|
|
120314
120396
|
className: "text-xs text-muted",
|
|
@@ -120328,20 +120410,20 @@ function SurfaceFormButtons({ form, props, scope }) {
|
|
|
120328
120410
|
const submitId = scope ? scope.submitActionId : form.resolveActionId("submit");
|
|
120329
120411
|
const cancelId = scope ? scope.cancelActionId : form.resolveActionId("cancel");
|
|
120330
120412
|
return /* @__PURE__ */ jsxs("div", {
|
|
120331
|
-
className: "flex gap-2",
|
|
120332
|
-
children: [/* @__PURE__ */ jsx(Button, {
|
|
120333
|
-
type: "submit",
|
|
120334
|
-
size: "sm",
|
|
120335
|
-
"data-webskill-surface-action": submitId,
|
|
120336
|
-
children: str(props, "submitLabel", "Submit")
|
|
120337
|
-
}), props["cancelLabel"] ? /* @__PURE__ */ jsx(Button, {
|
|
120413
|
+
className: "flex flex-wrap items-center justify-end gap-2",
|
|
120414
|
+
children: [props["cancelLabel"] ? /* @__PURE__ */ jsx(Button, {
|
|
120338
120415
|
type: "button",
|
|
120339
120416
|
size: "sm",
|
|
120340
120417
|
variant: "secondary",
|
|
120341
120418
|
"data-webskill-surface-action": cancelId,
|
|
120342
120419
|
onClick: () => form.emit(cancelId, scope),
|
|
120343
120420
|
children: str(props, "cancelLabel")
|
|
120344
|
-
}) : null
|
|
120421
|
+
}) : null, /* @__PURE__ */ jsx(Button, {
|
|
120422
|
+
type: "submit",
|
|
120423
|
+
size: "sm",
|
|
120424
|
+
"data-webskill-surface-action": submitId,
|
|
120425
|
+
children: str(props, "submitLabel", "Submit")
|
|
120426
|
+
})]
|
|
120345
120427
|
});
|
|
120346
120428
|
}
|
|
120347
120429
|
/** catalog `Button` 的唯一实现:submit 走带值提交,其余走裸动作 */
|
|
@@ -992,6 +992,7 @@ function shapeInteractionValue(model, values) {
|
|
|
992
992
|
case "confirm": return values["confirmed"] === true;
|
|
993
993
|
case "select": return values["selected"];
|
|
994
994
|
case "authorize": return true;
|
|
995
|
+
case "file-pick": return values["file"];
|
|
995
996
|
case "form": return values;
|
|
996
997
|
}
|
|
997
998
|
}
|
|
@@ -1005,7 +1006,8 @@ function interactionToFormModel(request) {
|
|
|
1005
1006
|
name: "answer",
|
|
1006
1007
|
label: request.message,
|
|
1007
1008
|
control: "text",
|
|
1008
|
-
required: true
|
|
1009
|
+
required: true,
|
|
1010
|
+
...request.suggestion ? { suggestion: request.suggestion } : {}
|
|
1009
1011
|
}],
|
|
1010
1012
|
submitLabel: "Submit",
|
|
1011
1013
|
cancelLabel: "Cancel"
|
|
@@ -1046,7 +1048,8 @@ function interactionToFormModel(request) {
|
|
|
1046
1048
|
label: request.message,
|
|
1047
1049
|
control: "select",
|
|
1048
1050
|
required: true,
|
|
1049
|
-
options: request.options
|
|
1051
|
+
options: request.options,
|
|
1052
|
+
...request.suggestion ? { suggestion: request.suggestion } : {}
|
|
1050
1053
|
}],
|
|
1051
1054
|
submitLabel: "Select",
|
|
1052
1055
|
cancelLabel: "Cancel"
|
|
@@ -1059,6 +1062,21 @@ function interactionToFormModel(request) {
|
|
|
1059
1062
|
submitLabel: "Allow",
|
|
1060
1063
|
cancelLabel: "Deny"
|
|
1061
1064
|
};
|
|
1065
|
+
case "file-pick": return {
|
|
1066
|
+
kind: "file-pick",
|
|
1067
|
+
title: "File requested",
|
|
1068
|
+
message: request.message,
|
|
1069
|
+
controls: [{
|
|
1070
|
+
name: "file",
|
|
1071
|
+
label: request.field ?? "file",
|
|
1072
|
+
control: "file",
|
|
1073
|
+
required: true,
|
|
1074
|
+
...request.accept ? { accept: request.accept } : {},
|
|
1075
|
+
...request.multiple ? { multiple: true } : {}
|
|
1076
|
+
}],
|
|
1077
|
+
submitLabel: "Choose file",
|
|
1078
|
+
cancelLabel: "Decline"
|
|
1079
|
+
};
|
|
1062
1080
|
}
|
|
1063
1081
|
}
|
|
1064
1082
|
const isEmpty = (v) => v === void 0 || v === "";
|
|
@@ -1133,7 +1151,10 @@ function applySuggestion(control, container) {
|
|
|
1133
1151
|
* 全部经 doc.createElementNS 构建(内容来自技能输出,不拼 innerHTML)。
|
|
1134
1152
|
*/
|
|
1135
1153
|
const SVG_NS = "http://www.w3.org/2000/svg";
|
|
1136
|
-
/**
|
|
1154
|
+
/**
|
|
1155
|
+
* 固定 8 色循环调色板。这是**数据编码**(区分序列),不是主题色;
|
|
1156
|
+
* 图表的轴线与文字等“外壳”颜色走 currentColor,跟随宿主容器的主题。
|
|
1157
|
+
*/
|
|
1137
1158
|
const CHART_PALETTE = [
|
|
1138
1159
|
"#4e79a7",
|
|
1139
1160
|
"#f28e2b",
|
|
@@ -1156,7 +1177,8 @@ function text(doc, x, y, content, attrs = {}) {
|
|
|
1156
1177
|
x: String(x),
|
|
1157
1178
|
y: String(y),
|
|
1158
1179
|
"font-size": "9",
|
|
1159
|
-
fill: "
|
|
1180
|
+
fill: "currentColor",
|
|
1181
|
+
"fill-opacity": "0.65",
|
|
1160
1182
|
...attrs
|
|
1161
1183
|
});
|
|
1162
1184
|
node.textContent = content;
|
|
@@ -1181,14 +1203,16 @@ function renderBar(chart, svg, doc) {
|
|
|
1181
1203
|
y1: String(plot.y0),
|
|
1182
1204
|
x2: String(plot.x0),
|
|
1183
1205
|
y2: String(plot.y1),
|
|
1184
|
-
stroke: "
|
|
1206
|
+
stroke: "currentColor",
|
|
1207
|
+
"stroke-opacity": "0.35"
|
|
1185
1208
|
}));
|
|
1186
1209
|
svg.appendChild(el(doc, "line", {
|
|
1187
1210
|
x1: String(plot.x0),
|
|
1188
1211
|
y1: String(plot.y1),
|
|
1189
1212
|
x2: String(plot.x1),
|
|
1190
1213
|
y2: String(plot.y1),
|
|
1191
|
-
stroke: "
|
|
1214
|
+
stroke: "currentColor",
|
|
1215
|
+
"stroke-opacity": "0.35"
|
|
1192
1216
|
}));
|
|
1193
1217
|
if (max <= 0 || chart.labels.length === 0 || chart.series.length === 0) return;
|
|
1194
1218
|
const groupWidth = (plot.x1 - plot.x0) / chart.labels.length;
|
|
@@ -1228,14 +1252,16 @@ function renderLine(chart, svg, doc) {
|
|
|
1228
1252
|
y1: String(plot.y0),
|
|
1229
1253
|
x2: String(plot.x0),
|
|
1230
1254
|
y2: String(plot.y1),
|
|
1231
|
-
stroke: "
|
|
1255
|
+
stroke: "currentColor",
|
|
1256
|
+
"stroke-opacity": "0.35"
|
|
1232
1257
|
}));
|
|
1233
1258
|
svg.appendChild(el(doc, "line", {
|
|
1234
1259
|
x1: String(plot.x0),
|
|
1235
1260
|
y1: String(plot.y1),
|
|
1236
1261
|
x2: String(plot.x1),
|
|
1237
1262
|
y2: String(plot.y1),
|
|
1238
|
-
stroke: "
|
|
1263
|
+
stroke: "currentColor",
|
|
1264
|
+
"stroke-opacity": "0.35"
|
|
1239
1265
|
}));
|
|
1240
1266
|
if (max <= 0 || chart.labels.length === 0 || chart.series.length === 0) return;
|
|
1241
1267
|
const step = chart.labels.length > 1 ? (plot.x1 - plot.x0) / (chart.labels.length - 1) : 0;
|
|
@@ -1315,7 +1341,8 @@ function renderMiniChart(chart, doc) {
|
|
|
1315
1341
|
if (chart.title) svg.appendChild(text(doc, WIDTH / 2, 14, chart.title, {
|
|
1316
1342
|
"text-anchor": "middle",
|
|
1317
1343
|
"font-size": "11",
|
|
1318
|
-
fill: "
|
|
1344
|
+
fill: "currentColor",
|
|
1345
|
+
"fill-opacity": "1"
|
|
1319
1346
|
}));
|
|
1320
1347
|
switch (chart.kind) {
|
|
1321
1348
|
case "bar":
|
|
@@ -1632,7 +1659,7 @@ var WebFormBridge = class {
|
|
|
1632
1659
|
wrapper.appendChild(error);
|
|
1633
1660
|
return wrapper;
|
|
1634
1661
|
}
|
|
1635
|
-
/**
|
|
1662
|
+
/** 建议值以**建议**形态出现(FR-19.4):控件初始值仍为空,点「使用」才写入 */
|
|
1636
1663
|
#renderSuggestion(control, container) {
|
|
1637
1664
|
const doc = this.#doc;
|
|
1638
1665
|
const row = doc.createElement("div");
|
|
@@ -1640,8 +1667,15 @@ var WebFormBridge = class {
|
|
|
1640
1667
|
row.setAttribute("data-webskill-suggestion", control.name);
|
|
1641
1668
|
const preview = doc.createElement("span");
|
|
1642
1669
|
preview.className = "webskill-form__suggestion-value";
|
|
1643
|
-
preview.textContent = `
|
|
1670
|
+
preview.textContent = `Suggested: ${String(control.suggestion?.value)}`;
|
|
1644
1671
|
row.appendChild(preview);
|
|
1672
|
+
const reason = control.suggestion?.reason;
|
|
1673
|
+
if (reason !== void 0 && reason !== "") {
|
|
1674
|
+
const why = doc.createElement("span");
|
|
1675
|
+
why.className = "webskill-form__suggestion-reason";
|
|
1676
|
+
why.textContent = `(${reason})`;
|
|
1677
|
+
row.appendChild(why);
|
|
1678
|
+
}
|
|
1645
1679
|
const use = doc.createElement("button");
|
|
1646
1680
|
use.type = "button";
|
|
1647
1681
|
use.className = "webskill-form__suggestion-use";
|
|
@@ -2016,7 +2050,8 @@ const FIELD_TYPE = {
|
|
|
2016
2050
|
number: "number",
|
|
2017
2051
|
boolean: "toggle",
|
|
2018
2052
|
select: "select",
|
|
2019
|
-
textarea: "textarea"
|
|
2053
|
+
textarea: "textarea",
|
|
2054
|
+
file: "file"
|
|
2020
2055
|
};
|
|
2021
2056
|
function toOptions(options) {
|
|
2022
2057
|
return (options ?? []).map((option) => ({
|
|
@@ -2035,6 +2070,8 @@ function toField(control) {
|
|
|
2035
2070
|
...control.description ? { description: control.description } : {},
|
|
2036
2071
|
...control.defaultValue !== void 0 ? { defaultValue: control.defaultValue } : {},
|
|
2037
2072
|
...control.suggestion ? { suggestion: control.suggestion } : {},
|
|
2073
|
+
...control.accept ? { accept: [...control.accept] } : {},
|
|
2074
|
+
...control.multiple ? { multiple: true } : {},
|
|
2038
2075
|
...control.options ? { options: toOptions(control.options) } : {}
|
|
2039
2076
|
}
|
|
2040
2077
|
};
|
|
@@ -2087,6 +2124,8 @@ const INTENTS = /* @__PURE__ */ new Set([
|
|
|
2087
2124
|
"download",
|
|
2088
2125
|
"refresh"
|
|
2089
2126
|
]);
|
|
2127
|
+
/** 去重靠指纹兜底,但重复调用本身也浪费一轮,所以先在提示词里劝阻(FR-21.5) */
|
|
2128
|
+
const NO_DUPLICATE_RENDER = "If a skill has already rendered a surface for this request, do not call render_ui again with the same content.";
|
|
2090
2129
|
function isIntent(value) {
|
|
2091
2130
|
return typeof value === "string" && INTENTS.has(value);
|
|
2092
2131
|
}
|
|
@@ -2167,7 +2206,7 @@ function createUiCatalogToolSource(options = {}) {
|
|
|
2167
2206
|
});
|
|
2168
2207
|
return {
|
|
2169
2208
|
kind: "ui-catalog",
|
|
2170
|
-
systemPrompt: () => Promise.resolve(catalog.toPrompt()),
|
|
2209
|
+
systemPrompt: () => Promise.resolve(`${catalog.toPrompt()}\n\n${NO_DUPLICATE_RENDER}`),
|
|
2171
2210
|
listToolSpecs: () => Promise.resolve(presets.length > 0 ? [renderTool(), presetTool()] : [renderTool()]),
|
|
2172
2211
|
canHandle: (name) => name === "render_ui" || presets.length > 0 && name === "describe_ui_preset",
|
|
2173
2212
|
call: (name, args) => {
|
|
@@ -2452,7 +2491,7 @@ function fromA2uiSpecAction(event) {
|
|
|
2452
2491
|
*/
|
|
2453
2492
|
async function loadWebSkillLitCatalog() {
|
|
2454
2493
|
try {
|
|
2455
|
-
const { webskillLitCatalog } = await import("./webskillLitCatalog-_mugzRHx-
|
|
2494
|
+
const { webskillLitCatalog } = await import("./webskillLitCatalog-_mugzRHx-B_54vxum.js");
|
|
2456
2495
|
return webskillLitCatalog();
|
|
2457
2496
|
} catch (cause) {
|
|
2458
2497
|
throw new WebSkillError("UI_UNAVAILABLE", "The WebSkill A2UI catalog is unavailable; install @a2ui/lit, @a2ui/web_core and lit to render catalog surfaces with A2UI", cause);
|