@cassius0924/dsh-usage-dashboard 0.8.0 → 0.8.1
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/lib/client.js
CHANGED
|
@@ -26,7 +26,7 @@ __export(index_exports, {
|
|
|
26
26
|
name: () => name
|
|
27
27
|
});
|
|
28
28
|
module.exports = __toCommonJS(index_exports);
|
|
29
|
-
var
|
|
29
|
+
var import_react8 = require("react");
|
|
30
30
|
|
|
31
31
|
// src/client/boundary.tsx
|
|
32
32
|
var import_react = require("react");
|
|
@@ -554,6 +554,9 @@ var zh = {
|
|
|
554
554
|
"widget.expandAria": "\u5C55\u5F00\u989D\u5EA6\u7A97\u53E3",
|
|
555
555
|
"widget.collapseAria": "\u6536\u8D77\u989D\u5EA6\u7A97\u53E3",
|
|
556
556
|
"messageCost.label": "\u672C\u8F6E\u8D39\u7528",
|
|
557
|
+
"sessionCost.title": "\u4F1A\u8BDD\u8D39\u7528",
|
|
558
|
+
"sessionCost.aria": "\u672C\u4F1A\u8BDD\u4F30\u7B97\u8D39\u7528 {amount}",
|
|
559
|
+
"sessionCost.active": "\u6D3B\u8DC3\u65F6\u95F4",
|
|
557
560
|
"messageCost.tooltip": "\u7531 dsh-usage-dashboard \u63D0\u4F9B \xB7 \u672C\u8F6E\u5BF9\u8BDD\u8D39\u7528\u4E3A\u4F30\u7B97\u503C",
|
|
558
561
|
"messageCost.aria": "{amount}\uFF0C\u672C\u8F6E\u5BF9\u8BDD\u4F30\u7B97\u8D39\u7528\uFF0C\u7531 dsh-usage-dashboard \u63D0\u4F9B",
|
|
559
562
|
"boundary.title": "\u989D\u5EA6\u9762\u677F\u51FA\u9519\u4E86",
|
|
@@ -822,6 +825,9 @@ var en = {
|
|
|
822
825
|
"widget.expandAria": "Expand balance widget",
|
|
823
826
|
"widget.collapseAria": "Collapse balance widget",
|
|
824
827
|
"messageCost.label": "Turn cost",
|
|
828
|
+
"sessionCost.title": "Session cost",
|
|
829
|
+
"sessionCost.aria": "Estimated session cost {amount}",
|
|
830
|
+
"sessionCost.active": "Active time",
|
|
825
831
|
"messageCost.tooltip": "Provided by dsh-usage-dashboard \xB7 estimated cost for this turn",
|
|
826
832
|
"messageCost.aria": "{amount}, estimated cost for this turn, provided by dsh-usage-dashboard",
|
|
827
833
|
"boundary.title": "The usage dashboard crashed",
|
|
@@ -2894,7 +2900,7 @@ function BalanceDashboard(props) {
|
|
|
2894
2900
|
] })
|
|
2895
2901
|
] })
|
|
2896
2902
|
] }),
|
|
2897
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "dq-footer", children: "@cassius0924/dsh-usage-dashboard v0.8.
|
|
2903
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "dq-footer", children: "@cassius0924/dsh-usage-dashboard v0.8.1" })
|
|
2898
2904
|
] });
|
|
2899
2905
|
}
|
|
2900
2906
|
|
|
@@ -2938,6 +2944,254 @@ function MessageCost({ sessionId, messageId }) {
|
|
|
2938
2944
|
);
|
|
2939
2945
|
}
|
|
2940
2946
|
|
|
2947
|
+
// src/client/session-cost-pill.tsx
|
|
2948
|
+
var import_react6 = require("react");
|
|
2949
|
+
var import_react_dom = require("react-dom");
|
|
2950
|
+
|
|
2951
|
+
// src/pricing.ts
|
|
2952
|
+
var PEAK_PRICING_FROM_MS = Date.UTC(2026, 7, 16, 16, 0, 0);
|
|
2953
|
+
var V41_FLASH_PRICING_FROM_MS = Date.UTC(2026, 8, 10, 4, 0, 0);
|
|
2954
|
+
var PRO_ROUTED_TO_FLASH_FROM_MS = Date.UTC(2026, 8, 14, 4, 0, 0);
|
|
2955
|
+
var PEAK_WINDOWS = [[9, 12], [14, 18]];
|
|
2956
|
+
var BEIJING_OFFSET_MS3 = 8 * 36e5;
|
|
2957
|
+
var FLAT_RATES = {
|
|
2958
|
+
pro: { cacheHit: 0.025, input: 3, output: 6 },
|
|
2959
|
+
flash: { cacheHit: 0.02, input: 1, output: 2 },
|
|
2960
|
+
// The vision model billed at flash rates from day one, so its pre-switch
|
|
2961
|
+
// history is costed at the same flat prices as flash.
|
|
2962
|
+
vision: { cacheHit: 0.02, input: 1, output: 2 }
|
|
2963
|
+
};
|
|
2964
|
+
var PEAK_RATES_08_17 = {
|
|
2965
|
+
pro: { cacheHit: 0.3, input: 9, output: 27 },
|
|
2966
|
+
flash: { cacheHit: 0.1, input: 3, output: 9 },
|
|
2967
|
+
// Official policy: the vision model is priced identically to flash; images
|
|
2968
|
+
// cost tokens, not their own multiplier.
|
|
2969
|
+
vision: { cacheHit: 0.1, input: 3, output: 9 }
|
|
2970
|
+
};
|
|
2971
|
+
var PEAK_RATES_09_10 = {
|
|
2972
|
+
pro: { cacheHit: 0.3, input: 9, output: 27 },
|
|
2973
|
+
flash: { cacheHit: 0.04, input: 2, output: 8 },
|
|
2974
|
+
vision: { cacheHit: 0.04, input: 2, output: 8 }
|
|
2975
|
+
};
|
|
2976
|
+
var PRICE_ERAS = [
|
|
2977
|
+
{ fromMs: PEAK_PRICING_FROM_MS, peak: PEAK_RATES_08_17, weekdaysOnly: false },
|
|
2978
|
+
{ fromMs: V41_FLASH_PRICING_FROM_MS, peak: PEAK_RATES_09_10, weekdaysOnly: true }
|
|
2979
|
+
];
|
|
2980
|
+
function eraAt(timeMs) {
|
|
2981
|
+
let era = PRICE_ERAS[0];
|
|
2982
|
+
for (const candidate of PRICE_ERAS) if (timeMs >= candidate.fromMs) era = candidate;
|
|
2983
|
+
return era;
|
|
2984
|
+
}
|
|
2985
|
+
var halved = (rates) => ({
|
|
2986
|
+
cacheHit: rates.cacheHit / 2,
|
|
2987
|
+
input: rates.input / 2,
|
|
2988
|
+
output: rates.output / 2
|
|
2989
|
+
});
|
|
2990
|
+
function tierOf(model) {
|
|
2991
|
+
const name2 = model.toLowerCase();
|
|
2992
|
+
if (name2.includes("vision")) return "vision";
|
|
2993
|
+
if (name2.includes("flash")) return "flash";
|
|
2994
|
+
return "pro";
|
|
2995
|
+
}
|
|
2996
|
+
function billedTierOf(timeMs, model) {
|
|
2997
|
+
const tier = tierOf(model);
|
|
2998
|
+
return tier === "pro" && timeMs >= PRO_ROUTED_TO_FLASH_FROM_MS ? "flash" : tier;
|
|
2999
|
+
}
|
|
3000
|
+
function isBeijingWeekday(timeMs) {
|
|
3001
|
+
const day = new Date(timeMs + BEIJING_OFFSET_MS3).getUTCDay();
|
|
3002
|
+
return day >= 1 && day <= 5;
|
|
3003
|
+
}
|
|
3004
|
+
function isPeak(timeMs) {
|
|
3005
|
+
if (eraAt(timeMs).weekdaysOnly && !isBeijingWeekday(timeMs)) return false;
|
|
3006
|
+
const hour = Math.floor(((timeMs + BEIJING_OFFSET_MS3) % 864e5 + 864e5) % 864e5 / 36e5);
|
|
3007
|
+
return PEAK_WINDOWS.some(([from, to]) => hour >= from && hour < to);
|
|
3008
|
+
}
|
|
3009
|
+
function ratesAt(timeMs, model) {
|
|
3010
|
+
if (timeMs < PEAK_PRICING_FROM_MS) return FLAT_RATES[tierOf(model)];
|
|
3011
|
+
const peak = eraAt(timeMs).peak[billedTierOf(timeMs, model)];
|
|
3012
|
+
return isPeak(timeMs) ? peak : halved(peak);
|
|
3013
|
+
}
|
|
3014
|
+
|
|
3015
|
+
// src/client/session-cost-pill.tsx
|
|
3016
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
3017
|
+
var PANEL_MARGIN = 12;
|
|
3018
|
+
var PANEL_GAP = 8;
|
|
3019
|
+
var cachedData2 = (sessionId) => {
|
|
3020
|
+
const response = getCachedSessionUsage(sessionId);
|
|
3021
|
+
return response?.ok === true ? response.data ?? null : null;
|
|
3022
|
+
};
|
|
3023
|
+
function CostIcon() {
|
|
3024
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
3025
|
+
"svg",
|
|
3026
|
+
{
|
|
3027
|
+
width: "14",
|
|
3028
|
+
height: "14",
|
|
3029
|
+
viewBox: "0 0 16 16",
|
|
3030
|
+
fill: "none",
|
|
3031
|
+
stroke: "currentColor",
|
|
3032
|
+
strokeWidth: "1",
|
|
3033
|
+
strokeLinecap: "round",
|
|
3034
|
+
strokeLinejoin: "round",
|
|
3035
|
+
"aria-hidden": "true",
|
|
3036
|
+
focusable: "false",
|
|
3037
|
+
children: [
|
|
3038
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "8", cy: "8", r: "6" }),
|
|
3039
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M5.5 5.3 8 8.4l2.5-3.1" }),
|
|
3040
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M8 8.4v2.9" }),
|
|
3041
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M5.8 9.5h4.4" }),
|
|
3042
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M5.8 10.9h4.4" })
|
|
3043
|
+
]
|
|
3044
|
+
}
|
|
3045
|
+
);
|
|
3046
|
+
}
|
|
3047
|
+
function SessionCostPill({ sessionId }) {
|
|
3048
|
+
const { t, locale } = useI18n();
|
|
3049
|
+
const [data, setData] = (0, import_react6.useState)(
|
|
3050
|
+
() => sessionId === void 0 || sessionId === "" ? null : cachedData2(sessionId)
|
|
3051
|
+
);
|
|
3052
|
+
const [open, setOpen] = (0, import_react6.useState)(false);
|
|
3053
|
+
const anchorRef = (0, import_react6.useRef)(null);
|
|
3054
|
+
const panelRef = (0, import_react6.useRef)(null);
|
|
3055
|
+
const [pos, setPos] = (0, import_react6.useState)(null);
|
|
3056
|
+
(0, import_react6.useEffect)(() => {
|
|
3057
|
+
if (sessionId === void 0 || sessionId === "") return;
|
|
3058
|
+
setData(cachedData2(sessionId));
|
|
3059
|
+
const unsubscribe = subscribeSessionUsage(sessionId, () => setData(cachedData2(sessionId)));
|
|
3060
|
+
if (getCachedSessionUsage(sessionId) === null) void fetchSessionUsage(sessionId);
|
|
3061
|
+
return unsubscribe;
|
|
3062
|
+
}, [sessionId]);
|
|
3063
|
+
(0, import_react6.useLayoutEffect)(() => {
|
|
3064
|
+
if (!open) {
|
|
3065
|
+
setPos(null);
|
|
3066
|
+
return;
|
|
3067
|
+
}
|
|
3068
|
+
const anchor = anchorRef.current;
|
|
3069
|
+
const panel = panelRef.current;
|
|
3070
|
+
if (anchor === null || panel === null) return;
|
|
3071
|
+
const pill = anchor.getBoundingClientRect();
|
|
3072
|
+
const width = panel.getBoundingClientRect().width;
|
|
3073
|
+
setPos({
|
|
3074
|
+
left: Math.min(Math.max(pill.left, PANEL_MARGIN), Math.max(PANEL_MARGIN, window.innerWidth - width - PANEL_MARGIN)),
|
|
3075
|
+
bottom: window.innerHeight - pill.top + PANEL_GAP
|
|
3076
|
+
});
|
|
3077
|
+
}, [open, data]);
|
|
3078
|
+
(0, import_react6.useEffect)(() => {
|
|
3079
|
+
if (!open) return;
|
|
3080
|
+
const close = () => setOpen(false);
|
|
3081
|
+
const onPointerDown = (event) => {
|
|
3082
|
+
const target = event.target;
|
|
3083
|
+
if (!(target instanceof Node)) return;
|
|
3084
|
+
if (anchorRef.current?.contains(target) === true || panelRef.current?.contains(target) === true) return;
|
|
3085
|
+
close();
|
|
3086
|
+
};
|
|
3087
|
+
const onKeyDown = (event) => {
|
|
3088
|
+
if (event.key === "Escape") close();
|
|
3089
|
+
};
|
|
3090
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
3091
|
+
document.addEventListener("keydown", onKeyDown);
|
|
3092
|
+
window.addEventListener("resize", close);
|
|
3093
|
+
document.addEventListener("scroll", close, true);
|
|
3094
|
+
return () => {
|
|
3095
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
3096
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
3097
|
+
window.removeEventListener("resize", close);
|
|
3098
|
+
document.removeEventListener("scroll", close, true);
|
|
3099
|
+
};
|
|
3100
|
+
}, [open]);
|
|
3101
|
+
if (sessionId === void 0 || sessionId === "" || data === null || data.calls === 0) return null;
|
|
3102
|
+
const amount = `\xA5${fmtTurnCost(data.cost)}`;
|
|
3103
|
+
const priceAt = data.lastActive ?? Date.now();
|
|
3104
|
+
const split = data.models.reduce(
|
|
3105
|
+
(sum, model) => {
|
|
3106
|
+
const rates = ratesAt(priceAt, model.model);
|
|
3107
|
+
const weighted = {
|
|
3108
|
+
input: model.input * rates.input,
|
|
3109
|
+
cache: model.cache * rates.cacheHit,
|
|
3110
|
+
output: model.output * rates.output
|
|
3111
|
+
};
|
|
3112
|
+
const weight = weighted.input + weighted.cache + weighted.output;
|
|
3113
|
+
if (weight <= 0) return sum;
|
|
3114
|
+
sum.input += model.cost * (weighted.input / weight);
|
|
3115
|
+
sum.cache += model.cost * (weighted.cache / weight);
|
|
3116
|
+
sum.output += model.cost * (weighted.output / weight);
|
|
3117
|
+
return sum;
|
|
3118
|
+
},
|
|
3119
|
+
{ input: 0, cache: 0, output: 0 }
|
|
3120
|
+
);
|
|
3121
|
+
const rangeTime = new Intl.DateTimeFormat(locale === "en" ? "en-US" : "zh-CN", {
|
|
3122
|
+
timeZone: "Asia/Shanghai",
|
|
3123
|
+
month: "numeric",
|
|
3124
|
+
day: "numeric",
|
|
3125
|
+
hour: "2-digit",
|
|
3126
|
+
minute: "2-digit",
|
|
3127
|
+
hour12: false
|
|
3128
|
+
});
|
|
3129
|
+
const range = data.firstActive !== null && data.lastActive !== null ? `${rangeTime.format(data.firstActive)} \u2013 ${rangeTime.format(data.lastActive)}` : null;
|
|
3130
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
3131
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { ref: anchorRef, className: "dq-cost-anchor", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
3132
|
+
"button",
|
|
3133
|
+
{
|
|
3134
|
+
type: "button",
|
|
3135
|
+
className: "dq-cost-pill",
|
|
3136
|
+
"aria-haspopup": "dialog",
|
|
3137
|
+
"aria-expanded": open,
|
|
3138
|
+
"aria-label": t("sessionCost.aria", { amount }),
|
|
3139
|
+
onClick: () => setOpen((value) => !value),
|
|
3140
|
+
children: [
|
|
3141
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CostIcon, {}),
|
|
3142
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dq-cost-pill-label", children: amount })
|
|
3143
|
+
]
|
|
3144
|
+
}
|
|
3145
|
+
) }),
|
|
3146
|
+
open && (0, import_react_dom.createPortal)(
|
|
3147
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
3148
|
+
"div",
|
|
3149
|
+
{
|
|
3150
|
+
ref: panelRef,
|
|
3151
|
+
className: "dq-cost-panel",
|
|
3152
|
+
role: "dialog",
|
|
3153
|
+
"aria-label": t("sessionCost.title"),
|
|
3154
|
+
style: pos === null ? { visibility: "hidden", left: 0, top: 0 } : { visibility: "visible", left: pos.left, bottom: pos.bottom, top: "auto" },
|
|
3155
|
+
children: [
|
|
3156
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dq-cost-panel-title", children: [
|
|
3157
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "dq-cost-panel-title-label", children: [
|
|
3158
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CostIcon, {}),
|
|
3159
|
+
t("sessionCost.title")
|
|
3160
|
+
] }),
|
|
3161
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dq-cost-panel-value", children: amount })
|
|
3162
|
+
] }),
|
|
3163
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "dq-cost-panel-rule", "aria-hidden": true }),
|
|
3164
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("dl", { className: "dq-cost-details", children: [
|
|
3165
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { children: t("common.input") }),
|
|
3166
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("dd", { children: [
|
|
3167
|
+
"\xA5",
|
|
3168
|
+
fmtTurnCost(split.input)
|
|
3169
|
+
] }),
|
|
3170
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { children: t("common.cacheHit") }),
|
|
3171
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("dd", { children: [
|
|
3172
|
+
"\xA5",
|
|
3173
|
+
fmtTurnCost(split.cache)
|
|
3174
|
+
] }),
|
|
3175
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { children: t("common.output") }),
|
|
3176
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("dd", { children: [
|
|
3177
|
+
"\xA5",
|
|
3178
|
+
fmtTurnCost(split.output)
|
|
3179
|
+
] }),
|
|
3180
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { children: t("sessionUsage.calls") }),
|
|
3181
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dd", { children: fmtInt(data.calls) }),
|
|
3182
|
+
range !== null && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
3183
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { children: t("sessionCost.active") }),
|
|
3184
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dd", { children: range })
|
|
3185
|
+
] })
|
|
3186
|
+
] })
|
|
3187
|
+
]
|
|
3188
|
+
}
|
|
3189
|
+
),
|
|
3190
|
+
document.body
|
|
3191
|
+
)
|
|
3192
|
+
] });
|
|
3193
|
+
}
|
|
3194
|
+
|
|
2941
3195
|
// src/client/styles.ts
|
|
2942
3196
|
var css = `
|
|
2943
3197
|
.dsh-quota-root{-webkit-text-size-adjust:100%;text-size-adjust:100%;position:absolute;right:16px;bottom:16px;z-index:2147483000;pointer-events:auto;opacity:1;visibility:visible;font-family:var(--dsw-font-family,-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei","Helvetica Neue",Helvetica,Arial,sans-serif);font-size:13px;line-height:1.45;font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-primary,#1f2328);--dq-text-success:#1a7f37;--dq-text-success:color-mix(in oklab,var(--dsw-alias-state-success-primary,#2da44e) 52%,var(--dsw-alias-label-primary,#1f2328) 48%);--dq-text-warn:#9a6700;--dq-text-warn:color-mix(in oklab,var(--dsw-alias-state-warn-primary,#bf8700) 52%,var(--dsw-alias-label-primary,#1f2328) 48%);transition:left .28s cubic-bezier(.22,1,.36,1),top .28s cubic-bezier(.22,1,.36,1),opacity .16s ease-out,visibility 0s linear}
|
|
@@ -2976,12 +3230,31 @@ var css = `
|
|
|
2976
3230
|
.dq-message-cost-amount{text-decoration-line:underline;text-decoration-style:dotted;text-decoration-color:currentColor;text-underline-offset:4px}
|
|
2977
3231
|
.dq-message-cost:hover{color:var(--dsw-alias-label-secondary,#3f4852)}
|
|
2978
3232
|
.dq-message-cost:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,#0969da);outline-offset:2px;border-radius:4px}
|
|
2979
|
-
.dq-message-cost::after{content:attr(data-dq-tooltip);position:absolute;left:0;
|
|
3233
|
+
.dq-message-cost::after{content:attr(data-dq-tooltip);position:absolute;left:0;bottom:calc(100% + 6px);top:auto;z-index:2147483001;width:max-content;max-width:min(240px,calc(100vw - 24px));padding:6px 9px;border-radius:8px;background:var(--dsw-alias-tooltip-bg,#1f2328);color:var(--dsw-static-neutral-bluish-00,#fff);box-shadow:0 6px 18px rgba(0,0,0,.22);font-size:12px;font-weight:400;line-height:1.5;text-align:left;white-space:normal;pointer-events:none;opacity:0;visibility:hidden;transform:translateY(3px);transition:opacity .12s ease-out,transform .12s cubic-bezier(.22,1,.36,1),visibility 0s linear .12s}
|
|
2980
3234
|
.dq-message-cost:hover::after,.dq-message-cost:focus-visible::after{opacity:1;visibility:visible;transform:translateY(0);transition:opacity .12s ease-out,transform .12s cubic-bezier(.22,1,.36,1),visibility 0s linear}
|
|
2981
3235
|
@media (hover:hover){
|
|
2982
3236
|
[data-time-hover-root] .dq-message-cost{opacity:0;transition:opacity 80ms ease}
|
|
2983
3237
|
[data-time-hover-root]:hover .dq-message-cost,[data-time-hover-root]:focus-within .dq-message-cost{opacity:1}
|
|
2984
3238
|
}
|
|
3239
|
+
/* Composer-dock session cost pill: one more reading beside the host's own
|
|
3240
|
+
\u300C\u4F1A\u8BDD\u7EDF\u8BA1\u300D/\u300CToken \u7528\u91CF\u300Dpills (same slot, same compact skin). */
|
|
3241
|
+
.dq-cost-anchor{display:inline-flex;min-width:0;font-size:calc(var(--dsh-content-font-size-secondary,13px) - 1px);line-height:calc(20px + var(--dsh-content-font-delta-secondary,0px))}
|
|
3242
|
+
.dq-cost-pill{display:inline-flex;align-items:center;gap:6px;box-sizing:border-box;max-width:100%;padding:1px 8px;border:0;border-radius:var(--dsw-radius-sm,8px);background:transparent;color:var(--dsw-alias-label-tertiary,#59636e);font:inherit;font-variant-numeric:tabular-nums;line-height:inherit;white-space:nowrap;cursor:pointer}
|
|
3243
|
+
.dq-cost-pill:hover,.dq-cost-pill[aria-expanded="true"]{background:var(--dsw-alias-interactive-bg-hover,rgba(120,130,150,.12));color:var(--dsw-alias-label-secondary,#59636e)}
|
|
3244
|
+
.dq-cost-pill:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,#0969da);outline-offset:2px}
|
|
3245
|
+
.dq-cost-pill svg{flex:none}
|
|
3246
|
+
.dq-cost-pill-label{min-width:0;overflow:hidden;text-overflow:ellipsis}
|
|
3247
|
+
/* Click-open breakdown: the host stat-dialog skin (menu surface, prominent
|
|
3248
|
+
elevation, 12/18 rows), portaled to the body and placed above the pill. */
|
|
3249
|
+
.dq-cost-panel{position:fixed;z-index:1100;box-sizing:border-box;width:max-content;min-width:min(300px,calc(100vw - 24px));max-width:min(440px,calc(100vw - 24px));padding:16px;border:0;border-radius:var(--dsw-radius-lg,16px);background:var(--dsw-specific-menu,var(--dsw-alias-bg-overlay,#fff));-webkit-backdrop-filter:var(--dsw-menu-backdrop-filter,blur(40px) saturate(150%));backdrop-filter:var(--dsw-menu-backdrop-filter,blur(40px) saturate(150%));box-shadow:var(--dsw-elevation-prominent,0 12px 32px rgba(0,0,0,.24));font-family:var(--dsw-font-family,-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei","Helvetica Neue",Helvetica,Arial,sans-serif);font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary,#59636e);cursor:default}
|
|
3250
|
+
.dq-cost-panel-title{display:flex;justify-content:space-between;gap:16px;margin-bottom:8px;color:var(--dsw-alias-label-primary,#1f2328);font-weight:500}
|
|
3251
|
+
.dq-cost-panel-title-label{display:inline-flex;align-items:center;gap:6px;min-width:0}
|
|
3252
|
+
.dq-cost-panel-title-label svg{flex:none}
|
|
3253
|
+
.dq-cost-panel-value{font-variant-numeric:tabular-nums}
|
|
3254
|
+
.dq-cost-panel-rule{margin-bottom:10px;border-top:.5px solid var(--dsw-alias-border-l2,rgba(0,0,0,.1))}
|
|
3255
|
+
.dq-cost-details{display:grid;grid-template-columns:minmax(76px,auto) minmax(0,1fr);gap:6px 16px;margin:0;color:var(--dsw-alias-label-tertiary,#59636e)}
|
|
3256
|
+
.dq-cost-details dt,.dq-cost-details dd{min-width:0;margin:0}
|
|
3257
|
+
.dq-cost-details dd{color:var(--dsw-alias-label-secondary,#59636e);font-variant-numeric:tabular-nums;text-align:right}
|
|
2985
3258
|
/* \u5361\u7247\u95F4\u8DDD\uFF08\u6B64\u5904 gap\uFF09\u523B\u610F\u5927\u4E8E\u5361\u5185\u5C0F\u8282\u95F4\u8DDD\uFF08margin-top:12/14/16px \u90A3\u4E00\u6863\uFF09\uFF0C\u5236\u9020"\u5361\u7247\u5916\u758F\u3001\u5361\u7247\u5185\u5BC6"\u7684
|
|
2986
3259
|
\u758F\u5BC6\u5BF9\u6BD4\uFF1A24px \u76F8\u5BF9\u5361\u5185\u6700\u5927\u6863 16px \u4ECD\u6709 1.5 \u500D\u7EA7\u5DEE\uFF0C\u76F8\u5BF9\u5E38\u89C1\u6863 12px \u6709 2 \u500D\u7EA7\u5DEE\uFF0C\u4E0D\u4E0E .dq-card \u7684
|
|
2987
3260
|
padding\uFF0816px/20px\uFF0C\u5361\u7247\u5185\u90E8\u547C\u5438\u611F\uFF0C\u8F6E\u6B21 36 \u5DF2\u5B9A\uFF09\u6DF7\u540C\u3002 */
|
|
@@ -3449,7 +3722,7 @@ html[data-dq-quota-view] .dq-balance{padding-bottom:48px}
|
|
|
3449
3722
|
`;
|
|
3450
3723
|
|
|
3451
3724
|
// src/client/widget.tsx
|
|
3452
|
-
var
|
|
3725
|
+
var import_react7 = require("react");
|
|
3453
3726
|
|
|
3454
3727
|
// src/client/sessions.ts
|
|
3455
3728
|
function currentSessionIdOf(state) {
|
|
@@ -3458,7 +3731,7 @@ function currentSessionIdOf(state) {
|
|
|
3458
3731
|
}
|
|
3459
3732
|
|
|
3460
3733
|
// src/client/widget.tsx
|
|
3461
|
-
var
|
|
3734
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
3462
3735
|
var MARGIN = 16;
|
|
3463
3736
|
var CORNER_KEY = "widget.corner";
|
|
3464
3737
|
var COLLAPSED_KEY = "widget.collapsed";
|
|
@@ -3509,47 +3782,47 @@ function cornerPos(corner, node, bounds) {
|
|
|
3509
3782
|
function QuotaWidget(props) {
|
|
3510
3783
|
const { t } = useI18n();
|
|
3511
3784
|
const sessionId = props.useSessions(currentSessionIdOf);
|
|
3512
|
-
const [visible, setVisible] = (0,
|
|
3513
|
-
(0,
|
|
3514
|
-
const [quotaViewActive2, setQuotaViewActive] = (0,
|
|
3515
|
-
(0,
|
|
3516
|
-
const [lowBalance, setLowBalance] = (0,
|
|
3517
|
-
(0,
|
|
3518
|
-
const [selectedTabIds, setSelectedTabIds] = (0,
|
|
3519
|
-
(0,
|
|
3520
|
-
const [viewTabs, setViewTabs] = (0,
|
|
3521
|
-
(0,
|
|
3522
|
-
const [activeViewId, setActiveViewId] = (0,
|
|
3785
|
+
const [visible, setVisible] = (0, import_react7.useState)(widgetVisibleStore.get());
|
|
3786
|
+
(0, import_react7.useEffect)(() => widgetVisibleStore.subscribe(() => setVisible(widgetVisibleStore.get())), []);
|
|
3787
|
+
const [quotaViewActive2, setQuotaViewActive] = (0, import_react7.useState)(quotaViewActiveStore.get());
|
|
3788
|
+
(0, import_react7.useEffect)(() => quotaViewActiveStore.subscribe(() => setQuotaViewActive(quotaViewActiveStore.get())), []);
|
|
3789
|
+
const [lowBalance, setLowBalance] = (0, import_react7.useState)(lowBalanceStore.get());
|
|
3790
|
+
(0, import_react7.useEffect)(() => lowBalanceStore.subscribe(() => setLowBalance(lowBalanceStore.get())), []);
|
|
3791
|
+
const [selectedTabIds, setSelectedTabIds] = (0, import_react7.useState)(widgetTabIdsStore.get());
|
|
3792
|
+
(0, import_react7.useEffect)(() => widgetTabIdsStore.subscribe(() => setSelectedTabIds(widgetTabIdsStore.get())), []);
|
|
3793
|
+
const [viewTabs, setViewTabs] = (0, import_react7.useState)(() => props.views.list());
|
|
3794
|
+
(0, import_react7.useEffect)(() => props.views.subscribe(() => setViewTabs(props.views.list())), [props.views]);
|
|
3795
|
+
const [activeViewId, setActiveViewId] = (0, import_react7.useState)(null);
|
|
3523
3796
|
const cachedBalance = getCachedBalance();
|
|
3524
|
-
const [data, setData] = (0,
|
|
3525
|
-
const [error, setError] = (0,
|
|
3526
|
-
const [loading, setLoading] = (0,
|
|
3527
|
-
const [collapsed, setCollapsed] = (0,
|
|
3528
|
-
const [pos, setPos] = (0,
|
|
3529
|
-
const [corner, setCorner] = (0,
|
|
3530
|
-
const [dragging, setDragging] = (0,
|
|
3531
|
-
const rootRef = (0,
|
|
3532
|
-
const dragRef = (0,
|
|
3797
|
+
const [data, setData] = (0, import_react7.useState)(cachedBalance?.data ?? null);
|
|
3798
|
+
const [error, setError] = (0, import_react7.useState)(null);
|
|
3799
|
+
const [loading, setLoading] = (0, import_react7.useState)(cachedBalance === null);
|
|
3800
|
+
const [collapsed, setCollapsed] = (0, import_react7.useState)(() => loadPref(COLLAPSED_KEY, isBoolean, false));
|
|
3801
|
+
const [pos, setPos] = (0, import_react7.useState)(null);
|
|
3802
|
+
const [corner, setCorner] = (0, import_react7.useState)(() => loadPref(CORNER_KEY, isCorner, "br"));
|
|
3803
|
+
const [dragging, setDragging] = (0, import_react7.useState)(false);
|
|
3804
|
+
const rootRef = (0, import_react7.useRef)(null);
|
|
3805
|
+
const dragRef = (0, import_react7.useRef)(null);
|
|
3533
3806
|
const readUsage = () => {
|
|
3534
3807
|
const cached = getCachedUsage();
|
|
3535
3808
|
return { data: cached?.ok === true ? cached.data ?? null : null, at: getCachedUsageAt() };
|
|
3536
3809
|
};
|
|
3537
|
-
const [usage, setUsage] = (0,
|
|
3538
|
-
(0,
|
|
3810
|
+
const [usage, setUsage] = (0, import_react7.useState)(readUsage);
|
|
3811
|
+
(0, import_react7.useEffect)(() => subscribeUsage(() => setUsage(readUsage())), []);
|
|
3539
3812
|
const readSessionUsage = (id) => {
|
|
3540
3813
|
if (id === void 0) return null;
|
|
3541
3814
|
const response = getCachedSessionUsage(id);
|
|
3542
3815
|
return response?.ok === true ? response.data ?? null : null;
|
|
3543
3816
|
};
|
|
3544
|
-
const [sessionUsage, setSessionUsage] = (0,
|
|
3545
|
-
(0,
|
|
3817
|
+
const [sessionUsage, setSessionUsage] = (0, import_react7.useState)(() => readSessionUsage(sessionId));
|
|
3818
|
+
(0, import_react7.useEffect)(() => {
|
|
3546
3819
|
setSessionUsage(readSessionUsage(sessionId));
|
|
3547
3820
|
if (sessionId === void 0) return;
|
|
3548
3821
|
const unsubscribe = subscribeSessionUsage(sessionId, () => setSessionUsage(readSessionUsage(sessionId)));
|
|
3549
3822
|
void fetchSessionUsage(sessionId);
|
|
3550
3823
|
return unsubscribe;
|
|
3551
3824
|
}, [sessionId]);
|
|
3552
|
-
(0,
|
|
3825
|
+
(0, import_react7.useLayoutEffect)(() => {
|
|
3553
3826
|
const viewIds = viewTabs.map((tab) => tab.id);
|
|
3554
3827
|
const read = () => {
|
|
3555
3828
|
const next = getActiveConversationViewId(getShellFrame(rootRef.current), viewIds);
|
|
@@ -3586,14 +3859,14 @@ function QuotaWidget(props) {
|
|
|
3586
3859
|
setLoading(false);
|
|
3587
3860
|
}
|
|
3588
3861
|
};
|
|
3589
|
-
(0,
|
|
3862
|
+
(0, import_react7.useEffect)(() => {
|
|
3590
3863
|
void load(true);
|
|
3591
3864
|
const id = setInterval(() => {
|
|
3592
3865
|
void load(false);
|
|
3593
3866
|
}, 6e4);
|
|
3594
3867
|
return () => clearInterval(id);
|
|
3595
3868
|
}, []);
|
|
3596
|
-
(0,
|
|
3869
|
+
(0, import_react7.useLayoutEffect)(() => {
|
|
3597
3870
|
if (!visible || quotaViewActive2) return;
|
|
3598
3871
|
const node = rootRef.current;
|
|
3599
3872
|
if (node === null) return;
|
|
@@ -3721,9 +3994,9 @@ function QuotaWidget(props) {
|
|
|
3721
3994
|
const dotClass = primary === null ? "dsh-quota-dot dsh-quota-dot--idle" : data?.isAvailable === false ? "dsh-quota-dot dsh-quota-dot--error" : low ? "dsh-quota-dot dsh-quota-dot--warn" : "dsh-quota-dot";
|
|
3722
3995
|
const ageMinutes = usage.at === null ? null : Math.floor((Date.now() - usage.at) / 6e4);
|
|
3723
3996
|
const usageAgeText = ageMinutes === null || ageMinutes < 1 ? t("widget.updatedNow") : t("widget.stale", { minutes: ageMinutes });
|
|
3724
|
-
const sessionCostRow = sessionUsage === null ? null : /* @__PURE__ */ (0,
|
|
3725
|
-
/* @__PURE__ */ (0,
|
|
3726
|
-
/* @__PURE__ */ (0,
|
|
3997
|
+
const sessionCostRow = sessionUsage === null ? null : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-quota-row", title: t("widget.sessionCostTitle"), children: [
|
|
3998
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-quota-label", children: t("widget.sessionCost") }),
|
|
3999
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "dsh-quota-value", children: [
|
|
3727
4000
|
"\xA5",
|
|
3728
4001
|
fmtTurnCost(sessionUsage.cost)
|
|
3729
4002
|
] })
|
|
@@ -3731,50 +4004,50 @@ function QuotaWidget(props) {
|
|
|
3731
4004
|
let body = null;
|
|
3732
4005
|
if (!collapsed) {
|
|
3733
4006
|
if (loading && data === null && error === null) {
|
|
3734
|
-
body = /* @__PURE__ */ (0,
|
|
3735
|
-
/* @__PURE__ */ (0,
|
|
4007
|
+
body = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-quota-body", children: [
|
|
4008
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { children: t("widget.loading") }),
|
|
3736
4009
|
sessionCostRow
|
|
3737
4010
|
] });
|
|
3738
4011
|
} else if (error !== null && data === null) {
|
|
3739
|
-
body = /* @__PURE__ */ (0,
|
|
3740
|
-
/* @__PURE__ */ (0,
|
|
4012
|
+
body = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-quota-body", children: [
|
|
4013
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-quota-error", children: localizeApiError(error, t, "error.query") }),
|
|
3741
4014
|
sessionCostRow
|
|
3742
4015
|
] });
|
|
3743
4016
|
} else if (primary !== null) {
|
|
3744
|
-
body = /* @__PURE__ */ (0,
|
|
3745
|
-
/* @__PURE__ */ (0,
|
|
3746
|
-
/* @__PURE__ */ (0,
|
|
3747
|
-
/* @__PURE__ */ (0,
|
|
3748
|
-
/* @__PURE__ */ (0,
|
|
4017
|
+
body = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-quota-body", children: [
|
|
4018
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-quota-remaining-label", children: t("balance.remaining") }),
|
|
4019
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { title: low ? t("widget.lowTitle", { amount: fmt(lowBalance) }) : void 0, children: [
|
|
4020
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: `dsh-quota-total${low ? " dsh-quota-total--low" : ""}`, children: fmt(primary.total) }),
|
|
4021
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-quota-currency", children: primary.currency })
|
|
3749
4022
|
] }),
|
|
3750
|
-
usage.data !== null && /* @__PURE__ */ (0,
|
|
3751
|
-
/* @__PURE__ */ (0,
|
|
3752
|
-
/* @__PURE__ */ (0,
|
|
4023
|
+
usage.data !== null && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-quota-row", title: t("widget.todayCostTitle", { age: usageAgeText }), children: [
|
|
4024
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-quota-label", children: t("widget.todayCost") }),
|
|
4025
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "dsh-quota-value", children: [
|
|
3753
4026
|
"\xA5",
|
|
3754
4027
|
fmt(usage.data.summary.today.cost)
|
|
3755
4028
|
] })
|
|
3756
4029
|
] }),
|
|
3757
4030
|
sessionCostRow,
|
|
3758
|
-
data?.isAvailable === false && /* @__PURE__ */ (0,
|
|
3759
|
-
/* @__PURE__ */ (0,
|
|
3760
|
-
/* @__PURE__ */ (0,
|
|
4031
|
+
data?.isAvailable === false && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-quota-row", children: [
|
|
4032
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-quota-label", children: t("common.status") }),
|
|
4033
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-quota-value dsh-quota-error", children: t("common.unavailable") })
|
|
3761
4034
|
] })
|
|
3762
4035
|
] });
|
|
3763
4036
|
} else {
|
|
3764
|
-
body = /* @__PURE__ */ (0,
|
|
3765
|
-
/* @__PURE__ */ (0,
|
|
4037
|
+
body = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-quota-body", children: [
|
|
4038
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-quota-error", children: t("widget.noBalance") }),
|
|
3766
4039
|
sessionCostRow
|
|
3767
4040
|
] });
|
|
3768
4041
|
}
|
|
3769
4042
|
}
|
|
3770
4043
|
const style = pos !== null ? { left: `${pos.x}px`, top: `${pos.y}px`, right: "auto", bottom: "auto" } : void 0;
|
|
3771
|
-
return /* @__PURE__ */ (0,
|
|
4044
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3772
4045
|
"div",
|
|
3773
4046
|
{
|
|
3774
4047
|
className: `dsh-quota-root${dragging ? " dsh-quota-dragging" : ""}${hidden ? " dsh-quota-root--hidden" : ""}`,
|
|
3775
4048
|
style,
|
|
3776
4049
|
"aria-hidden": hidden,
|
|
3777
|
-
children: /* @__PURE__ */ (0,
|
|
4050
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
3778
4051
|
"div",
|
|
3779
4052
|
{
|
|
3780
4053
|
ref: rootRef,
|
|
@@ -3786,14 +4059,14 @@ function QuotaWidget(props) {
|
|
|
3786
4059
|
onPointerCancel: () => endDrag(false),
|
|
3787
4060
|
onLostPointerCapture: () => endDrag(false),
|
|
3788
4061
|
children: [
|
|
3789
|
-
/* @__PURE__ */ (0,
|
|
3790
|
-
/* @__PURE__ */ (0,
|
|
3791
|
-
/* @__PURE__ */ (0,
|
|
3792
|
-
/* @__PURE__ */ (0,
|
|
3793
|
-
/* @__PURE__ */ (0,
|
|
4062
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-quota-header", children: [
|
|
4063
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-quota-title", children: [
|
|
4064
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-quota-grip", title: t("widget.dragGrip"), children: "\u2807" }),
|
|
4065
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: dotClass }),
|
|
4066
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dsh-quota-name", children: t("widget.title") })
|
|
3794
4067
|
] }),
|
|
3795
|
-
/* @__PURE__ */ (0,
|
|
3796
|
-
/* @__PURE__ */ (0,
|
|
4068
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dsh-quota-actions", children: [
|
|
4069
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3797
4070
|
"button",
|
|
3798
4071
|
{
|
|
3799
4072
|
className: "dsh-quota-btn",
|
|
@@ -3809,7 +4082,7 @@ function QuotaWidget(props) {
|
|
|
3809
4082
|
children: "\u21BB"
|
|
3810
4083
|
}
|
|
3811
4084
|
),
|
|
3812
|
-
/* @__PURE__ */ (0,
|
|
4085
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3813
4086
|
"button",
|
|
3814
4087
|
{
|
|
3815
4088
|
className: "dsh-quota-btn",
|
|
@@ -3827,7 +4100,7 @@ function QuotaWidget(props) {
|
|
|
3827
4100
|
)
|
|
3828
4101
|
] })
|
|
3829
4102
|
] }),
|
|
3830
|
-
collapsed && primary !== null && /* @__PURE__ */ (0,
|
|
4103
|
+
collapsed && primary !== null && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "dsh-quota-collapsed-total-row", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: `dsh-quota-collapsed-total${low ? " dsh-quota-total--low" : ""}`, children: [
|
|
3831
4104
|
fmt(primary.total),
|
|
3832
4105
|
" ",
|
|
3833
4106
|
primary.currency
|
|
@@ -3858,7 +4131,7 @@ function conversationViewsSource(slots) {
|
|
|
3858
4131
|
}
|
|
3859
4132
|
|
|
3860
4133
|
// src/client/index.tsx
|
|
3861
|
-
var
|
|
4134
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
3862
4135
|
var name = "dsh-usage-dashboard";
|
|
3863
4136
|
var inject = ["slots", "locale", "layout"];
|
|
3864
4137
|
var openQuotaTab = null;
|
|
@@ -3879,7 +4152,11 @@ function apply(ctx) {
|
|
|
3879
4152
|
});
|
|
3880
4153
|
ctx.slots.inject("shell.overlay", () => ctx.slots.register(
|
|
3881
4154
|
{ name: "shell.overlay", id: "deepseek-quota", order: 1e3, locale: NS, label: () => t("widget.title") },
|
|
3882
|
-
({ t: slotT, useSessions }) => /* @__PURE__ */ (0,
|
|
4155
|
+
({ t: slotT, useSessions }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LocaleProvider, { t: slotT, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ErrorBoundary, { t: slotT, silent: true, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(QuotaWidget, { useSessions, views }) }) })
|
|
4156
|
+
));
|
|
4157
|
+
ctx.slots.inject("conversation.composer.dock", () => ctx.slots.register(
|
|
4158
|
+
{ name: "conversation.composer.dock", id: "quota-cost", order: 2, locale: NS },
|
|
4159
|
+
({ t: slotT, sessionId }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LocaleProvider, { t: slotT, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ErrorBoundary, { t: slotT, silent: true, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SessionCostPill, { sessionId }) }) })
|
|
3883
4160
|
));
|
|
3884
4161
|
ctx.slots.inject("conversation.chat.assistant-actions", () => ctx.slots.register(
|
|
3885
4162
|
{
|
|
@@ -3889,13 +4166,13 @@ function apply(ctx) {
|
|
|
3889
4166
|
locale: NS,
|
|
3890
4167
|
label: () => t("messageCost.label")
|
|
3891
4168
|
},
|
|
3892
|
-
({ t: slotT, sessionId, messageId }) => /* @__PURE__ */ (0,
|
|
4169
|
+
({ t: slotT, sessionId, messageId }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LocaleProvider, { t: slotT, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ErrorBoundary, { t: slotT, silent: true, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(MessageCost, { sessionId, messageId }) }) })
|
|
3893
4170
|
));
|
|
3894
4171
|
const QuotaView = ({ t: slotT, sessionId, openView }) => {
|
|
3895
|
-
(0,
|
|
4172
|
+
(0, import_react8.useEffect)(() => {
|
|
3896
4173
|
if (openView !== void 0) openQuotaTab = openView;
|
|
3897
4174
|
}, [openView]);
|
|
3898
|
-
return /* @__PURE__ */ (0,
|
|
4175
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LocaleProvider, { t: slotT, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ErrorBoundary, { t: slotT, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(BalanceDashboard, { sessionId, views }) }) });
|
|
3899
4176
|
};
|
|
3900
4177
|
ctx.effect(() => {
|
|
3901
4178
|
let disposeView = null;
|
|
@@ -3931,14 +4208,14 @@ function apply(ctx) {
|
|
|
3931
4208
|
disposeView?.();
|
|
3932
4209
|
};
|
|
3933
4210
|
}, "dsh-usage-dashboard: quota tab registration");
|
|
3934
|
-
const QuotaPanel = ({ t: slotT }) => /* @__PURE__ */ (0,
|
|
3935
|
-
/* @__PURE__ */ (0,
|
|
3936
|
-
/* @__PURE__ */ (0,
|
|
3937
|
-
/* @__PURE__ */ (0,
|
|
4211
|
+
const QuotaPanel = ({ t: slotT }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "dq-panel", children: [
|
|
4212
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "dq-panel-head", "data-window-drag": true, children: [
|
|
4213
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h1", { className: "dq-panel-title", children: slotT("nav.quota") }),
|
|
4214
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "dq-panel-caption", children: slotT("panel.caption") })
|
|
3938
4215
|
] }),
|
|
3939
|
-
/* @__PURE__ */ (0,
|
|
4216
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LocaleProvider, { t: slotT, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ErrorBoundary, { t: slotT, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(BalanceDashboard, { views }) }) })
|
|
3940
4217
|
] });
|
|
3941
|
-
const QuotaGlyph = ({ size, active }) => /* @__PURE__ */ (0,
|
|
4218
|
+
const QuotaGlyph = ({ size, active }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3942
4219
|
"svg",
|
|
3943
4220
|
{
|
|
3944
4221
|
className: "dq-side-icon",
|
|
@@ -3954,23 +4231,23 @@ function apply(ctx) {
|
|
|
3954
4231
|
"aria-hidden": "true",
|
|
3955
4232
|
focusable: "false",
|
|
3956
4233
|
children: [
|
|
3957
|
-
/* @__PURE__ */ (0,
|
|
3958
|
-
/* @__PURE__ */ (0,
|
|
3959
|
-
/* @__PURE__ */ (0,
|
|
3960
|
-
/* @__PURE__ */ (0,
|
|
4234
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M3.5 3.3 8 8.7l4.5-5.4" }),
|
|
4235
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M8 8.7V13.2" }),
|
|
4236
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M3.5 10.2h9" }),
|
|
4237
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M3.5 12.1h9" })
|
|
3961
4238
|
]
|
|
3962
4239
|
}
|
|
3963
4240
|
);
|
|
3964
4241
|
const QuotaFooterButton = ({ wide, t: slotT }) => {
|
|
3965
|
-
const [active, setActive] = (0,
|
|
3966
|
-
(0,
|
|
4242
|
+
const [active, setActive] = (0, import_react8.useState)(() => ctx.layout.panelInfo.getSnapshot().activePanelId === QUOTA_PANEL_ID);
|
|
4243
|
+
(0, import_react8.useEffect)(() => {
|
|
3967
4244
|
const sync = () => {
|
|
3968
4245
|
setActive(ctx.layout.panelInfo.getSnapshot().activePanelId === QUOTA_PANEL_ID);
|
|
3969
4246
|
};
|
|
3970
4247
|
sync();
|
|
3971
4248
|
return ctx.layout.panelInfo.subscribe(sync);
|
|
3972
4249
|
}, []);
|
|
3973
|
-
return /* @__PURE__ */ (0,
|
|
4250
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3974
4251
|
"button",
|
|
3975
4252
|
{
|
|
3976
4253
|
type: "button",
|
|
@@ -3982,8 +4259,8 @@ function apply(ctx) {
|
|
|
3982
4259
|
ctx.layout.selectPanel(active ? null : QUOTA_PANEL_ID);
|
|
3983
4260
|
},
|
|
3984
4261
|
children: [
|
|
3985
|
-
/* @__PURE__ */ (0,
|
|
3986
|
-
wide && /* @__PURE__ */ (0,
|
|
4262
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "dq-side-entry-icon", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(QuotaGlyph, { size: 16 }) }),
|
|
4263
|
+
wide && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "dq-side-entry-label", children: slotT("nav.quota") })
|
|
3987
4264
|
]
|
|
3988
4265
|
}
|
|
3989
4266
|
);
|