@tangle-network/agent-app 0.45.32 → 0.45.34
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/{DesignCanvas-RSWQCXM3.js → DesignCanvas-EODMDQMT.js} +2 -2
- package/dist/{DesignCanvasEditor-XZMGIST7.js → DesignCanvasEditor-DRRZ6ZD3.js} +4 -4
- package/dist/{InvitationsPanel-CJ7DR4F7.js → InvitationsPanel-BATXZHY4.js} +2 -2
- package/dist/{MembersPanel-BB4OD2KB.js → MembersPanel-XNLF3SA4.js} +2 -2
- package/dist/agent-session-controls-1q1XR3j8.d.ts +257 -0
- package/dist/assistant/index.d.ts +1 -1
- package/dist/assistant/index.js +11 -10
- package/dist/assistant/index.js.map +1 -1
- package/dist/chat-react/index.d.ts +1 -1
- package/dist/chat-react/index.js +1 -1
- package/dist/{chunk-YIQHOAHN.js → chunk-3UBAO3N5.js} +3 -3
- package/dist/{chunk-YIQHOAHN.js.map → chunk-3UBAO3N5.js.map} +1 -1
- package/dist/{chunk-PURHUAOR.js → chunk-556RB3XI.js} +5 -5
- package/dist/chunk-556RB3XI.js.map +1 -0
- package/dist/{chunk-HZ4WCA37.js → chunk-5MZXWPFN.js} +9 -9
- package/dist/chunk-5MZXWPFN.js.map +1 -0
- package/dist/{chunk-FNM7JYME.js → chunk-5N434BGF.js} +17 -17
- package/dist/chunk-5N434BGF.js.map +1 -0
- package/dist/{chunk-5SXS3YAB.js → chunk-7MV23XBW.js} +2 -2
- package/dist/chunk-7MV23XBW.js.map +1 -0
- package/dist/{chunk-IFYJDX3J.js → chunk-AIHKKLKY.js} +47 -46
- package/dist/chunk-AIHKKLKY.js.map +1 -0
- package/dist/{chunk-S564OFTL.js → chunk-F4XLTVQ3.js} +3 -3
- package/dist/{chunk-S564OFTL.js.map → chunk-F4XLTVQ3.js.map} +1 -1
- package/dist/{chunk-LSQR6HM6.js → chunk-IN6LNZ7O.js} +35 -34
- package/dist/chunk-IN6LNZ7O.js.map +1 -0
- package/dist/chunk-MIZMWCKW.js +904 -0
- package/dist/chunk-MIZMWCKW.js.map +1 -0
- package/dist/{chunk-QGOU3VXH.js → chunk-UXRJAUJL.js} +3 -3
- package/dist/design-canvas-react/index.js +8 -8
- package/dist/design-canvas-react/index.js.map +1 -1
- package/dist/design-canvas-react/lazy.js +1 -1
- package/dist/studio-react/index.js +27 -27
- package/dist/studio-react/index.js.map +1 -1
- package/dist/teams-react/index.js +2 -2
- package/dist/teams-react/lazy.js +2 -2
- package/dist/theme/index.js +1 -1
- package/dist/theme/tailwind-preset.d.ts +5 -1
- package/dist/theme/tailwind-preset.js +11 -2
- package/dist/theme/tailwind-preset.js.map +1 -1
- package/dist/theme/tokens.css +126 -79
- package/dist/web-react/async/index.js +1 -1
- package/dist/web-react/index.d.ts +31 -91
- package/dist/web-react/index.js +13 -3
- package/dist/work-product-react/index.js +3 -3
- package/dist/work-product-react/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/agent-session-controls-BwImzYKC.d.ts +0 -129
- package/dist/chunk-5SXS3YAB.js.map +0 -1
- package/dist/chunk-FNM7JYME.js.map +0 -1
- package/dist/chunk-HZ4WCA37.js.map +0 -1
- package/dist/chunk-IFYJDX3J.js.map +0 -1
- package/dist/chunk-L7FHRORY.js +0 -763
- package/dist/chunk-L7FHRORY.js.map +0 -1
- package/dist/chunk-LSQR6HM6.js.map +0 -1
- package/dist/chunk-PURHUAOR.js.map +0 -1
- /package/dist/{DesignCanvas-RSWQCXM3.js.map → DesignCanvas-EODMDQMT.js.map} +0 -0
- /package/dist/{DesignCanvasEditor-XZMGIST7.js.map → DesignCanvasEditor-DRRZ6ZD3.js.map} +0 -0
- /package/dist/{InvitationsPanel-CJ7DR4F7.js.map → InvitationsPanel-BATXZHY4.js.map} +0 -0
- /package/dist/{MembersPanel-BB4OD2KB.js.map → MembersPanel-XNLF3SA4.js.map} +0 -0
- /package/dist/{chunk-QGOU3VXH.js.map → chunk-UXRJAUJL.js.map} +0 -0
|
@@ -0,0 +1,904 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ATTACHMENT_ACCEPT,
|
|
3
|
+
ATTACHMENT_MAX_COUNT,
|
|
4
|
+
MAX_ATTACHMENT_TOTAL_BYTES,
|
|
5
|
+
MAX_BINARY_ATTACHMENT_BYTES,
|
|
6
|
+
MAX_TEXT_ATTACHMENT_BYTES,
|
|
7
|
+
attachmentSizeErrorMessage,
|
|
8
|
+
attachmentTotalSizeErrorMessage,
|
|
9
|
+
checkAttachmentType,
|
|
10
|
+
sanitizeAttachmentFileName,
|
|
11
|
+
sniffBinary
|
|
12
|
+
} from "./chunk-CCVG2TL6.js";
|
|
13
|
+
import {
|
|
14
|
+
snapHarnessToModel,
|
|
15
|
+
snapModelToHarness
|
|
16
|
+
} from "./chunk-TH7L265V.js";
|
|
17
|
+
|
|
18
|
+
// src/web-react/provider-logo.tsx
|
|
19
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
20
|
+
var LOGOS = {
|
|
21
|
+
anthropic: { viewBox: "0 0 24 24", fill: "#D97757", paths: ["M17.3041 3.541h-3.6718l6.696 16.918H24Zm-10.6082 0L0 20.459h3.7442l1.3693-3.5527h7.0052l1.3693 3.5528h3.7442L10.5363 3.5409Zm-.3712 10.2232 2.2914-5.9456 2.2914 5.9456Z"] },
|
|
22
|
+
google: { viewBox: "0 0 24 24", fill: "#8E75B2", paths: ["M11.04 19.32Q12 21.51 12 24q0-2.49.93-4.68.96-2.19 2.58-3.81t3.81-2.55Q21.51 12 24 12q-2.49 0-4.68-.93a12.3 12.3 0 0 1-3.81-2.58 12.3 12.3 0 0 1-2.58-3.81Q12 2.49 12 0q0 2.49-.96 4.68-.93 2.19-2.55 3.81a12.3 12.3 0 0 1-3.81 2.58Q2.49 12 0 12q2.49 0 4.68.96 2.19.93 3.81 2.55t2.55 3.81"] },
|
|
23
|
+
deepseek: { viewBox: "0 0 24 24", fill: "#4D6BFE", paths: ["M23.748 4.651c-.254-.124-.364.113-.512.233-.051.04-.094.09-.137.137-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.155-.708-.311-.955-.65-.172-.24-.219-.509-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.094.172.187.129.323-.082.28-.18.553-.266.833-.055.179-.137.218-.328.14a5.5 5.5 0 0 1-1.737-1.179c-.857-.828-1.631-1.743-2.597-2.46a12 12 0 0 0-.689-.47c-.985-.957.13-1.743.387-1.836.27-.098.094-.433-.778-.428-.872.003-1.67.295-2.687.685a3 3 0 0 1-.465.136 9.6 9.6 0 0 0-2.883-.101c-1.885.21-3.39 1.1-4.497 2.622C.082 8.776-.231 10.854.152 13.02c.403 2.284 1.568 4.175 3.36 5.653 1.857 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.132-.284 4.994-1.86.47.234.962.328 1.78.398.629.058 1.235-.031 1.705-.129.735-.155.684-.836.418-.961-2.155-1.004-1.682-.595-2.112-.926 1.095-1.295 2.768-3.598 3.284-6.733.05-.346.115-.834.108-1.114-.004-.171.035-.238.23-.257a4.2 4.2 0 0 0 1.545-.475c1.397-.763 1.96-2.016 2.093-3.517.02-.23-.004-.467-.247-.588M11.58 18.168c-2.088-1.642-3.101-2.183-3.52-2.16-.39.024-.32.472-.234.763.09.288.207.487.371.74.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.168-1.361-.801-2.5-1.86-3.301-3.306-.775-1.393-1.225-2.888-1.299-4.482-.02-.385.094-.522.477-.592a4.7 4.7 0 0 1 1.53-.038c2.131.311 3.946 1.264 5.467 2.774.868.86 1.525 1.887 2.202 2.89.72 1.066 1.494 2.082 2.48 2.915.348.291.626.513.892.677-.802.09-2.14.109-3.055-.615zm1.001-6.44a.306.306 0 0 1 .415-.287.3.3 0 0 1 .113.074.3.3 0 0 1 .086.214c0 .17-.136.307-.308.307a.303.303 0 0 1-.306-.307m3.11 1.596c-.2.081-.4.151-.591.16a1.25 1.25 0 0 1-.798-.254c-.274-.23-.47-.358-.551-.758a1.7 1.7 0 0 1 .015-.588c.07-.327-.007-.537-.238-.727-.188-.156-.426-.199-.689-.199a.6.6 0 0 1-.254-.078.253.253 0 0 1-.114-.358 1 1 0 0 1 .192-.21c.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.392.451.462.576.685.915.176.264.336.536.446.848.066.194-.02.353-.25.45"] },
|
|
24
|
+
mistral: { viewBox: "0 0 24 24", fill: "#FA520F", paths: ["M17.143 3.429v3.428h-3.429v3.429h-3.428V6.857H6.857V3.43H3.43v13.714H0v3.428h10.286v-3.428H6.857v-3.429h3.429v3.429h3.429v-3.429h3.428v3.429h-3.428v3.428H24v-3.428h-3.43V3.429z"] },
|
|
25
|
+
xai: { viewBox: "0 0 24 24", fill: "#000000", paths: ["M14.234 10.162 22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299-.929-1.329L3.076 1.56h3.182l5.965 8.532.929 1.329 7.754 11.09h-3.182z"] },
|
|
26
|
+
nvidia: { viewBox: "0 0 24 24", fill: "#76B900", paths: ["M8.948 8.798v-1.43a6.7 6.7 0 0 1 .424-.018c3.922-.124 6.493 3.374 6.493 3.374s-2.774 3.851-5.75 3.851c-.398 0-.787-.062-1.158-.185v-4.346c1.528.185 1.837.857 2.747 2.385l2.04-1.714s-1.492-1.952-4-1.952a6.016 6.016 0 0 0-.796.035m0-4.735v2.138l.424-.027c5.45-.185 9.01 4.47 9.01 4.47s-4.08 4.964-8.33 4.964c-.37 0-.733-.035-1.095-.097v1.325c.3.035.61.062.91.062 3.957 0 6.82-2.023 9.593-4.408.459.371 2.34 1.263 2.73 1.652-2.633 2.208-8.772 3.984-12.253 3.984-.335 0-.653-.018-.971-.053v1.864H24V4.063zm0 10.326v1.131c-3.657-.654-4.673-4.46-4.673-4.46s1.758-1.944 4.673-2.262v1.237H8.94c-1.528-.186-2.73 1.245-2.73 1.245s.68 2.412 2.739 3.11M2.456 10.9s2.164-3.197 6.5-3.533V6.201C4.153 6.59 0 10.653 0 10.653s2.35 6.802 8.948 7.42v-1.237c-4.84-.6-6.492-5.936-6.492-5.936z"] },
|
|
27
|
+
meta: { viewBox: "0 0 24 24", fill: "#0467DF", paths: ["M6.915 4.03c-1.968 0-3.683 1.28-4.871 3.113C.704 9.208 0 11.883 0 14.449c0 .706.07 1.369.21 1.973a6.624 6.624 0 0 0 .265.86 5.297 5.297 0 0 0 .371.761c.696 1.159 1.818 1.927 3.593 1.927 1.497 0 2.633-.671 3.965-2.444.76-1.012 1.144-1.626 2.663-4.32l.756-1.339.186-.325c.061.1.121.196.183.3l2.152 3.595c.724 1.21 1.665 2.556 2.47 3.314 1.046.987 1.992 1.22 3.06 1.22 1.075 0 1.876-.355 2.455-.843a3.743 3.743 0 0 0 .81-.973c.542-.939.861-2.127.861-3.745 0-2.72-.681-5.357-2.084-7.45-1.282-1.912-2.957-2.93-4.716-2.93-1.047 0-2.088.467-3.053 1.308-.652.57-1.257 1.29-1.82 2.05-.69-.875-1.335-1.547-1.958-2.056-1.182-.966-2.315-1.303-3.454-1.303zm10.16 2.053c1.147 0 2.188.758 2.992 1.999 1.132 1.748 1.647 4.195 1.647 6.4 0 1.548-.368 2.9-1.839 2.9-.58 0-1.027-.23-1.664-1.004-.496-.601-1.343-1.878-2.832-4.358l-.617-1.028a44.908 44.908 0 0 0-1.255-1.98c.07-.109.141-.224.211-.327 1.12-1.667 2.118-2.602 3.358-2.602zm-10.201.553c1.265 0 2.058.791 2.675 1.446.307.327.737.871 1.234 1.579l-1.02 1.566c-.757 1.163-1.882 3.017-2.837 4.338-1.191 1.649-1.81 1.817-2.486 1.817-.524 0-1.038-.237-1.383-.794-.263-.426-.464-1.13-.464-2.046 0-2.221.63-4.535 1.66-6.088.454-.687.964-1.226 1.533-1.533a2.264 2.264 0 0 1 1.088-.285z"] },
|
|
28
|
+
moonshotai: { viewBox: "0 0 24 24", fill: "#16191E", paths: ["m1.053 16.91 9.538 2.55a21 20.981 0 0 0 .06 2.031l5.956 1.592a12 11.99 0 0 1-15.554-6.172m-1.02-5.79 11.352 3.035a21 20.981 0 0 0-.469 2.01l10.817 2.89a12 11.99 0 0 1-1.845 2.004L.658 15.918a12 11.99 0 0 1-.625-4.796m1.593-5.146L13.573 9.17a21 20.981 0 0 0-1.01 1.874l11.297 3.02a21 20.981 0 0 1-.67 2.362l-11.55-3.087L.125 10.26a12 11.99 0 0 1 1.499-4.285ZM6.067 1.58l11.285 3.016a21 20.981 0 0 0-1.688 1.719l7.824 2.091a21 20.981 0 0 1 .513 2.664L2.107 5.218a12 11.99 0 0 1 3.96-3.638M21.68 4.866 7.222 1.003A12 11.99 0 0 1 21.68 4.866"] },
|
|
29
|
+
openai: { viewBox: "0 0 256 260", fill: "#10A37F", paths: ["M239.184 106.203a64.72 64.72 0 0 0-5.576-53.103C219.452 28.459 191 15.784 163.213 21.74A65.586 65.586 0 0 0 52.096 45.22a64.72 64.72 0 0 0-43.23 31.36c-14.31 24.602-11.061 55.634 8.033 76.74a64.67 64.67 0 0 0 5.525 53.102c14.174 24.65 42.644 37.324 70.446 31.36a64.72 64.72 0 0 0 48.754 21.744c28.481.025 53.714-18.361 62.414-45.481a64.77 64.77 0 0 0 43.229-31.36c14.137-24.558 10.875-55.423-8.083-76.483m-97.56 136.338a48.4 48.4 0 0 1-31.105-11.255l1.535-.87l51.67-29.825a8.6 8.6 0 0 0 4.247-7.367v-72.85l21.845 12.636c.218.111.37.32.409.563v60.367c-.056 26.818-21.783 48.545-48.601 48.601M37.158 197.93a48.35 48.35 0 0 1-5.781-32.589l1.534.921l51.722 29.826a8.34 8.34 0 0 0 8.441 0l63.181-36.425v25.221a.87.87 0 0 1-.358.665l-52.335 30.184c-23.257 13.398-52.97 5.431-66.404-17.803M23.549 85.38a48.5 48.5 0 0 1 25.58-21.333v61.39a8.29 8.29 0 0 0 4.195 7.316l62.874 36.272l-21.845 12.636a.82.82 0 0 1-.767 0L41.353 151.53c-23.211-13.454-31.171-43.144-17.804-66.405zm179.466 41.695l-63.08-36.63L161.73 77.86a.82.82 0 0 1 .768 0l52.233 30.184a48.6 48.6 0 0 1-7.316 87.635v-61.391a8.54 8.54 0 0 0-4.4-7.213m21.742-32.69l-1.535-.922l-51.619-30.081a8.39 8.39 0 0 0-8.492 0L99.98 99.808V74.587a.72.72 0 0 1 .307-.665l52.233-30.133a48.652 48.652 0 0 1 72.236 50.391zM88.061 139.097l-21.845-12.585a.87.87 0 0 1-.41-.614V65.685a48.652 48.652 0 0 1 79.757-37.346l-1.535.87l-51.67 29.825a8.6 8.6 0 0 0-4.246 7.367zm11.868-25.58L128.067 97.3l28.188 16.218v32.434l-28.086 16.218l-28.188-16.218z"] }
|
|
30
|
+
};
|
|
31
|
+
var ALIASES = {
|
|
32
|
+
moonshot: "moonshotai",
|
|
33
|
+
deepseek_ai: "deepseek",
|
|
34
|
+
"x-ai": "xai",
|
|
35
|
+
"meta-llama": "meta"
|
|
36
|
+
};
|
|
37
|
+
var MONOGRAM = {
|
|
38
|
+
cohere: { bg: "#fae8ff", fg: "#c026d3" },
|
|
39
|
+
groq: { bg: "#fce7f3", fg: "#db2777" },
|
|
40
|
+
cerebras: { bg: "#ccfbf1", fg: "#0d9488" },
|
|
41
|
+
zai: { bg: "#ede9fe", fg: "#7c3aed" },
|
|
42
|
+
"z-ai": { bg: "#ede9fe", fg: "#7c3aed" },
|
|
43
|
+
tuner: { bg: "#dbeafe", fg: "#2563eb" }
|
|
44
|
+
};
|
|
45
|
+
function ProviderLogo({ provider, size = 16 }) {
|
|
46
|
+
const key = ALIASES[provider ?? ""] ?? provider ?? "";
|
|
47
|
+
const logo = LOGOS[key];
|
|
48
|
+
if (logo) {
|
|
49
|
+
return /* @__PURE__ */ jsx("svg", { width: size, height: size, viewBox: logo.viewBox, role: "img", "aria-label": key, children: logo.paths.map((d, i) => /* @__PURE__ */ jsx("path", { d, fill: logo.fill }, i)) });
|
|
50
|
+
}
|
|
51
|
+
const mono = MONOGRAM[key] ?? { bg: "#f3f4f6", fg: "#6b7280" };
|
|
52
|
+
return /* @__PURE__ */ jsxs("svg", { width: size, height: size, viewBox: "0 0 16 16", role: "img", "aria-label": key || "model", children: [
|
|
53
|
+
/* @__PURE__ */ jsx("rect", { width: "16", height: "16", rx: "4", fill: mono.bg }),
|
|
54
|
+
/* @__PURE__ */ jsx("text", { x: "8", y: "11.6", textAnchor: "middle", fill: mono.fg, fontSize: "9", fontWeight: "700", fontFamily: "system-ui, sans-serif", children: (key || "?").charAt(0).toUpperCase() })
|
|
55
|
+
] });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// src/web-react/controls.tsx
|
|
59
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
60
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
61
|
+
function ChevronDown({ className }) {
|
|
62
|
+
return /* @__PURE__ */ jsx2("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx2("path", { d: "m6 9 6 6 6-6" }) });
|
|
63
|
+
}
|
|
64
|
+
function SearchGlyph({ className }) {
|
|
65
|
+
return /* @__PURE__ */ jsxs2("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
66
|
+
/* @__PURE__ */ jsx2("circle", { cx: "11", cy: "11", r: "8" }),
|
|
67
|
+
/* @__PURE__ */ jsx2("path", { d: "m21 21-4.3-4.3" })
|
|
68
|
+
] });
|
|
69
|
+
}
|
|
70
|
+
function SparkleGlyph({ className }) {
|
|
71
|
+
return /* @__PURE__ */ jsx2("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx2("path", { d: "M12 3v3m0 12v3M3 12h3m12 0h3M5.6 5.6l2.1 2.1m8.6 8.6 2.1 2.1m0-12.8-2.1 2.1M7.7 16.3l-2.1 2.1" }) });
|
|
72
|
+
}
|
|
73
|
+
function BrainGlyph({ className }) {
|
|
74
|
+
return /* @__PURE__ */ jsxs2("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
75
|
+
/* @__PURE__ */ jsx2("path", { d: "M12 18V5" }),
|
|
76
|
+
/* @__PURE__ */ jsx2("path", { d: "M15 13a4.17 4.17 0 0 1-3-4 4.17 4.17 0 0 1-3 4" }),
|
|
77
|
+
/* @__PURE__ */ jsx2("path", { d: "M17.598 6.5A3 3 0 1 0 12 5a3 3 0 1 0-5.598 1.5" }),
|
|
78
|
+
/* @__PURE__ */ jsx2("path", { d: "M17.997 5.125a4 4 0 0 1 2.526 5.77" }),
|
|
79
|
+
/* @__PURE__ */ jsx2("path", { d: "M18 18a4 4 0 0 0 2-7.464" }),
|
|
80
|
+
/* @__PURE__ */ jsx2("path", { d: "M19.967 17.483A4 4 0 1 1 12 18a4 4 0 1 1-7.967-.517" }),
|
|
81
|
+
/* @__PURE__ */ jsx2("path", { d: "M6 18a4 4 0 0 1-2-7.464" }),
|
|
82
|
+
/* @__PURE__ */ jsx2("path", { d: "M6.003 5.125a4 4 0 0 0-2.526 5.77" })
|
|
83
|
+
] });
|
|
84
|
+
}
|
|
85
|
+
function CheckGlyph({ className }) {
|
|
86
|
+
return /* @__PURE__ */ jsx2("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx2("path", { d: "M20 6 9 17l-5-5" }) });
|
|
87
|
+
}
|
|
88
|
+
function usePopover(open, setOpen) {
|
|
89
|
+
const containerRef = useRef(null);
|
|
90
|
+
const triggerRef = useRef(null);
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
if (!open) return;
|
|
93
|
+
function onMouseDown(e) {
|
|
94
|
+
if (containerRef.current && !containerRef.current.contains(e.target)) setOpen(false);
|
|
95
|
+
}
|
|
96
|
+
function onKeyDown(e) {
|
|
97
|
+
if (e.key === "Escape") {
|
|
98
|
+
setOpen(false);
|
|
99
|
+
triggerRef.current?.focus();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
document.addEventListener("mousedown", onMouseDown);
|
|
103
|
+
document.addEventListener("keydown", onKeyDown);
|
|
104
|
+
return () => {
|
|
105
|
+
document.removeEventListener("mousedown", onMouseDown);
|
|
106
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
107
|
+
};
|
|
108
|
+
}, [open, setOpen]);
|
|
109
|
+
return {
|
|
110
|
+
containerRef,
|
|
111
|
+
triggerRef,
|
|
112
|
+
triggerProps: {
|
|
113
|
+
ref: triggerRef,
|
|
114
|
+
"aria-haspopup": true,
|
|
115
|
+
"aria-expanded": open
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
var POPOVER_OPTION_FOCUS = "focus-visible:[outline-offset:-2px]";
|
|
120
|
+
var OVERLAY_SHADOW = "shadow-[0_1px_2px_hsl(var(--foreground)/0.05),0_12px_28px_hsl(var(--foreground)/0.07)] dark:shadow-[0_1px_2px_hsl(var(--foreground)/0.14),0_12px_28px_hsl(var(--foreground)/0.22)]";
|
|
121
|
+
function usePending() {
|
|
122
|
+
const [pending, setPending] = useState(false);
|
|
123
|
+
const inFlight = useRef(false);
|
|
124
|
+
const mounted = useRef(true);
|
|
125
|
+
useEffect(() => {
|
|
126
|
+
mounted.current = true;
|
|
127
|
+
return () => {
|
|
128
|
+
mounted.current = false;
|
|
129
|
+
};
|
|
130
|
+
}, []);
|
|
131
|
+
const run = (action) => {
|
|
132
|
+
if (inFlight.current) return;
|
|
133
|
+
let result;
|
|
134
|
+
try {
|
|
135
|
+
result = action();
|
|
136
|
+
} catch {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (!(result instanceof Promise)) return;
|
|
140
|
+
inFlight.current = true;
|
|
141
|
+
setPending(true);
|
|
142
|
+
void result.finally(() => {
|
|
143
|
+
inFlight.current = false;
|
|
144
|
+
if (mounted.current) setPending(false);
|
|
145
|
+
});
|
|
146
|
+
};
|
|
147
|
+
return { pending, run };
|
|
148
|
+
}
|
|
149
|
+
function formatPrice(p) {
|
|
150
|
+
if (!p) return void 0;
|
|
151
|
+
const n = Number(p);
|
|
152
|
+
if (isNaN(n) || n === 0) return void 0;
|
|
153
|
+
const perM = n * 1e6;
|
|
154
|
+
return perM >= 1 ? `$${perM.toFixed(0)}/M` : `$${perM.toFixed(2)}/M`;
|
|
155
|
+
}
|
|
156
|
+
function formatContext(len) {
|
|
157
|
+
if (!len) return void 0;
|
|
158
|
+
if (len >= 1e6) return `${(len / 1e6).toFixed(1)}M ctx`;
|
|
159
|
+
if (len >= 1e3) return `${Math.round(len / 1e3)}K ctx`;
|
|
160
|
+
return `${len} ctx`;
|
|
161
|
+
}
|
|
162
|
+
function SectionHeader({ children }) {
|
|
163
|
+
return /* @__PURE__ */ jsx2("div", { className: "px-3 pb-1 pt-3 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children });
|
|
164
|
+
}
|
|
165
|
+
function ModelRow({
|
|
166
|
+
model,
|
|
167
|
+
selected,
|
|
168
|
+
onSelect,
|
|
169
|
+
renderProviderBadge
|
|
170
|
+
}) {
|
|
171
|
+
const price = formatPrice(model.pricing?.prompt);
|
|
172
|
+
const ctx = formatContext(model.contextLength);
|
|
173
|
+
return /* @__PURE__ */ jsxs2(
|
|
174
|
+
"button",
|
|
175
|
+
{
|
|
176
|
+
type: "button",
|
|
177
|
+
onClick: onSelect,
|
|
178
|
+
className: `flex w-full items-center gap-2.5 rounded-md px-3 py-2.5 text-left text-sm transition ${POPOVER_OPTION_FOCUS} ${selected ? "bg-primary/10 font-medium" : "hover:bg-accent"}`,
|
|
179
|
+
children: [
|
|
180
|
+
renderProviderBadge ? renderProviderBadge(model.provider) : /* @__PURE__ */ jsx2(ProviderLogo, { provider: model.provider, size: 16 }),
|
|
181
|
+
/* @__PURE__ */ jsx2("span", { className: "truncate", children: model.name }),
|
|
182
|
+
!model.supportsTools && /* @__PURE__ */ jsx2("span", { className: "shrink-0 rounded bg-secondary px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground", children: "no tools" }),
|
|
183
|
+
/* @__PURE__ */ jsxs2("span", { className: "ml-auto flex shrink-0 items-center gap-2 text-xs text-muted-foreground", children: [
|
|
184
|
+
ctx && /* @__PURE__ */ jsx2("span", { children: ctx }),
|
|
185
|
+
price && /* @__PURE__ */ jsx2("span", { children: price })
|
|
186
|
+
] })
|
|
187
|
+
]
|
|
188
|
+
}
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
function ModelPicker({ value, onChange, models, loading, renderProviderBadge, recommendedLabel = "Recommended", priorityGroup }) {
|
|
192
|
+
const [open, setOpen] = useState(false);
|
|
193
|
+
const [query, setQuery] = useState("");
|
|
194
|
+
const { containerRef, triggerProps } = usePopover(open, setOpen);
|
|
195
|
+
const inputRef = useRef(null);
|
|
196
|
+
const popoverRef = useRef(null);
|
|
197
|
+
useEffect(() => {
|
|
198
|
+
if (open) inputRef.current?.focus();
|
|
199
|
+
}, [open]);
|
|
200
|
+
useEffect(() => {
|
|
201
|
+
if (!open) return;
|
|
202
|
+
const el = popoverRef.current;
|
|
203
|
+
if (!el) return;
|
|
204
|
+
const overflowRight = el.getBoundingClientRect().right - (window.innerWidth - 16);
|
|
205
|
+
el.style.transform = overflowRight > 0 ? `translateX(-${Math.ceil(overflowRight)}px)` : "";
|
|
206
|
+
}, [open]);
|
|
207
|
+
const selected = models.find((m) => m.id === value);
|
|
208
|
+
const filtered = useMemo(() => {
|
|
209
|
+
const q = query.trim().toLowerCase();
|
|
210
|
+
if (!q) return null;
|
|
211
|
+
return models.filter(
|
|
212
|
+
(m) => m.id.toLowerCase().includes(q) || m.name.toLowerCase().includes(q) || (m.description?.toLowerCase() ?? "").includes(q) || m.provider.toLowerCase().includes(q)
|
|
213
|
+
);
|
|
214
|
+
}, [models, query]);
|
|
215
|
+
const sections = useMemo(() => {
|
|
216
|
+
const isPriority = priorityGroup ? (m) => priorityGroup.match(m) : () => false;
|
|
217
|
+
const priority = priorityGroup ? models.filter(isPriority) : [];
|
|
218
|
+
const recommended = models.filter((m) => m.featured && !isPriority(m));
|
|
219
|
+
const byProvider = [];
|
|
220
|
+
for (const m of models) {
|
|
221
|
+
if (m.featured || isPriority(m)) continue;
|
|
222
|
+
const last = byProvider[byProvider.length - 1];
|
|
223
|
+
if (last && last.provider === m.provider) last.items.push(m);
|
|
224
|
+
else byProvider.push({ provider: m.provider, items: [m] });
|
|
225
|
+
}
|
|
226
|
+
return { priority, recommended, byProvider };
|
|
227
|
+
}, [models, priorityGroup]);
|
|
228
|
+
const select = (id) => {
|
|
229
|
+
onChange(id);
|
|
230
|
+
setOpen(false);
|
|
231
|
+
setQuery("");
|
|
232
|
+
};
|
|
233
|
+
return /* @__PURE__ */ jsxs2("div", { ref: containerRef, className: "relative inline-flex", children: [
|
|
234
|
+
/* @__PURE__ */ jsxs2(
|
|
235
|
+
"button",
|
|
236
|
+
{
|
|
237
|
+
type: "button",
|
|
238
|
+
...triggerProps,
|
|
239
|
+
onClick: () => setOpen(!open),
|
|
240
|
+
className: "inline-flex items-center gap-1.5 rounded-full border border-border bg-card px-3 py-1.5 text-sm font-medium text-foreground transition hover:bg-accent",
|
|
241
|
+
children: [
|
|
242
|
+
selected ? renderProviderBadge ? renderProviderBadge(selected.provider) : /* @__PURE__ */ jsx2(ProviderLogo, { provider: selected.provider, size: 16 }) : /* @__PURE__ */ jsx2(SparkleGlyph, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
243
|
+
/* @__PURE__ */ jsx2("span", { className: "max-w-[160px] truncate", children: selected?.name ?? value }),
|
|
244
|
+
/* @__PURE__ */ jsx2(ChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" })
|
|
245
|
+
]
|
|
246
|
+
}
|
|
247
|
+
),
|
|
248
|
+
open && /* @__PURE__ */ jsxs2("div", { ref: popoverRef, className: `absolute bottom-full left-0 z-50 mb-2 w-[420px] max-w-[calc(100vw-2rem)] overflow-hidden rounded-xl border border-border bg-popover ${OVERLAY_SHADOW}`, children: [
|
|
249
|
+
/* @__PURE__ */ jsx2("div", { className: "border-b border-border px-3 py-2", children: /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 rounded-lg border border-border bg-background px-3 py-2", children: [
|
|
250
|
+
/* @__PURE__ */ jsx2(SearchGlyph, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
251
|
+
/* @__PURE__ */ jsx2(
|
|
252
|
+
"input",
|
|
253
|
+
{
|
|
254
|
+
ref: inputRef,
|
|
255
|
+
type: "text",
|
|
256
|
+
value: query,
|
|
257
|
+
onChange: (e) => setQuery(e.target.value),
|
|
258
|
+
placeholder: "Search models...",
|
|
259
|
+
className: "flex-1 bg-transparent text-sm placeholder:text-muted-foreground"
|
|
260
|
+
}
|
|
261
|
+
)
|
|
262
|
+
] }) }),
|
|
263
|
+
/* @__PURE__ */ jsxs2("div", { className: "max-h-[400px] overflow-y-auto p-1 pb-2", children: [
|
|
264
|
+
loading && /* @__PURE__ */ jsx2("div", { className: "px-3 py-4 text-center text-sm text-muted-foreground", children: "Loading models..." }),
|
|
265
|
+
!loading && filtered && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
266
|
+
filtered.length === 0 && /* @__PURE__ */ jsx2("div", { className: "px-3 py-4 text-center text-sm text-muted-foreground", children: "No models match your search" }),
|
|
267
|
+
filtered.map((m) => /* @__PURE__ */ jsx2(ModelRow, { model: m, selected: m.id === value, onSelect: () => select(m.id), renderProviderBadge }, m.id))
|
|
268
|
+
] }),
|
|
269
|
+
!loading && !filtered && models.length === 0 && /* @__PURE__ */ jsx2("div", { className: "px-3 py-4 text-center text-sm text-muted-foreground", children: "No models available" }),
|
|
270
|
+
!loading && !filtered && models.length > 0 && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
271
|
+
priorityGroup && sections.priority.length > 0 && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
272
|
+
/* @__PURE__ */ jsx2(SectionHeader, { children: priorityGroup.label }),
|
|
273
|
+
sections.priority.map((m) => /* @__PURE__ */ jsx2(ModelRow, { model: m, selected: m.id === value, onSelect: () => select(m.id), renderProviderBadge }, m.id))
|
|
274
|
+
] }),
|
|
275
|
+
sections.recommended.length > 0 && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
276
|
+
/* @__PURE__ */ jsx2(SectionHeader, { children: recommendedLabel }),
|
|
277
|
+
sections.recommended.map((m) => /* @__PURE__ */ jsx2(ModelRow, { model: m, selected: m.id === value, onSelect: () => select(m.id), renderProviderBadge }, m.id))
|
|
278
|
+
] }),
|
|
279
|
+
sections.byProvider.map((g) => /* @__PURE__ */ jsxs2("div", { children: [
|
|
280
|
+
/* @__PURE__ */ jsx2(SectionHeader, { children: g.provider }),
|
|
281
|
+
g.items.map((m) => /* @__PURE__ */ jsx2(ModelRow, { model: m, selected: m.id === value, onSelect: () => select(m.id), renderProviderBadge }, m.id))
|
|
282
|
+
] }, g.provider))
|
|
283
|
+
] })
|
|
284
|
+
] })
|
|
285
|
+
] })
|
|
286
|
+
] });
|
|
287
|
+
}
|
|
288
|
+
var DEFAULT_EFFORT_LEVELS = [
|
|
289
|
+
{ id: "off", label: "Off" },
|
|
290
|
+
{ id: "low", label: "Quick" },
|
|
291
|
+
{ id: "medium", label: "Standard" },
|
|
292
|
+
{ id: "high", label: "Extended" }
|
|
293
|
+
];
|
|
294
|
+
var EFFORT_METER_SEGMENTS = 4;
|
|
295
|
+
var EFFORT_METER_FILL_OPACITY = [0.25, 0.5, 0.75, 1];
|
|
296
|
+
var EFFORT_METER_GHOST_OPACITY = 0.15;
|
|
297
|
+
var OFF_LEVEL_IDS = /* @__PURE__ */ new Set(["off", "none"]);
|
|
298
|
+
function effortMeterFill(levelId, levels = DEFAULT_EFFORT_LEVELS) {
|
|
299
|
+
if (OFF_LEVEL_IDS.has(levelId)) return 0;
|
|
300
|
+
const active = levels.filter((l) => !OFF_LEVEL_IDS.has(l.id));
|
|
301
|
+
const index = active.findIndex((l) => l.id === levelId);
|
|
302
|
+
if (index < 0 || active.length === 0) return 0;
|
|
303
|
+
return Math.max(1, Math.floor((index + 1) * EFFORT_METER_SEGMENTS / active.length));
|
|
304
|
+
}
|
|
305
|
+
function EffortMeter({ fill, className }) {
|
|
306
|
+
return /* @__PURE__ */ jsx2("span", { "aria-hidden": true, className: `inline-flex items-center gap-[2px] ${className ?? ""}`, children: Array.from({ length: EFFORT_METER_SEGMENTS }, (_, i) => /* @__PURE__ */ jsx2(
|
|
307
|
+
"span",
|
|
308
|
+
{
|
|
309
|
+
className: "h-3 w-[3px] rounded-full bg-current",
|
|
310
|
+
style: { opacity: i < fill ? EFFORT_METER_FILL_OPACITY[i] : EFFORT_METER_GHOST_OPACITY }
|
|
311
|
+
},
|
|
312
|
+
i
|
|
313
|
+
)) });
|
|
314
|
+
}
|
|
315
|
+
function EffortPicker({ value, onChange, levels = DEFAULT_EFFORT_LEVELS, label = "Thinking" }) {
|
|
316
|
+
const [open, setOpen] = useState(false);
|
|
317
|
+
const { containerRef, triggerProps } = usePopover(open, setOpen);
|
|
318
|
+
const selected = levels.find((l) => l.id === value) ?? levels[2] ?? levels[0];
|
|
319
|
+
return /* @__PURE__ */ jsxs2("div", { ref: containerRef, className: "relative inline-flex", children: [
|
|
320
|
+
/* @__PURE__ */ jsxs2(
|
|
321
|
+
"button",
|
|
322
|
+
{
|
|
323
|
+
type: "button",
|
|
324
|
+
...triggerProps,
|
|
325
|
+
onClick: () => setOpen(!open),
|
|
326
|
+
title: label ? `${label} \u2014 how hard the agent reasons before answering` : "Reasoning effort",
|
|
327
|
+
className: "inline-flex min-h-[36px] items-center gap-1.5 rounded-full border border-border bg-card px-3 py-1.5 text-sm font-medium text-foreground transition hover:bg-accent",
|
|
328
|
+
children: [
|
|
329
|
+
/* @__PURE__ */ jsx2(BrainGlyph, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
330
|
+
/* @__PURE__ */ jsxs2("span", { children: [
|
|
331
|
+
label ? /* @__PURE__ */ jsxs2("span", { className: "text-muted-foreground", children: [
|
|
332
|
+
label,
|
|
333
|
+
": "
|
|
334
|
+
] }) : null,
|
|
335
|
+
selected?.label
|
|
336
|
+
] }),
|
|
337
|
+
selected && /* @__PURE__ */ jsx2(EffortMeter, { fill: effortMeterFill(selected.id, levels), className: "text-foreground" }),
|
|
338
|
+
/* @__PURE__ */ jsx2(ChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" })
|
|
339
|
+
]
|
|
340
|
+
}
|
|
341
|
+
),
|
|
342
|
+
open && /* @__PURE__ */ jsx2("div", { role: "menu", className: `absolute bottom-full left-0 z-50 mb-2 w-44 overflow-hidden rounded-xl border border-border bg-popover p-1 ${OVERLAY_SHADOW}`, children: levels.map((l) => /* @__PURE__ */ jsxs2(
|
|
343
|
+
"button",
|
|
344
|
+
{
|
|
345
|
+
type: "button",
|
|
346
|
+
role: "menuitemradio",
|
|
347
|
+
"aria-checked": l.id === value,
|
|
348
|
+
onClick: () => {
|
|
349
|
+
onChange(l.id);
|
|
350
|
+
setOpen(false);
|
|
351
|
+
},
|
|
352
|
+
className: `flex min-h-[40px] w-full items-center gap-2 rounded-md px-3 py-2 text-left text-sm transition ${POPOVER_OPTION_FOCUS} ${l.id === value ? "bg-primary/10 font-medium" : "hover:bg-accent"}`,
|
|
353
|
+
children: [
|
|
354
|
+
/* @__PURE__ */ jsx2(BrainGlyph, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
355
|
+
/* @__PURE__ */ jsx2("span", { className: "truncate", children: l.label }),
|
|
356
|
+
/* @__PURE__ */ jsx2(EffortMeter, { fill: effortMeterFill(l.id, levels), className: "ml-auto text-foreground" }),
|
|
357
|
+
l.id === value && /* @__PURE__ */ jsx2(CheckGlyph, { className: "h-3.5 w-3.5 shrink-0 text-primary" })
|
|
358
|
+
]
|
|
359
|
+
},
|
|
360
|
+
l.id
|
|
361
|
+
)) })
|
|
362
|
+
] });
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// src/web-react/use-composer-attachments.ts
|
|
366
|
+
import { useCallback, useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
|
|
367
|
+
function newId() {
|
|
368
|
+
const cryptoObject = globalThis.crypto;
|
|
369
|
+
if (typeof cryptoObject?.randomUUID === "function") return cryptoObject.randomUUID();
|
|
370
|
+
return `att-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
371
|
+
}
|
|
372
|
+
function dedupeName(name, taken) {
|
|
373
|
+
if (!taken.has(name)) return name;
|
|
374
|
+
const dot = name.lastIndexOf(".");
|
|
375
|
+
const base = dot > 0 ? name.slice(0, dot) : name;
|
|
376
|
+
const ext = dot > 0 ? name.slice(dot) : "";
|
|
377
|
+
let n = 2;
|
|
378
|
+
let candidate = `${base}-${n}${ext}`;
|
|
379
|
+
while (taken.has(candidate)) {
|
|
380
|
+
n += 1;
|
|
381
|
+
candidate = `${base}-${n}${ext}`;
|
|
382
|
+
}
|
|
383
|
+
return candidate;
|
|
384
|
+
}
|
|
385
|
+
function kindForMime(mime) {
|
|
386
|
+
return mime.startsWith("image/") ? "image" : "file";
|
|
387
|
+
}
|
|
388
|
+
function isAcceptedFileType(file, accept) {
|
|
389
|
+
const patterns = accept.split(",").map((p) => p.trim()).filter((p) => p.length > 0);
|
|
390
|
+
if (patterns.length === 0) return true;
|
|
391
|
+
const name = file.name.toLowerCase();
|
|
392
|
+
const type = (file.type || "").toLowerCase();
|
|
393
|
+
return patterns.some((pattern) => {
|
|
394
|
+
const lower = pattern.toLowerCase();
|
|
395
|
+
if (lower.startsWith(".")) return name.endsWith(lower);
|
|
396
|
+
if (lower.endsWith("/*")) return type.startsWith(lower.slice(0, -1));
|
|
397
|
+
return type === lower;
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
async function parseUploadError(res) {
|
|
401
|
+
const detail = await res.json().catch(() => null);
|
|
402
|
+
if (detail && typeof detail === "object" && "error" in detail) {
|
|
403
|
+
const error = detail.error;
|
|
404
|
+
if (typeof error === "string" && error) return error;
|
|
405
|
+
if (error && typeof error === "object" && "message" in error) {
|
|
406
|
+
const message = error.message;
|
|
407
|
+
if (typeof message === "string" && message) return message;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
return `Upload failed (${res.status})`;
|
|
411
|
+
}
|
|
412
|
+
var NO_UPLOAD_TARGET_MESSAGE = "No upload destination configured (pass uploadUrl or buildUploadRequest)";
|
|
413
|
+
function useComposerAttachments(options) {
|
|
414
|
+
const optionsRef = useRef2(options);
|
|
415
|
+
optionsRef.current = options;
|
|
416
|
+
const [staged, setStagedState] = useState2([]);
|
|
417
|
+
const stagedRef = useRef2([]);
|
|
418
|
+
const controllersRef = useRef2(/* @__PURE__ */ new Map());
|
|
419
|
+
const setStaged = useCallback(
|
|
420
|
+
(updater) => {
|
|
421
|
+
const next = typeof updater === "function" ? updater(stagedRef.current) : updater;
|
|
422
|
+
stagedRef.current = next;
|
|
423
|
+
setStagedState(next);
|
|
424
|
+
},
|
|
425
|
+
[]
|
|
426
|
+
);
|
|
427
|
+
const upload = useCallback(
|
|
428
|
+
async (id, file, name) => {
|
|
429
|
+
const opts = optionsRef.current;
|
|
430
|
+
setStaged(
|
|
431
|
+
(prev) => prev.map((s) => s.id === id ? { ...s, status: "uploading", errorMessage: void 0 } : s)
|
|
432
|
+
);
|
|
433
|
+
const controller = new AbortController();
|
|
434
|
+
controllersRef.current.set(id, controller);
|
|
435
|
+
const form = new FormData();
|
|
436
|
+
form.append("file", file, name);
|
|
437
|
+
const request = opts.buildUploadRequest ? opts.buildUploadRequest({ file, name, form }) : opts.uploadUrl ? { url: opts.uploadUrl } : null;
|
|
438
|
+
if (!request) {
|
|
439
|
+
setStaged(
|
|
440
|
+
(prev) => prev.map(
|
|
441
|
+
(s) => s.id === id ? { ...s, status: "error", errorMessage: NO_UPLOAD_TARGET_MESSAGE } : s
|
|
442
|
+
)
|
|
443
|
+
);
|
|
444
|
+
opts.onError?.(NO_UPLOAD_TARGET_MESSAGE);
|
|
445
|
+
controllersRef.current.delete(id);
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
try {
|
|
449
|
+
const res = await fetch(request.url, {
|
|
450
|
+
method: "POST",
|
|
451
|
+
credentials: "same-origin",
|
|
452
|
+
...request.init,
|
|
453
|
+
body: form,
|
|
454
|
+
signal: controller.signal
|
|
455
|
+
});
|
|
456
|
+
if (!res.ok) {
|
|
457
|
+
const message = await parseUploadError(res);
|
|
458
|
+
setStaged(
|
|
459
|
+
(prev) => prev.map((s) => s.id === id ? { ...s, status: "error", errorMessage: message } : s)
|
|
460
|
+
);
|
|
461
|
+
opts.onError?.(message);
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
const data = await res.json();
|
|
465
|
+
const uploaded = data.files?.[0];
|
|
466
|
+
if (!uploaded) {
|
|
467
|
+
const message = "Upload returned no file";
|
|
468
|
+
setStaged(
|
|
469
|
+
(prev) => prev.map((s) => s.id === id ? { ...s, status: "error", errorMessage: message } : s)
|
|
470
|
+
);
|
|
471
|
+
opts.onError?.(message);
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
setStaged(
|
|
475
|
+
(prev) => prev.map((s) => s.id === id ? { ...s, status: "ready", reference: uploaded } : s)
|
|
476
|
+
);
|
|
477
|
+
} catch (err) {
|
|
478
|
+
if (err.name === "AbortError") return;
|
|
479
|
+
const message = err instanceof Error && err.message ? err.message : "Upload failed \u2014 check your connection";
|
|
480
|
+
setStaged(
|
|
481
|
+
(prev) => prev.map((s) => s.id === id ? { ...s, status: "error", errorMessage: message } : s)
|
|
482
|
+
);
|
|
483
|
+
opts.onError?.(message);
|
|
484
|
+
} finally {
|
|
485
|
+
controllersRef.current.delete(id);
|
|
486
|
+
}
|
|
487
|
+
},
|
|
488
|
+
[setStaged]
|
|
489
|
+
);
|
|
490
|
+
const addFiles = useCallback(
|
|
491
|
+
async (files) => {
|
|
492
|
+
const opts = optionsRef.current;
|
|
493
|
+
const enabled2 = opts.enabled ?? true;
|
|
494
|
+
if (!enabled2) {
|
|
495
|
+
opts.onReject?.("Attachments are disabled");
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
const accept = opts.accept ?? ATTACHMENT_ACCEPT;
|
|
499
|
+
const maxCount = opts.limits?.maxCount ?? ATTACHMENT_MAX_COUNT;
|
|
500
|
+
const maxBinaryBytes = opts.limits?.maxBinaryBytes ?? MAX_BINARY_ATTACHMENT_BYTES;
|
|
501
|
+
const maxTextBytes = opts.limits?.maxTextBytes ?? MAX_TEXT_ATTACHMENT_BYTES;
|
|
502
|
+
const maxTotalBytes = opts.limits?.maxTotalBytes ?? MAX_ATTACHMENT_TOTAL_BYTES;
|
|
503
|
+
const allowedKinds = opts.allowedKinds ?? ["image", "file"];
|
|
504
|
+
const list = Array.isArray(files) ? files : Array.from(files);
|
|
505
|
+
const currentCount = stagedRef.current.length;
|
|
506
|
+
const countAccepted = [];
|
|
507
|
+
for (const file of list) {
|
|
508
|
+
if (!isAcceptedFileType(file, accept)) {
|
|
509
|
+
opts.onReject?.(`"${file.name}" is not an accepted file type (${accept}).`, file);
|
|
510
|
+
continue;
|
|
511
|
+
}
|
|
512
|
+
if (currentCount + countAccepted.length >= maxCount) {
|
|
513
|
+
opts.onReject?.(`"${file.name}" was not added \u2014 the ${maxCount}-file limit is already reached.`, file);
|
|
514
|
+
continue;
|
|
515
|
+
}
|
|
516
|
+
countAccepted.push(file);
|
|
517
|
+
}
|
|
518
|
+
const sizeAccepted = [];
|
|
519
|
+
for (const file of countAccepted) {
|
|
520
|
+
const bytes = new Uint8Array(await file.arrayBuffer());
|
|
521
|
+
const sniff = sniffBinary(bytes);
|
|
522
|
+
const typeCheck = checkAttachmentType(file.name, sniff);
|
|
523
|
+
if (!typeCheck.succeeded) {
|
|
524
|
+
opts.onReject?.(typeCheck.message, file);
|
|
525
|
+
continue;
|
|
526
|
+
}
|
|
527
|
+
const limit = sniff.binary ? maxBinaryBytes : maxTextBytes;
|
|
528
|
+
if (file.size > limit) {
|
|
529
|
+
opts.onReject?.(attachmentSizeErrorMessage(file.name, file.size, limit), file);
|
|
530
|
+
continue;
|
|
531
|
+
}
|
|
532
|
+
const mediaType = sniff.mime ?? file.type ?? "";
|
|
533
|
+
const kind = kindForMime(mediaType);
|
|
534
|
+
if (!allowedKinds.includes(kind)) {
|
|
535
|
+
opts.onReject?.(`"${file.name}" is a ${kind} attachment, which isn't accepted here`, file);
|
|
536
|
+
continue;
|
|
537
|
+
}
|
|
538
|
+
sizeAccepted.push(file);
|
|
539
|
+
}
|
|
540
|
+
const accepted = [];
|
|
541
|
+
let totalBytes = stagedRef.current.reduce((total, s) => total + s.size, 0);
|
|
542
|
+
for (const file of sizeAccepted) {
|
|
543
|
+
const nextTotalBytes = totalBytes + file.size;
|
|
544
|
+
if (nextTotalBytes > maxTotalBytes) {
|
|
545
|
+
opts.onReject?.(attachmentTotalSizeErrorMessage(nextTotalBytes, maxTotalBytes), file);
|
|
546
|
+
continue;
|
|
547
|
+
}
|
|
548
|
+
accepted.push(file);
|
|
549
|
+
totalBytes = nextTotalBytes;
|
|
550
|
+
}
|
|
551
|
+
if (accepted.length === 0) return;
|
|
552
|
+
const taken = new Set(stagedRef.current.map((s) => s.name));
|
|
553
|
+
const entries = accepted.map((file) => {
|
|
554
|
+
const name = dedupeName(sanitizeAttachmentFileName(file.name), taken);
|
|
555
|
+
taken.add(name);
|
|
556
|
+
return {
|
|
557
|
+
id: newId(),
|
|
558
|
+
file,
|
|
559
|
+
name,
|
|
560
|
+
size: file.size,
|
|
561
|
+
status: "pending",
|
|
562
|
+
previewUrl: file.type.startsWith("image/") ? URL.createObjectURL(file) : void 0
|
|
563
|
+
};
|
|
564
|
+
});
|
|
565
|
+
setStaged((prev) => [...prev, ...entries]);
|
|
566
|
+
for (const entry of entries) void upload(entry.id, entry.file, entry.name);
|
|
567
|
+
},
|
|
568
|
+
[setStaged, upload]
|
|
569
|
+
);
|
|
570
|
+
const retry = useCallback(
|
|
571
|
+
(id) => {
|
|
572
|
+
const entry = stagedRef.current.find((s) => s.id === id);
|
|
573
|
+
if (!entry) return;
|
|
574
|
+
void upload(entry.id, entry.file, entry.name);
|
|
575
|
+
},
|
|
576
|
+
[upload]
|
|
577
|
+
);
|
|
578
|
+
const removeAttachment = useCallback(
|
|
579
|
+
(id) => {
|
|
580
|
+
controllersRef.current.get(id)?.abort();
|
|
581
|
+
controllersRef.current.delete(id);
|
|
582
|
+
const entry = stagedRef.current.find((s) => s.id === id);
|
|
583
|
+
if (entry?.previewUrl) URL.revokeObjectURL(entry.previewUrl);
|
|
584
|
+
setStaged((prev) => prev.filter((s) => s.id !== id));
|
|
585
|
+
},
|
|
586
|
+
[setStaged]
|
|
587
|
+
);
|
|
588
|
+
const clear = useCallback(() => {
|
|
589
|
+
for (const controller of controllersRef.current.values()) controller.abort();
|
|
590
|
+
controllersRef.current.clear();
|
|
591
|
+
for (const entry of stagedRef.current) {
|
|
592
|
+
if (entry.previewUrl) URL.revokeObjectURL(entry.previewUrl);
|
|
593
|
+
}
|
|
594
|
+
setStaged([]);
|
|
595
|
+
}, [setStaged]);
|
|
596
|
+
useEffect2(
|
|
597
|
+
() => () => {
|
|
598
|
+
for (const controller of controllersRef.current.values()) controller.abort();
|
|
599
|
+
controllersRef.current.clear();
|
|
600
|
+
for (const entry of stagedRef.current) {
|
|
601
|
+
if (entry.previewUrl) URL.revokeObjectURL(entry.previewUrl);
|
|
602
|
+
}
|
|
603
|
+
},
|
|
604
|
+
[]
|
|
605
|
+
);
|
|
606
|
+
const composerFiles = useMemo2(
|
|
607
|
+
() => staged.map((s) => ({
|
|
608
|
+
id: s.id,
|
|
609
|
+
name: s.name,
|
|
610
|
+
size: s.size,
|
|
611
|
+
kind: "file",
|
|
612
|
+
status: s.status
|
|
613
|
+
})),
|
|
614
|
+
[staged]
|
|
615
|
+
);
|
|
616
|
+
const references = useMemo2(
|
|
617
|
+
() => staged.filter((s) => s.status === "ready" && !!s.reference).map((s) => s.reference),
|
|
618
|
+
[staged]
|
|
619
|
+
);
|
|
620
|
+
const hasPending = useMemo2(
|
|
621
|
+
() => staged.some((s) => s.status === "pending" || s.status === "uploading"),
|
|
622
|
+
[staged]
|
|
623
|
+
);
|
|
624
|
+
const hasError = useMemo2(() => staged.some((s) => s.status === "error"), [staged]);
|
|
625
|
+
const enabled = options.enabled ?? true;
|
|
626
|
+
const blockReason = !enabled ? "Attachments are disabled" : hasPending ? "Attachments are still uploading" : hasError ? "Remove failed attachments to send" : null;
|
|
627
|
+
return {
|
|
628
|
+
composerFiles,
|
|
629
|
+
references,
|
|
630
|
+
addFiles,
|
|
631
|
+
retry,
|
|
632
|
+
removeAttachment,
|
|
633
|
+
clear,
|
|
634
|
+
hasPending,
|
|
635
|
+
hasError,
|
|
636
|
+
blockReason
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
// src/web-react/harness-glyphs.tsx
|
|
641
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
642
|
+
var BRAND_PATHS = {
|
|
643
|
+
opencode: [
|
|
644
|
+
"M16 6H8v12h8V6zm4 16H4V2h16v20z"
|
|
645
|
+
],
|
|
646
|
+
"claude-code": [
|
|
647
|
+
"M20.998 10.949H24v3.102h-3v3.028h-1.487V20H18v-2.921h-1.487V20H15v-2.921H9V20H7.488v-2.921H6V20H4.487v-2.921H3V14.05H0V10.95h3V5h17.998v5.949zM6 10.949h1.488V8.102H6v2.847zm10.51 0H18V8.102h-1.49v2.847z"
|
|
648
|
+
],
|
|
649
|
+
codex: [
|
|
650
|
+
"M8.086.457a6.105 6.105 0 013.046-.415c1.333.153 2.521.72 3.564 1.7a.117.117 0 00.107.029c1.408-.346 2.762-.224 4.061.366l.063.03.154.076c1.357.703 2.33 1.77 2.918 3.198.278.679.418 1.388.421 2.126a5.655 5.655 0 01-.18 1.631.167.167 0 00.04.155 5.982 5.982 0 011.578 2.891c.385 1.901-.01 3.615-1.183 5.14l-.182.22a6.063 6.063 0 01-2.934 1.851.162.162 0 00-.108.102c-.255.736-.511 1.364-.987 1.992-1.199 1.582-2.962 2.462-4.948 2.451-1.583-.008-2.986-.587-4.21-1.736a.145.145 0 00-.14-.032c-.518.167-1.04.191-1.604.185a5.924 5.924 0 01-2.595-.622 6.058 6.058 0 01-2.146-1.781c-.203-.269-.404-.522-.551-.821a7.74 7.74 0 01-.495-1.283 6.11 6.11 0 01-.017-3.064.166.166 0 00.008-.074.115.115 0 00-.037-.064 5.958 5.958 0 01-1.38-2.202 5.196 5.196 0 01-.333-1.589 6.915 6.915 0 01.188-2.132c.45-1.484 1.309-2.648 2.577-3.493.282-.188.55-.334.802-.438.286-.12.573-.22.861-.304a.129.129 0 00.087-.087A6.016 6.016 0 015.635 2.31C6.315 1.464 7.132.846 8.086.457zm-.804 7.85a.848.848 0 00-1.473.842l1.694 2.965-1.688 2.848a.849.849 0 001.46.864l1.94-3.272a.849.849 0 00.007-.854l-1.94-3.393zm5.446 6.24a.849.849 0 000 1.695h4.848a.849.849 0 000-1.696h-4.848z"
|
|
651
|
+
],
|
|
652
|
+
amp: [
|
|
653
|
+
"M15.087 23.18L12.03 24l-2.097-7.823-5.738 5.738-2.251-2.251 5.718-5.719-7.769-2.082.82-3.057 11.294 3.08 3.08 11.295z",
|
|
654
|
+
"M19.505 18.762l-3.057.82-2.564-9.573-9.572-2.564.819-3.057 11.295 3.079 3.08 11.295z",
|
|
655
|
+
"M23.893 14.374l-3.057.82-2.565-9.572L8.7 3.057 9.52 0l11.295 3.08 3.079 11.294z"
|
|
656
|
+
],
|
|
657
|
+
"kimi-code": [
|
|
658
|
+
"M1.052 16.916l9.539 2.552a21.007 21.007 0 00.06 2.033l5.956 1.593a11.997 11.997 0 01-5.586.865l-.18-.016-.044-.004-.084-.009-.094-.01a11.605 11.605 0 01-.157-.02l-.107-.014-.11-.016a11.962 11.962 0 01-.32-.051l-.042-.008-.075-.013-.107-.02-.07-.015-.093-.019-.075-.016-.095-.02-.097-.023-.094-.022-.068-.017-.088-.022-.09-.024-.095-.025-.082-.023-.109-.03-.062-.02-.084-.025-.093-.028-.105-.034-.058-.019-.08-.026-.09-.031-.066-.024a6.293 6.293 0 01-.044-.015l-.068-.025-.101-.037-.057-.022-.08-.03-.087-.035-.088-.035-.079-.032-.095-.04-.063-.028-.063-.027a5.655 5.655 0 01-.041-.018l-.066-.03-.103-.047-.052-.024-.096-.046-.062-.03-.084-.04-.086-.044-.093-.047-.052-.027-.103-.055-.057-.03-.058-.032a6.49 6.49 0 01-.046-.026l-.094-.053-.06-.034-.051-.03-.072-.041-.082-.05-.093-.056-.052-.032-.084-.053-.061-.039-.079-.05-.07-.047-.053-.035a7.785 7.785 0 01-.054-.036l-.044-.03-.044-.03a6.066 6.066 0 01-.04-.028l-.057-.04-.076-.054-.069-.05-.074-.054-.056-.042-.076-.057-.076-.059-.086-.067-.045-.035-.064-.052-.074-.06-.089-.073-.046-.039-.046-.039a7.516 7.516 0 01-.043-.037l-.045-.04-.061-.053-.07-.062-.068-.06-.062-.058-.067-.062-.053-.05-.088-.084a13.28 13.28 0 01-.099-.097l-.029-.028-.041-.042-.069-.07-.05-.051-.05-.053a6.457 6.457 0 01-.168-.179l-.08-.088-.062-.07-.071-.08-.042-.049-.053-.062-.058-.068-.046-.056a7.175 7.175 0 01-.027-.033l-.045-.055-.066-.082-.041-.052-.05-.064-.02-.025a11.99 11.99 0 01-1.44-2.402zm-1.02-5.794l11.353 3.037a20.468 20.468 0 00-.469 2.011l10.817 2.894a12.076 12.076 0 01-1.845 2.005L.657 15.923l-.016-.046-.035-.104a11.965 11.965 0 01-.05-.153l-.007-.023a11.896 11.896 0 01-.207-.741l-.03-.126-.018-.08-.021-.097-.018-.081-.018-.09-.017-.084-.018-.094c-.026-.141-.05-.283-.071-.426l-.017-.118-.011-.083-.013-.102a12.01 12.01 0 01-.019-.161l-.005-.047a12.12 12.12 0 01-.034-2.145zm1.593-5.15l11.948 3.196c-.368.605-.705 1.231-1.01 1.875l11.295 3.022c-.142.82-.368 1.612-.668 2.365l-11.55-3.09L.124 10.26l.015-.1.008-.049.01-.067.015-.087.018-.098c.026-.148.056-.295.088-.442l.028-.124.02-.085.024-.097c.022-.09.045-.18.07-.268l.028-.102.023-.083.03-.1.025-.082.03-.096.026-.082.031-.095a11.896 11.896 0 011.01-2.232zm4.442-4.4L17.352 4.59a20.77 20.77 0 00-1.688 1.721l7.823 2.093c.267.852.442 1.744.513 2.665L2.106 5.213l.045-.065.027-.04.04-.055.046-.065.055-.076.054-.072.064-.086.05-.065.057-.073.055-.07.06-.074.055-.069.065-.077.054-.066.066-.077.053-.06.072-.082.053-.06.067-.074.054-.058.073-.078.058-.06.063-.067.168-.17.1-.098.059-.056.076-.071a12.084 12.084 0 012.272-1.677zM12.017 0h.097l.082.001.069.001.054.002.068.002.046.001.076.003.047.002.06.003.054.002.087.005.105.007.144.011.088.007.044.004.077.008.082.008.047.005.102.012.05.006.108.014.081.01.042.006.065.01.207.032.07.012.065.011.14.026.092.018.11.022.046.01.075.016.041.01L14.7.3l.042.01.065.015.049.012.071.017.096.024.112.03.113.03.113.032.05.015.07.02.078.024.073.023.05.016.05.016.076.025.099.033.102.036.048.017.064.023.093.034.11.041.116.045.1.04.047.02.06.024.041.018.063.026.04.018.057.025.11.048.1.046.074.035.075.036.06.028.092.046.091.045.102.052.053.028.049.026.046.024.06.033.041.022.052.029.088.05.106.06.087.051.057.034.053.032.096.059.088.055.098.062.036.024.064.041.084.056.04.027.062.042.062.043.023.017c.054.037.108.075.161.114l.083.06.065.048.056.043.086.065.082.064.04.03.05.041.086.069.079.065.085.071c.712.6 1.353 1.283 1.909 2.031L7.222.994l.062-.027.065-.028.081-.034.086-.035c.113-.045.227-.09.341-.131l.096-.035.093-.033.084-.03.096-.031c.087-.03.176-.058.264-.085l.091-.027.086-.025.102-.03.085-.023.1-.026L9.04.37l.09-.023.091-.022.095-.022.09-.02.098-.021.091-.02.095-.018.092-.018.1-.018.091-.016.098-.017.092-.014.097-.015.092-.013.102-.013.091-.012.105-.012.09-.01.105-.01c.093-.01.186-.018.28-.024l.106-.008.09-.005.11-.006.093-.004.1-.004.097-.002.099-.002.197-.002z"
|
|
659
|
+
],
|
|
660
|
+
openclaw: [
|
|
661
|
+
"M9.046 7.104a.527.527 0 110 1.055.527.527 0 010-1.055z",
|
|
662
|
+
"M15.376 7.104a.528.528 0 110 1.056.528.528 0 010-1.056z",
|
|
663
|
+
"M16.877 1.912c.58-.27 1.14-.323 1.616-.037a.317.317 0 01-.326.542c-.227-.136-.547-.153-1.022.068-.352.165-.765.45-1.234.866 2.683 1.17 4.4 3.5 5.148 5.921a6.421 6.421 0 00-.704.184c-.578.016-1.174.204-1.502.735-.338.55-.268 1.276.072 2.069l.005.012.007.014c.523 1.045 1.318 1.91 2.2 2.284-.912 3.274-3.44 6.144-5.972 6.988v2.109h-2.11v-2.11c-1.043.417-2.086.01-2.11 0v2.11h-2.11v-2.11c-2.531-.843-5.061-3.713-5.973-6.987.882-.373 1.678-1.238 2.2-2.284l.007-.014.006-.012c.34-.793.41-1.518.071-2.069-.327-.531-.923-.719-1.503-.735a6.409 6.409 0 00-.704-.183c.749-2.421 2.466-4.751 5.149-5.922-.47-.416-.88-.701-1.234-.866-.474-.221-.794-.204-1.021-.068a.318.318 0 01-.435-.109.317.317 0 01.109-.433c.476-.286 1.036-.233 1.615.037.49.229 1.031.628 1.621 1.182A9.924 9.924 0 0112 2.568c1.199 0 2.284.19 3.256.526.59-.554 1.13-.953 1.62-1.182zM8.835 6.577a1.266 1.266 0 100 2.532 1.266 1.266 0 000-2.532zm6.33 0a1.267 1.267 0 100 2.533 1.267 1.267 0 000-2.533z",
|
|
664
|
+
"M.395 13.118c-.966-1.932-.163-3.863 2.41-3.365v-.001l.05.01c.084.018.17.038.26.06.033.009.067.017.1.027.084.022.168.048.255.076l.09.027c.528 0 .95.158 1.16.501.212.343.212.87-.105 1.61-.085.17-.178.333-.276.489l-.01.017a4.967 4.967 0 01-.62.791l-.019.02c-1.092 1.117-2.496 1.336-3.295-.262z",
|
|
665
|
+
"M21.193 9.753c2.574-.5 3.378 1.433 2.411 3.365-.58 1.159-1.476 1.361-2.342.96l-.011-.005a2.419 2.419 0 01-.114-.056l-.019-.01a2.751 2.751 0 01-.115-.067l-.023-.014c-.035-.022-.071-.044-.106-.068l-.05-.035c-.55-.388-1.062-1.007-1.44-1.76-.276-.647-.311-1.132-.174-1.472.176-.439.636-.639 1.23-.639.032-.011.066-.02.099-.03.08-.026.16-.05.238-.072l.117-.03a5.502 5.502 0 01.3-.067z"
|
|
666
|
+
],
|
|
667
|
+
hermes: [
|
|
668
|
+
"M5.938 12.835c.127-.039.285.02.373.143.028.038.036.092.046.14.003.014-.02.033-.04.05-.124-.098-.24-.194-.354-.291-.011-.01-.016-.027-.025-.042zM8.396 9.412c.195-.032.39-.06.588-.05a.54.54 0 01.148.026c.202.071.402.147.601.224.028.01.05.036.075.055l-.013.027a9.203 9.203 0 01-.26-.089c-.115-.038-.213-.077-.315-.098-.25-.05-.25-.046-.292-.014l.574.144c.275.139.55.276.823.417.042.022.09.057.107.098.026.06.063.076.117.072.066-.006.132-.017.213-.027l-.04.086c.051.08.142.02.216.064-.074.13-.247.09-.334.199l.061.074-.12.087c0 .106-.038.168-.306.243l.026.085-.196.042.07.124h-.25l-.007.137c-.081-.01-.161-.018-.244-.027l-.053.123c-.027-.008-.052-.011-.073-.023-.067-.038-.128-.056-.195.006-.019.017-.063.014-.093.008-.026-.006-.05-.029-.07-.042-.11.095-.11.095-.208.003-.057.046-.12.074-.186.011-.063.027-.123-.02-.178-.014-.07.007-.097-.035-.133-.07l-.13.033c-.013-.236-.194-.19-.34-.203.005-.072.05-.092.095-.094a.474.474 0 01.159.022c.164.05.32.12.496.138.203.021.405.029.601-.015.265-.059.52-.149.707-.365.049-.056.083-.127.117-.195.019-.038.02-.084-.02-.116a1.397 1.397 0 00-.382-.217c.024.12-.031.182-.115.221 0 .014-.004.025 0 .03.08.115.084.16-.007.267a1.39 1.39 0 01-.218.211.477.477 0 01-.641-.05 1.36 1.36 0 01-.133-.152c-.078-.107-.076-.108-.033-.236-.165-.08-.128-.226-.104-.364.008-.05.028-.096.049-.163-.04.014-.067.017-.087.032a.897.897 0 00-.316.357c-.007.016-.01.034-.02.047-.012.015-.034.038-.045.035-.02-.006-.037-.027-.05-.045-.008-.012-.007-.032-.012-.057h-.126l.053-.172a14.82 14.82 0 00-.039-.049l.11-.284c-.06.026-.091.044-.124.051-.03.007-.064 0-.095 0 0-.031-.01-.07.004-.092.149-.22.305-.428.593-.476z",
|
|
669
|
+
"M8.06 10.788c-.003-.038-.004-.075.037-.062.016.006.034.048.028.067-.01.04-.038.032-.064-.005z",
|
|
670
|
+
"M11.981.009c.226-.012.453-.011.679 0 .247.01.495.024.74.062.401.064.798.157 1.19.273.463.138.92.299 1.356.511a7.31 7.31 0 012.948 2.642c.292.469.536.963.739 1.479.219.556.446 1.11.623 1.683.204.654.329 1.326.458 1.997.097.504.182 1.01.29 1.511.156.722.329 1.44.494 2.16.186.812.4 1.615.63 2.415.102.355.193.713.282 1.072.11.436.202.876.254 1.323.031.278.066.557.073.837a7.56 7.56 0 01-.017.88c-.037.413-.1.818-.226 1.212a5.017 5.017 0 01-.915 1.649l-.13.156.018.023c.043-.023.088-.041.127-.068.2-.138.373-.307.531-.49.4-.46.721-.973.975-1.529a3.59 3.59 0 00.325-1.72c-.024-.424-.097-.834-.3-1.213-.013-.027-.015-.06-.03-.121.05.035.082.048.101.072.107.13.22.258.315.398.33.494.46 1.052.486 1.64a3.75 3.75 0 01-.47 1.97c-.36.655-.887 1.14-1.526 1.506-.193.111-.394.21-.595.308-.157.078-.248.211-.318.365a.522.522 0 00-.033.406.359.359 0 01.013.139c-.005.077-.077.155-.14.162-.054.006-.125-.043-.15-.116a1.206 1.206 0 01-.06-.233c-.04-.314-.155-.6-.308-.87a3.906 3.906 0 00-.73-.91 2.129 2.129 0 00-.897-.524 4.093 4.093 0 00-.692-.131c-.075-.008-.15-.04-.22.01.18.06.363.11.538.18.434.173.82.43 1.18.728.308.255.58.543.794.884.098.155.186.315.227.496.027.123.042.25.067.375.013.062-.002.109-.053.144-.047.033-.122.034-.163-.01a.455.455 0 01-.08-.14c-.03-.073-.038-.159-.078-.225a7.314 7.314 0 00-1.423-1.664c-.16-.137-.329-.26-.537-.323-.376-.114-.753-.203-1.15-.154-.213.025-.427.032-.64.053a1.6 1.6 0 00-.736.278 5.14 5.14 0 00-.834.72c-.329.342-.642.699-.955 1.055-.136.155-.264.319-.314.531a5.227 5.227 0 00-.012.051.096.096 0 01-.09.076h-.31c-.046 0-.082-.048-.072-.094.023-.108.045-.216.07-.324.075-.325.19-.635.368-.917.024-.039.04-.088.104-.08l.01.049.027.077c.28-.435.571-.834.996-1.135.283-.204.584-.378.89-.55a.196.196 0 00-.098-.002c-.162.043-.325.084-.485.134-.402.124-.764.33-1.11.566-.147.1-.298.193-.414.333a7.314 7.314 0 00-1.07 1.767.845.845 0 00-.04.12.075.075 0 01-.072.056h-.494c-.04 0-.062-.051-.036-.082.123-.14.246-.282.377-.415.275-.281.58-.532.777-.884.027-.048.063-.09.095-.135.238-.333.54-.607.818-.902.082-.086.175-.16.26-.24.029-.027.053-.057.079-.085l-.018-.025-.135.041c-.034.017-.07.031-.102.05-.248.144-.494.292-.743.433-.408.23-.825.439-1.209.711-.281.2-.591.358-.889.533-.02.012-.044.015-.08.028-.015-.135.143-.201.108-.336-.033.014-.064.02-.085.038-.111.096-.227.19-.328.296-.148.157-.284.325-.425.488-.125.143-.25.286-.373.431A.153.153 0 019.89 24H8.762a.316.316 0 00.016-.042c.028-.09.085-.172.083-.28-.091-.018-.162.001-.212.077a4.45 4.45 0 00-.136.215c-.01.016-.024.03-.042.03h-.093c-.019 0-.029-.022-.017-.037.071-.088.14-.178.209-.268.001-.002-.006-.012-.012-.024-.014.004-.03.006-.045.013-.176.09-.352.181-.527.274a.363.363 0 01-.168.042H5.202c-.026 0-.039-.036-.019-.053.21-.178.402-.374.558-.605.335-.496.538-1.047.667-1.629.004-.02-.003-.043-.006-.091-.037.048-.059.072-.076.1a1.943 1.943 0 01-.334.415c-.28.258-.59.448-.983.464-.297.012-.588 0-.865-.127-.46-.21-.722-.57-.794-1.072-.025-.17-.017-.171-.182-.219A3.513 3.513 0 011.97 20.6a2.286 2.286 0 01-.808-1.13 3.569 3.569 0 01-.16-1.245c.002-.034.016-.067.024-.1.032.023.046.043.05.066.033.153.059.308.096.46.086.355.257.664.516.92.258.256.571.419.91.532.358.118.717.138 1.07-.016a1.89 1.89 0 00.621-.452c.328-.348.533-.76.648-1.223.009-.034.005-.071.007-.11-.015.006-.026.006-.03.011-.031.05-.064.1-.093.152-.284.502-.679.887-1.196 1.135-.351.17-.718.255-1.11.159a1.607 1.607 0 01-.971-.64 2.006 2.006 0 01-.368-.924 2.903 2.903 0 01.02-.886c.05-.439.466-1.17.742-1.271-.02.063-.035.112-.053.16-.043.116-.097.227-.13.345a1.901 1.901 0 00-.05.82c.033.212.09.416.204.6.147.236.346.407.62.465.11.023.225.014.338.018a.576.576 0 00.386-.131c.164-.128.282-.292.366-.481.168-.375.24-.777.309-1.179.05-.296.093-.594.133-.893.039-.281.071-.563.104-.845.026-.232.048-.464.074-.696.024-.228.052-.455.076-.683.024-.227.047-.455.069-.683.013-.14.022-.28.034-.42l.037-.417c.022-.25.041-.5.065-.748.008-.082-.02-.132-.09-.177a2.46 2.46 0 01-.492-.418c-.1-.109-.188-.228-.282-.342-.035-.042-.056-.097-.116-.118a2.084 2.084 0 00.275.597c.06.092.131.176.196.265.063.086.182.115.234.226-.028.003-.046.01-.06.006a4.74 4.74 0 01-.22-.057 2.71 2.71 0 01-1.287-.819c-.435-.487-.656-1.076-.71-1.723a5.206 5.206 0 01.014-1.06c.072-.602.22-1.186.45-1.745.155-.376.338-.741.526-1.102.205-.393.466-.75.765-1.076.512-.559 1.104-1.024 1.726-1.448.717-.49 1.478-.898 2.277-1.233C8.244.828 8.767.632 9.31.494c.655-.166 1.31-.33 1.982-.415.229-.03.458-.058.688-.07zm-1.847 22.82c-.07.06-.147.111-.207.18-.238.27-.464.549-.668.869l-.044.108a.177.177 0 00.093-.057c.174-.19.351-.378.519-.574.104-.122.195-.255.288-.386.024-.034.03-.08.046-.12l-.027-.02zm1.65-3.695a5.51 5.51 0 00-.653.593l-.37.386a.963.963 0 01-.377.25 1.372 1.372 0 01-.467.09c-.044 0-.087.006-.151.012.028.058.043.097.064.131.15.242.301.482.45.724.136.22.276.438.399.666.068.125.105.267.156.404.077.027.14-.018.202-.048.29-.135.579-.274.867-.412.213-.101.437-.186.636-.31.347-.215.68-.455 1.018-.685.015-.01.026-.028.042-.046-.023-.019-.038-.037-.056-.044-.287-.111-.527-.3-.77-.482a5.319 5.319 0 01-.506-.42 1.757 1.757 0 01-.41-.653c-.019-.049-.045-.095-.075-.156zm-5.847.264c-.06.096-.097.194-.132.293a3.38 3.38 0 01-.555 1.01c-.2.25-.455.412-.762.493-.23.06-.464.076-.7.07-.048-.002-.097.002-.158.005.016.04.021.066.035.085.1.145.23.246.4.295.157.046.316.034.498.023.181-.037.343-.115.485-.234.238-.199.402-.454.536-.732.175-.363.264-.751.342-1.144.01-.053.008-.11.011-.164zm14.945-4.586c.008.029.016.057.027.107.024.155.051.31.072.464.03.219.067.437.078.657.017.344.027.689-.014 1.033-.037.315-.063.633-.116.946a6.153 6.153 0 01-.46 1.518c-.008.018-.01.039-.02.082.047-.03.077-.042.098-.064.085-.083.17-.167.248-.255.271-.305.458-.66.596-1.043.18-.498.228-1.011.145-1.531-.103-.65-.33-1.263-.597-1.881a9.055 9.055 0 00-.024-.055l-.033.022zM5.797 8.29a.26.26 0 00.018.153c.124.251.25.501.379.75.025.049.066.09.03.163-.284.06-.578.119-.88.255.059.038.097.06.132.087.042.032.112.058.09.12-.01.033-.075.048-.117.072.017.01.043.021.067.036.166.102.33.207.447.368.138.192.229.404.188.644-.079.469-.306.85-.69 1.132-.054.04-.106.083-.161.122a.243.243 0 00-.103.245.77.77 0 00.055.195c.083.196.22.35.375.492.083.076.159.164.222.257a.37.37 0 01.025.377c-.023.05-.05.099-.076.148-.03.06-.028.111.022.162.041.042.08.089.112.138.038.058.078.079.147.05a.486.486 0 01.333-.006c.16.046.302.126.444.21.13.077.264.149.4.219.067.035.14.05.219.026.071-.022.124.01.145.076.02.064-.003.108-.074.139-.07.03-.137.063-.209.088-.1.035-.201.073-.314.077-.013-.107.11-.088.127-.159-.206-.126-.643-.145-.801-.034.063.112.035.21-.096.313-.13-.1-.025-.202.002-.3a.209.209 0 00-.249.17c-.015.101.067.216.178.224.108.007.218-.005.326-.012.06-.005.12-.027.199 0-.103.123-.248.127-.357.19.002.05.07.086.019.131-.053.048-.095-.001-.132-.03-.08-.063-.16-.126-.231-.197a.474.474 0 01-.157-.311.52.52 0 00-.043-.172c-.032-.074-.032-.137.033-.19-.018-.03-.028-.053-.045-.072a1.222 1.222 0 01-.196-.369c-.053-.137-.046-.264.048-.381.024-.03.05-.06.064-.095a.664.664 0 00.047-.168c.017-.165-.064-.287-.182-.387-.186-.156-.36-.322-.46-.551-.005-.011-.024-.017-.037-.026-.011.017-.024.027-.025.038-.019.185-.045.37-.052.557-.014.377.058.743.162 1.104.118.41.289.798.488 1.173.267.502.537 1.002.812 1.5.055.098.13.189.208.27.198.202.452.272.724.273.202 0 .404-.006.605-.026.295-.03.59-.073.884-.113.183-.025.365-.057.548-.08.21-.026.38.073.522.21.16.156.305.327.447.5.22.265.397.56.554.867.05.098.07.1.147.03.13-.121.26-.242.394-.36.067-.059.088-.12.067-.213a3.535 3.535 0 01-.085-.796c.002-.157.006-.314.018-.471.015-.224.03-.45.06-.672a59.114 59.114 0 01.362-2.298c.087-.493.182-.984.268-1.477.06-.347.118-.694.162-1.043.034-.273.055-.55.063-.825.011-.332.003-.665.002-.998 0-.077.004-.155-.01-.23-.028-.142-.01-.155-.162-.19a5.826 5.826 0 00-.607-.107c-.146-.018-.207-.053-.221-.19-.006-.049-.025-.098-.041-.146-.009-.025-.024-.048-.046-.09l-.025.264c-.009.096-.029.116-.127.115-.055 0-.11-.008-.164-.008-.476 0-.952-.008-1.426.032-.095.008-.173-.015-.226-.103-.04-.066-.088-.126-.134-.186-.063-.084-.086-.093-.182-.06-.195.068-.388.138-.582.21a2.71 2.71 0 00-.675.394.986.986 0 01-.323.168c-.033.01-.07.008-.127.013.02-.066.024-.114.047-.15.064-.105.135-.205.205-.306.023-.033.049-.063.073-.095l-.015-.023-.201.037c-.146.04-.296.07-.437.122-.148.053-.266.023-.386-.072a3.623 3.623 0 01-.733-.786l-.093-.132zm8.592 8.963l-.147.09c-.22.134-.44.266-.659.402-.093.058-.184.12-.27.188-.085.07-.124.161-.072.272.047.1.093.2.147.294.047.08.124.138.213.147.11.01.228.012.336-.012.217-.05.372-.205.528-.357a.291.291 0 00.087-.308c-.046-.18-.079-.365-.118-.547-.011-.052-.027-.103-.045-.169zm-.257-2.409c-.12.291-.205.597-.325.91-.151.433-.294.87-.435 1.323.036-.01.054-.01.067-.018.261-.16.522-.324.785-.484.054-.033.071-.078.065-.138-.012-.13-.024-.262-.034-.393l-.068-.886c-.008-.103-.02-.206-.029-.31-.009 0-.017-.002-.026-.004zm3.081-8.13l.099.285c.08.231.159.463.24.714l.58 1.952c.187.63.372 1.262.558 1.893.114.382.235.762.343 1.146.072.257.126.519.186.799.044.206.087.413.127.64.034.106.023.226.077.325l.025-.006-.068-.362c-.038-.206-.077-.412-.113-.638-.015-.07-.029-.141-.046-.211-.095-.396-.177-.796-.29-1.187-.196-.685-.413-1.364-.618-2.046-.165-.549-.322-1.1-.488-1.648-.069-.227-.15-.45-.226-.695l-.117-.336c-.037-.107-.075-.216-.115-.322-.04-.106-.084-.21-.127-.314a7.558 7.558 0 01-.027.01zM6.225 14.304c-.063-.001-.115.014-.134.083a.35.35 0 00.41.012 4.533 4.533 0 00-.276-.095zM5.23 11.98c-.026-.027-.057-.048-.075.002-.012.032-.007.07-.01.113.082-.037.082-.037.085-.115zm.062-1.189a.135.135 0 00-.088.056.197.197 0 00-.025.11c.005.152.01.306.026.457a.751.751 0 00.066.218c.061.136.157.167.288.101.055-.027.06-.054.025-.11a4.52 4.52 0 01-.129-.211c-.015-.068-.066-.131-.033-.207.04-.09-.076-.116-.074-.19V10.874c-.003-.038-.006-.087-.056-.083zm-.017-.968a.867.867 0 00-.467.127c-.076.045-.084.07-.05.158.034.087.07.173.115.254.064.117.09.125.21.077a.657.657 0 01.336-.053c.202.022.357.136.504.264l.092.077c.007-.006.014-.013.022-.018-.019-.105-.035-.226-.149-.264-.157-.053-.324-.075-.508-.117l-.24-.005c.24-.169.452-.044.687.009-.063-.115-.153-.147-.23-.193-.082-.05-.17-.092-.25-.144-.06-.037-.12-.08-.072-.172zm10.233.325c-.23-.01-.427.08-.608.211-.034.026-.06.065-.105.117.087.026.15.046.232.065.044-.015.088-.03.13-.046.306-.114.61-.115.904.031.126.063.237.04.366-.005-.02-.031-.03-.054-.045-.071a.986.986 0 00-.448-.273c-.14-.044-.284-.024-.426-.03zM7.99 6.483a.308.308 0 00.002.133c.08.321.156.643.242.962.104.387.27.75.456 1.103.02.037.061.08.098.087a.404.404 0 00.253-.051l-.472-.84c-.23-.448-.405-.92-.579-1.394zM10.397.497c-.2-.008-.405.004-.603.034-.236.035-.47.087-.7.152-.287.08-.569.18-.852.273-.04.013-.074.038-.11.058.028.014.05.018.07.014.287-.068.58-.085.873-.09.134-.002.269.009.402.025.19.024.382.048.57.09.456.104.874.3 1.265.556.464.306.888.66 1.257 1.078.205.232.395.475.56.739.17.274.315.561.449.856.273.601.456 1.232.6 1.876.04.173.07.348.1.524.017.104.065.167.17.19.122.028.2.105.22.251-.003.102-.06.174-.129.24a1.065 1.065 0 00-.268.358.164.164 0 00.083-.039c.08-.086.162-.172.235-.265a.56.56 0 00.13-.333c.009-.05.022-.1.024-.15.007-.124-.017-.15-.143-.168-.025-.004-.049-.014-.073-.015-.082-.007-.125-.063-.137-.131-.033-.198-.004-.355.247-.408.086-.018.174-.03.26-.042.158-.023.315-.053.473-.067.14-.012.19.033.226.167.008.029.018.057.021.087.019.179-.008.225-.141.288-.027.013-.055.024-.078.042a.148.148 0 00-.051.067c-.039.144.073.382.206.445l.673.32c.023.011.05.015.075.023l.018-.026c-.015-.008-.032-.013-.044-.024a2.27 2.27 0 00-.544-.32 4.898 4.898 0 00-.173-.075.203.203 0 01-.126-.191c-.003-.085.045-.154.128-.187l.059-.025c.099-.044.118-.076.112-.187a.384.384 0 00-.008-.063c-.067-.294-.123-.59-.205-.88a9.478 9.478 0 00-.826-2.036 7.465 7.465 0 00-1.39-1.805 4.536 4.536 0 00-1.177-.824 3.656 3.656 0 00-1.016-.328 6.155 6.155 0 00-.712-.074zm6.719 5.955c.01.014.018.028.038.034l-.022-.044-.016.01zM4.103 3.917a.062.062 0 01-.03.012.455.455 0 01-.04.039c-.01.01-.02.02-.045.04l-.363.354c-.088.085-.17.178-.266.253-.284.22-.425.53-.544.855a.132.132 0 00-.007.071c.013.055.033.108.052.168l.074.026c-.017.056-.03.105-.047.152-.058.164-.118.327-.175.491-.005.015.008.036.019.077.08-.175.158-.33.225-.489.228-.544.484-1.074.819-1.561.09-.133.182-.266.283-.401.004-.006.007-.013.022-.03.001-.016.003-.032.015-.04l.008-.017zm12.976 2.408a.023.023 0 01.009.019.073.073 0 00-.006.01.188.188 0 00.007.02l.018.022c.002-.007.007-.016.005-.021-.003-.01-.012-.018-.02-.038a1.331 1.331 0 01-.013-.012zM4.199 4.48c-.003.004-.008.008-.027.014-.005.013-.011.025-.031.047a2.085 2.085 0 01-.124.167c-.048.07-.116.055-.181.041-.134-.028-.228.016-.287.143-.089.187-.187.37-.273.56-.049.108-.11.216-.118.36.081.003.154.007.228.008h.228a2.563 2.563 0 01-.079.264c-.01.052-.022.103-.033.155l.02.004c.018-.046.037-.092.067-.153.066-.142.13-.285.2-.426.02-.04.034-.1.116-.092 0 .043.004.084 0 .124-.005.045-.017.09-.028.143.141.043.086.174.115.269.102-.022.104-.195.248-.144v.205l.017.002.439-1.059c-.13 0-.246-.02-.358.033-.024.011-.058-.001-.108-.004.075-.15.139-.278.211-.417a.128.128 0 01.025-.036c0-.015-.001-.03.008-.038l.006-.02c-.005.006-.01.011-.028.017-.004.012-.009.024-.026.045a.085.085 0 01-.032.033c-.123.157-.09.164-.258.106-.079-.027-.078-.028-.047-.144.028-.046.056-.093.098-.15 0-.016-.001-.032.007-.042L4.2 4.48zm2.073-.67c-.003.006-.007.011-.027.016-.094.125-.194.246-.28.377-.155.238-.301.481-.451.723-.14.224-.345.368-.575.481-.017.008-.04.006-.079.011.012-.059.016-.109.033-.153a6.076 6.076 0 01.229-.518l-.007-.02a.138.138 0 01-.035.025c-.028.05-.055.1-.093.164-.26.424-.443.817-.442.95.024.004.048.011.073.013.177.013.188.007.26-.165.03-.07.077-.12.147-.15l.175-.07c.044-.018.085-.057.146-.032.003.05-.01.11.014.145.042.062.044.125.047.193.002.049.017.098.026.147.029-.034.039-.065.05-.097.142-.39.277-.782.428-1.17.1-.256.22-.504.33-.756.013-.03.013-.067.03-.092V3.81zm3.987-.34c0 .045.01.084.021.123.042.16.094.318.124.48.024.133.023.27.028.406 0 .033-.019.067-.032.11-.094-.058-.047-.158-.106-.215h-.125c-.015.072-.01.152-.046.2-.066.085-.155.154-.236.227-.043.038-.078.018-.103-.025l-.046-.087c-.065.035-.117.069-.172.093-.116.051-.235.095-.35.147-.085.038-.09.053-.07.147.014.075.034.148.047.223.013.072.05.109.123.124.233.05.462.115.657.265.058-.102.058-.102.168-.151.03-.014.06-.03.092-.042.08-.03.115-.017.15.06.023.048.041.098.066.158.06-.14-.042-.267.017-.416.157.18.24.39.375.567a.235.235 0 00.022-.098c.002-.124 0-.247.002-.371 0-.034.013-.067.02-.1l.032-.003c.11.155.13.354.226.52a3.036 3.036 0 00-.01-.392c-.004-.045 0-.074.05-.088.08.036.116.14.215.158-.03-.275-.423-1.137-.798-1.635-.114-.127-.2-.28-.34-.386zm-2.667.696c-.019.034-.03.05-.037.067-.061.185-.125.37-.18.556-.031.105-.087.169-.195.19-.09.019-.178.052-.268.073-.038.009-.089.015-.118-.003-.024-.016-.025-.069-.036-.106-.064.076-.082.087-.17.047-.133-.062-.262-.135-.393-.201-.048-.025-.093-.063-.17-.03-.043.12-.091.25-.137.382-.099.28-.087.242.095.453.046.048.102.03.154.023.054-.009.106-.03.16-.036.13-.013.26-.08.367-.015.204-.064.387-.122.571-.178.05-.015.089.005.114.054.022.042.034.093.082.121.038-.056-.013-.128.063-.178l.14.241-.042-1.46zm.278.358c-.096-.01-.107.01-.11.108-.002.038-.003.078.002.115.03.2.099.386.174.57.002.006.012.01.022.015l.078-.05c.052.036.081.088.153.088.205-.002.41.014.616.012.099-.001.158.042.205.12.018.03.024.077.088.066l-.08-.394c-.05-.195-.085-.395-.172-.589-.057.057-.114.068-.18.046a.72.72 0 00-.135-.028c-.22-.028-.44-.059-.66-.08zm10.254-1.727c.089.163.155.316.139.491-.016.168.026.342-.044.516-.047-.033-.088-.082-.112-.075-.117.035-.164-.057-.227-.115a4.772 4.772 0 01-.286-.29l-.104-.113a4.856 4.856 0 01-.023.019c.035.046.07.093.11.156.04.064.084.127.122.193.034.058.065.118.031.205-.082-.01-.164-.019-.246-.032-.06-.01-.101 0-.124.07-.031.098-.037.096-.15.09.02.042.036.08.057.116.041.074.03.138-.03.196-.06.06-.118.122-.178.181a.175.175 0 01-.185.046c-.222-.061-.447-.113-.67-.174-.032-.009-.063-.04-.086-.068-.03-.04-.052-.087-.08-.13-.044-.07-.09-.138-.136-.207a.18.18 0 00-.014.105c.012.127.03.253.035.38.005.1-.024.12-.121.104-.104-.017-.206-.04-.31-.058-.064-.012-.131-.028-.202.03l.081.208c.09 0 .166-.01.237.002a.819.819 0 01.458.251c.078.083.154.168.241.26l.018-.005c-.004-.006-.008-.013-.01-.04.014-.056-.062-.118.018-.178.031.03.064.057.088.09.058.078.111.159.169.257l.089.141.024-.013a2093.819 2093.819 0 01-.427-.934c.055.007.083.007.108.016.193.07.385.142.577.216.074.028.147.06.219.094.062.028.112.018.157-.033.05-.056.102-.112.154-.167.05-.051.095-.046.132.014.016.025.026.053.04.08.071.138.143.277.217.433l.159.308.025-.011c-.044-.106-.07-.218-.138-.334-.057-.182-.168-.346-.206-.545.136.034.362.326.567.732l.057.074.018-.011a1.563 1.563 0 01-.052-.127c-.046-.145-.097-.29-.136-.436-.022-.083-.036-.173.022-.26l.109.058-.026-.207.027-.016c.022.02.05.036.065.06.073.108.143.22.215.33.01.016.029.029.043.043-.036-.217-.2-.38-.229-.626l.155.112c.014-.166.012-.319.042-.465.032-.158-.023-.297-.063-.445.024.004.036.006.055.025.092.124.183.249.277.371.02.027.05.047.069.087l.04.063.019-.015a.293.293 0 01-.053-.082 27.922 27.922 0 01-.332-.49c-.221-.311-.363-.467-.485-.521zm-6.57.327c-.003.161.092.275.069.415l-.368.087c.09.139.032.237-.052.331-.05.057-.092.122-.143.178-.037.04-.046.078-.018.126l.16.275c.029.048.072.066.128.064.076-.003.152 0 .228-.001.116-.003.216.022.275.137.006.014.02.024.044.052.004-.059-.003-.098.01-.13.016-.04.04-.099.072-.108.084-.023.173-.024.26-.03.013-.001.027.018.04.029l.071.065c.019-.11-.082-.198-.024-.31l.126.04c-.026-.123-.07-.245-.071-.366 0-.123.051-.243.115-.36.107.062.16.156.234.253.183.265.36.533.494.834.165-.078.27.068.407.088-.003-.106-.133-.441-.197-.492a.142.142 0 00-.102-.028c-.06.011-.119.039-.191.063-.025-.039-.056-.078-.077-.122a3.936 3.936 0 00-.473-.783c-.076-.094-.16-.182-.228-.26l-.391.285c-.049.035-.094.03-.132-.017l-.169-.207c-.025-.03-.053-.059-.097-.108z"
|
|
671
|
+
]
|
|
672
|
+
};
|
|
673
|
+
function BotGlyph({ className }) {
|
|
674
|
+
return /* @__PURE__ */ jsxs3("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
675
|
+
/* @__PURE__ */ jsx3("path", { d: "M12 8V4H8" }),
|
|
676
|
+
/* @__PURE__ */ jsx3("rect", { width: "16", height: "12", x: "4", y: "8", rx: "2" }),
|
|
677
|
+
/* @__PURE__ */ jsx3("path", { d: "M2 14h2" }),
|
|
678
|
+
/* @__PURE__ */ jsx3("path", { d: "M20 14h2" }),
|
|
679
|
+
/* @__PURE__ */ jsx3("path", { d: "M15 13v2" }),
|
|
680
|
+
/* @__PURE__ */ jsx3("path", { d: "M9 13v2" })
|
|
681
|
+
] });
|
|
682
|
+
}
|
|
683
|
+
function PlugGlyph({ className }) {
|
|
684
|
+
return /* @__PURE__ */ jsxs3("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
685
|
+
/* @__PURE__ */ jsx3("path", { d: "M12 22v-5" }),
|
|
686
|
+
/* @__PURE__ */ jsx3("path", { d: "M15 8V2" }),
|
|
687
|
+
/* @__PURE__ */ jsx3("path", { d: "M17 8a1 1 0 0 1 1 1v4a4 4 0 0 1-4 4h-4a4 4 0 0 1-4-4V9a1 1 0 0 1 1-1z" }),
|
|
688
|
+
/* @__PURE__ */ jsx3("path", { d: "M9 8V2" })
|
|
689
|
+
] });
|
|
690
|
+
}
|
|
691
|
+
function TerminalGlyph({ className }) {
|
|
692
|
+
return /* @__PURE__ */ jsxs3("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
693
|
+
/* @__PURE__ */ jsx3("path", { d: "M12 19h8" }),
|
|
694
|
+
/* @__PURE__ */ jsx3("path", { d: "m4 17 6-6-6-6" })
|
|
695
|
+
] });
|
|
696
|
+
}
|
|
697
|
+
var FALLBACK_GLYPHS = {
|
|
698
|
+
"factory-droids": BotGlyph,
|
|
699
|
+
nanoclaw: PlugGlyph,
|
|
700
|
+
"cli-base": TerminalGlyph
|
|
701
|
+
};
|
|
702
|
+
function HarnessGlyph({ harness, className }) {
|
|
703
|
+
const brand = BRAND_PATHS[harness];
|
|
704
|
+
if (brand) {
|
|
705
|
+
return /* @__PURE__ */ jsx3(
|
|
706
|
+
"svg",
|
|
707
|
+
{
|
|
708
|
+
className,
|
|
709
|
+
viewBox: "0 0 24 24",
|
|
710
|
+
fill: "currentColor",
|
|
711
|
+
fillRule: "evenodd",
|
|
712
|
+
clipRule: "evenodd",
|
|
713
|
+
role: "img",
|
|
714
|
+
"aria-label": harness,
|
|
715
|
+
"data-glyph": harness,
|
|
716
|
+
children: brand.map((d) => /* @__PURE__ */ jsx3("path", { d }, d.slice(0, 32)))
|
|
717
|
+
}
|
|
718
|
+
);
|
|
719
|
+
}
|
|
720
|
+
const Fallback = FALLBACK_GLYPHS[harness] ?? BotGlyph;
|
|
721
|
+
const kind = Fallback === BotGlyph ? "bot" : Fallback === PlugGlyph ? "plug" : "terminal";
|
|
722
|
+
return /* @__PURE__ */ jsx3("span", { role: "img", "aria-label": harness, "data-glyph": kind, className: "inline-flex", children: /* @__PURE__ */ jsx3(Fallback, { className }) });
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// src/web-react/agent-session-controls.tsx
|
|
726
|
+
import { useMemo as useMemo3, useState as useState3 } from "react";
|
|
727
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
728
|
+
var HARNESS_LABELS = {
|
|
729
|
+
opencode: "OpenCode (any model)",
|
|
730
|
+
"claude-code": "Claude Code (Anthropic)",
|
|
731
|
+
codex: "Codex (OpenAI)",
|
|
732
|
+
"kimi-code": "Kimi (Moonshot)",
|
|
733
|
+
amp: "Amp",
|
|
734
|
+
"factory-droids": "Factory Droids",
|
|
735
|
+
cursor: "Cursor",
|
|
736
|
+
hermes: "Hermes",
|
|
737
|
+
forge: "Forge",
|
|
738
|
+
pi: "Pi",
|
|
739
|
+
openclaw: "OpenClaw",
|
|
740
|
+
acp: "ACP",
|
|
741
|
+
"cli-base": "CLI"
|
|
742
|
+
};
|
|
743
|
+
function harnessLabel(h) {
|
|
744
|
+
return HARNESS_LABELS[h] ?? h;
|
|
745
|
+
}
|
|
746
|
+
function ChevronDown2({ className }) {
|
|
747
|
+
return /* @__PURE__ */ jsx4("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx4("path", { d: "m6 9 6 6 6-6" }) });
|
|
748
|
+
}
|
|
749
|
+
function GearGlyph({ className }) {
|
|
750
|
+
return /* @__PURE__ */ jsxs4("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
751
|
+
/* @__PURE__ */ jsx4("circle", { cx: "12", cy: "12", r: "3" }),
|
|
752
|
+
/* @__PURE__ */ jsx4("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" })
|
|
753
|
+
] });
|
|
754
|
+
}
|
|
755
|
+
var FOCUS_RING = "";
|
|
756
|
+
function HarnessPicker({
|
|
757
|
+
value,
|
|
758
|
+
onChange,
|
|
759
|
+
available
|
|
760
|
+
}) {
|
|
761
|
+
const [open, setOpen] = useState3(false);
|
|
762
|
+
const { containerRef, triggerProps } = usePopover(open, setOpen);
|
|
763
|
+
const options = available ?? Object.keys(HARNESS_LABELS);
|
|
764
|
+
return /* @__PURE__ */ jsxs4("div", { ref: containerRef, className: "relative inline-flex", children: [
|
|
765
|
+
/* @__PURE__ */ jsxs4(
|
|
766
|
+
"button",
|
|
767
|
+
{
|
|
768
|
+
type: "button",
|
|
769
|
+
...triggerProps,
|
|
770
|
+
onClick: () => setOpen(!open),
|
|
771
|
+
title: "Agent backend",
|
|
772
|
+
className: `inline-flex w-full items-center justify-between gap-1.5 rounded-lg border border-border bg-card px-3 py-1.5 text-sm font-medium text-foreground transition hover:bg-accent ${FOCUS_RING}`,
|
|
773
|
+
children: [
|
|
774
|
+
/* @__PURE__ */ jsxs4("span", { className: "flex min-w-0 items-center gap-1.5", children: [
|
|
775
|
+
/* @__PURE__ */ jsx4(HarnessGlyph, { harness: value, className: "h-4 w-4 shrink-0 text-foreground" }),
|
|
776
|
+
/* @__PURE__ */ jsx4("span", { className: "truncate", children: harnessLabel(value) })
|
|
777
|
+
] }),
|
|
778
|
+
/* @__PURE__ */ jsx4(ChevronDown2, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" })
|
|
779
|
+
]
|
|
780
|
+
}
|
|
781
|
+
),
|
|
782
|
+
open && /* @__PURE__ */ jsx4("div", { role: "menu", className: `absolute bottom-full left-0 z-50 mb-2 max-h-64 w-full min-w-[248px] overflow-y-auto rounded-xl border border-border bg-popover p-1 ${OVERLAY_SHADOW}`, children: options.map((h) => /* @__PURE__ */ jsxs4(
|
|
783
|
+
"button",
|
|
784
|
+
{
|
|
785
|
+
type: "button",
|
|
786
|
+
role: "menuitemradio",
|
|
787
|
+
"aria-checked": h === value,
|
|
788
|
+
onClick: () => {
|
|
789
|
+
onChange(h);
|
|
790
|
+
setOpen(false);
|
|
791
|
+
},
|
|
792
|
+
className: `flex w-full items-center gap-2.5 rounded-md px-3 py-2 text-left text-sm transition ${FOCUS_RING} ${h === value ? "bg-primary/10 font-medium" : "hover:bg-accent"}`,
|
|
793
|
+
children: [
|
|
794
|
+
/* @__PURE__ */ jsx4(HarnessGlyph, { harness: h, className: "h-4 w-4 shrink-0 text-foreground" }),
|
|
795
|
+
/* @__PURE__ */ jsx4("span", { className: "truncate", children: harnessLabel(h) }),
|
|
796
|
+
h === value && /* @__PURE__ */ jsx4(CheckGlyph, { className: "ml-auto h-3.5 w-3.5 shrink-0 text-primary" })
|
|
797
|
+
]
|
|
798
|
+
},
|
|
799
|
+
h
|
|
800
|
+
)) })
|
|
801
|
+
] });
|
|
802
|
+
}
|
|
803
|
+
function useCoherentHandlers(props) {
|
|
804
|
+
const { model, models, harness, onModelChange, onHarnessChange } = props;
|
|
805
|
+
const canonicalIds = useMemo3(() => models.map((m) => m.id), [models]);
|
|
806
|
+
const onModel = (next) => {
|
|
807
|
+
onModelChange(next);
|
|
808
|
+
const nextHarness = snapHarnessToModel(harness, next);
|
|
809
|
+
if (nextHarness !== harness) onHarnessChange(nextHarness);
|
|
810
|
+
};
|
|
811
|
+
const onHarness = (next) => {
|
|
812
|
+
onHarnessChange(next);
|
|
813
|
+
const snapped = snapModelToHarness(next, model, canonicalIds);
|
|
814
|
+
if (snapped !== model) onModelChange(snapped);
|
|
815
|
+
};
|
|
816
|
+
return { onModel, onHarness };
|
|
817
|
+
}
|
|
818
|
+
function AgentSessionControls(props) {
|
|
819
|
+
const {
|
|
820
|
+
models,
|
|
821
|
+
modelsLoading,
|
|
822
|
+
model,
|
|
823
|
+
harness,
|
|
824
|
+
availableHarnesses,
|
|
825
|
+
effort,
|
|
826
|
+
onEffortChange,
|
|
827
|
+
effortLevels,
|
|
828
|
+
layout = "inline",
|
|
829
|
+
showHarness = true,
|
|
830
|
+
renderProviderBadge,
|
|
831
|
+
className
|
|
832
|
+
} = props;
|
|
833
|
+
const { onModel, onHarness } = useCoherentHandlers(props);
|
|
834
|
+
const [open, setOpen] = useState3(false);
|
|
835
|
+
const { containerRef: popoverRef, triggerProps } = usePopover(open, setOpen);
|
|
836
|
+
const selectedModel = models.find((m) => m.id === model);
|
|
837
|
+
const showEffort = selectedModel?.supportsReasoning ?? true;
|
|
838
|
+
const modelPicker = /* @__PURE__ */ jsx4(
|
|
839
|
+
ModelPicker,
|
|
840
|
+
{
|
|
841
|
+
value: model,
|
|
842
|
+
onChange: onModel,
|
|
843
|
+
models,
|
|
844
|
+
loading: modelsLoading,
|
|
845
|
+
renderProviderBadge
|
|
846
|
+
}
|
|
847
|
+
);
|
|
848
|
+
if (layout === "inline") {
|
|
849
|
+
return /* @__PURE__ */ jsxs4("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
|
|
850
|
+
modelPicker,
|
|
851
|
+
showHarness && /* @__PURE__ */ jsx4(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
|
|
852
|
+
showEffort && /* @__PURE__ */ jsx4(EffortPicker, { value: effort, onChange: onEffortChange, levels: effortLevels })
|
|
853
|
+
] });
|
|
854
|
+
}
|
|
855
|
+
const hasAdvanced = showHarness || showEffort;
|
|
856
|
+
return /* @__PURE__ */ jsxs4("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
|
|
857
|
+
modelPicker,
|
|
858
|
+
hasAdvanced && /* @__PURE__ */ jsxs4("div", { ref: popoverRef, className: "relative inline-flex", children: [
|
|
859
|
+
/* @__PURE__ */ jsx4(
|
|
860
|
+
"button",
|
|
861
|
+
{
|
|
862
|
+
type: "button",
|
|
863
|
+
...triggerProps,
|
|
864
|
+
onClick: () => setOpen(!open),
|
|
865
|
+
title: "Model settings \u2014 pick the agent backend and how hard it thinks",
|
|
866
|
+
className: `flex h-8 w-8 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground data-[state=open]:bg-muted ${FOCUS_RING}`,
|
|
867
|
+
"data-state": open ? "open" : "closed",
|
|
868
|
+
children: /* @__PURE__ */ jsx4(GearGlyph, { className: "h-4 w-4" })
|
|
869
|
+
}
|
|
870
|
+
),
|
|
871
|
+
open && /* @__PURE__ */ jsxs4("div", { className: `absolute bottom-full left-0 z-50 mb-2 w-72 space-y-3 rounded-xl border border-border bg-popover p-3 ${OVERLAY_SHADOW}`, children: [
|
|
872
|
+
showHarness && /* @__PURE__ */ jsxs4("div", { className: "space-y-1.5", children: [
|
|
873
|
+
/* @__PURE__ */ jsx4("p", { className: "text-xs font-medium text-foreground", children: "Agent backend" }),
|
|
874
|
+
/* @__PURE__ */ jsx4(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
|
|
875
|
+
/* @__PURE__ */ jsx4("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "The engine that runs the agent. Switching it keeps your model choice compatible." })
|
|
876
|
+
] }),
|
|
877
|
+
showEffort && /* @__PURE__ */ jsxs4("div", { className: "space-y-1.5", children: [
|
|
878
|
+
/* @__PURE__ */ jsx4("p", { className: "text-xs font-medium text-foreground", children: "Thinking" }),
|
|
879
|
+
/* @__PURE__ */ jsx4(EffortPicker, { value: effort, onChange: onEffortChange, levels: effortLevels, label: "" }),
|
|
880
|
+
/* @__PURE__ */ jsx4("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "How hard the agent thinks before answering. Higher is slower but more thorough." })
|
|
881
|
+
] })
|
|
882
|
+
] })
|
|
883
|
+
] })
|
|
884
|
+
] });
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
export {
|
|
888
|
+
ProviderLogo,
|
|
889
|
+
ChevronDown,
|
|
890
|
+
usePopover,
|
|
891
|
+
POPOVER_OPTION_FOCUS,
|
|
892
|
+
OVERLAY_SHADOW,
|
|
893
|
+
usePending,
|
|
894
|
+
ModelPicker,
|
|
895
|
+
DEFAULT_EFFORT_LEVELS,
|
|
896
|
+
EFFORT_METER_SEGMENTS,
|
|
897
|
+
effortMeterFill,
|
|
898
|
+
EffortMeter,
|
|
899
|
+
EffortPicker,
|
|
900
|
+
useComposerAttachments,
|
|
901
|
+
HarnessGlyph,
|
|
902
|
+
AgentSessionControls
|
|
903
|
+
};
|
|
904
|
+
//# sourceMappingURL=chunk-MIZMWCKW.js.map
|