window.__ModuleLoader__.load({ id: "dsh-plugin-model-enhancer", factory: (require) => { var module = { exports: {} }; var exports = module.exports; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name2 in all) __defProp(target, name2, { get: all[name2], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/client/index.ts var index_exports = {}; __export(index_exports, { apply: () => apply, inject: () => inject, name: () => name }); module.exports = __toCommonJS(index_exports); // src/client/styles.ts var CODEX_LEVELS_ZH = [ { id: "off", label: "\u5173", short: "\u5173" }, { id: "minimal", label: "\u6781\u4F4E", short: "\u6781\u4F4E" }, { id: "low", label: "\u4F4E", short: "\u4F4E" }, { id: "medium", label: "\u4E2D", short: "\u4E2D" }, { id: "high", label: "\u9AD8", short: "\u9AD8" }, { id: "xhigh", label: "\u8D85\u9AD8", short: "\u8D85\u9AD8" }, { id: "max", label: "\u6700\u5927", short: "\u6700\u5927" } ]; var CODEX_LEVELS_EN = [ { id: "off", label: "Off", short: "Off" }, { id: "minimal", label: "Minimal", short: "Minimal" }, { id: "low", label: "Low", short: "Low" }, { id: "medium", label: "Medium", short: "Medium" }, { id: "high", label: "High", short: "High" }, { id: "xhigh", label: "X-High", short: "X-High" }, { id: "max", label: "Max", short: "Max" } ]; var ENHANCER_CSS = ` /* Hide default trigger when Codex trigger is active */ div[class*="_7KE1Ra_root"], div[class*="ModelSelect_module_css_root"] { display: none !important; } .me-codex-trigger { box-sizing: border-box; height: 28px; padding: 0 8px; border-radius: 14px; border: 1px solid transparent; background: transparent; color: var(--dsw-alias-label-secondary, #61666b); font-size: 13px; font-weight: 500; display: inline-flex; align-items: center; gap: 4px; cursor: pointer; outline: none; transition: all 120ms ease; user-select: none; } .me-codex-trigger:hover:not(:disabled), .me-codex-trigger.active-open { border-color: var(--dsw-alias-border-l2, rgba(0, 0, 0, 0.15)); color: var(--dsw-alias-label-primary, #0f1115); } body[data-ds-dark-theme] .me-codex-trigger:hover:not(:disabled), body[data-ds-dark-theme] .me-codex-trigger.active-open { border-color: var(--dsw-alias-border-l3, rgba(255, 255, 255, 0.2)); color: var(--dsw-alias-label-primary, #fff); } .me-codex-trigger-chevron { transition: transform 140ms ease; opacity: 0.7; } .me-codex-trigger-chevron.open { transform: rotate(180deg); } .me-codex-popup { position: absolute; bottom: calc(100% + 8px); right: 0; width: 280px; background: var(--dsw-specific-menu, #ffffff); border: 1px solid var(--dsw-alias-border-l2, rgba(0, 0, 0, 0.08)); box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.06); border-radius: 14px; padding: 10px 12px 12px; z-index: 1200; display: flex; flex-direction: column; gap: 8px; } body[data-ds-dark-theme] .me-codex-popup { background: var(--dsw-specific-menu, #1b1d22); border-color: var(--dsw-alias-border-l3, rgba(255, 255, 255, 0.1)); box-shadow: 0 10px 36px rgba(0, 0, 0, 0.5), 0 2px 10px rgba(0, 0, 0, 0.3); } .me-codex-topbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; } .me-codex-icon-btn { box-sizing: border-box; width: 26px; height: 26px; border-radius: 6px; border: none; background: transparent; color: var(--dsw-alias-label-secondary, #64748b); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; padding: 0; } .me-codex-icon-btn:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(0, 0, 0, 0.05)); color: var(--dsw-alias-label-primary, #0f172a); } body[data-ds-dark-theme] .me-codex-icon-btn { color: var(--dsw-alias-label-secondary, #94a3b8); } body[data-ds-dark-theme] .me-codex-icon-btn:hover { background: var(--dsw-alias-surface-l2, rgba(255, 255, 255, 0.08)); color: #fff; } .me-codex-center { flex: 1; display: flex; flex-direction: column; align-items: center; cursor: pointer; user-select: none; } .me-codex-effort-title { font-size: 13px; font-weight: 600; color: var(--dsw-alias-label-primary, #0f172a); display: flex; align-items: center; gap: 3px; } body[data-ds-dark-theme] .me-codex-effort-title { color: #fff; } .me-codex-model-name { font-size: 11px; color: var(--dsw-alias-label-tertiary, #64748b); white-space: nowrap; max-width: 170px; overflow: hidden; text-overflow: ellipsis; } .me-codex-model-name:hover { color: #2563eb; } body[data-ds-dark-theme] .me-codex-model-name { color: var(--dsw-alias-label-tertiary, #94a3b8); } body[data-ds-dark-theme] .me-codex-model-name:hover { color: #60a5fa; } .me-slider-track-wrap { box-sizing: border-box; padding: 4px 0 2px; cursor: pointer; user-select: none; } .me-slider-track { position: relative; height: 8px; background: var(--dsw-alias-border-l2, rgba(0, 0, 0, 0.08)); border-radius: 4px; display: flex; align-items: center; } body[data-ds-dark-theme] .me-slider-track { background: var(--dsw-alias-border-l3, rgba(255, 255, 255, 0.12)); } .me-slider-active-fill { position: absolute; left: 0; height: 100%; border-radius: 4px; background: #3b82f6; pointer-events: none; transition: width 120ms ease; } .me-slider-dots-layer { position: absolute; top: 0; left: 0; right: 0; bottom: 0; display: flex; justify-content: space-between; align-items: center; padding: 0 14px; pointer-events: none; } .me-slider-dot { width: 4px; height: 4px; border-radius: 50%; background: var(--dsw-alias-border-l3, rgba(0, 0, 0, 0.2)); } body[data-ds-dark-theme] .me-slider-dot { background: rgba(255, 255, 255, 0.25); } .me-slider-dot.lit { background: #fff; } .me-slider-thumb { position: absolute; top: 50%; transform: translate(-50%, -50%); width: 16px; height: 16px; border-radius: 50%; background: #ffffff; border: 2px solid #3b82f6; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); pointer-events: none; transition: left 120ms ease; } body[data-ds-dark-theme] .me-slider-thumb { background: #1e293b; border-color: #60a5fa; } .me-model-picker-list { max-height: 210px; overflow-y: auto; padding-right: 2px; } .me-model-group-section { margin-top: 8px; padding-top: 6px; border-top: 1px solid var(--dsw-alias-border-l2, rgba(0, 0, 0, 0.08)); } .me-model-group-section:first-child { margin-top: 0; padding-top: 0; border-top: none; } .me-model-picker-group { font-size: 11px; color: #2563eb; font-weight: 600; padding: 3px 6px; text-transform: uppercase; letter-spacing: 0.05em; display: inline-flex; align-items: center; gap: 4px; background: rgba(37, 99, 235, 0.08); border-radius: 4px; margin-bottom: 4px; } body[data-ds-dark-theme] .me-model-picker-group { color: #60a5fa; background: rgba(59, 130, 246, 0.08); } .me-model-picker-item { box-sizing: border-box; width: 100%; padding: 6px 8px; border-radius: 6px; background: transparent; border: none; color: var(--dsw-alias-label-primary, #0f1115); font-size: 13px; text-align: left; cursor: pointer; display: flex; align-items: center; justify-content: space-between; transition: all 120ms ease; } .me-model-picker-item:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(0, 0, 0, 0.05)); } .me-model-picker-item.active { background: rgba(37, 99, 235, 0.1); color: #2563eb; font-weight: 500; } body[data-ds-dark-theme] .me-model-picker-item { color: var(--dsw-alias-label-primary, #e2e8f0); } body[data-ds-dark-theme] .me-model-picker-item:hover { background: var(--dsw-alias-surface-l2, rgba(255, 255, 255, 0.06)); } body[data-ds-dark-theme] .me-model-picker-item.active { background: rgba(56, 189, 248, 0.12); color: #38bdf8; } /* Footer Section */ .me-footer-card { box-sizing: border-box; margin-top: 16px; padding: 16px; border-radius: 12px; border: 1px solid var(--dsw-alias-border-l2, rgba(0, 0, 0, 0.08)); background: var(--dsw-alias-bg-module-platform, rgba(0, 0, 0, 0.02)); display: flex; flex-direction: column; gap: 12px; } body[data-ds-dark-theme] .me-footer-card { border-color: var(--dsw-alias-border-l3, rgba(255, 255, 255, 0.1)); background: var(--dsw-alias-surface-l1, rgba(255, 255, 255, 0.02)); } .me-footer-title { font-size: 15px; font-weight: 600; color: var(--dsw-alias-label-primary, #0f1115); display: flex; align-items: center; gap: 8px; } body[data-ds-dark-theme] .me-footer-title { color: #fff; } .me-footer-desc { font-size: 13px; color: var(--dsw-alias-label-secondary, #61666b); line-height: 20px; } .me-diff-table { width: 100%; border-collapse: collapse; font-size: 13px; } .me-diff-table th, .me-diff-table td { padding: 6px 8px; border: 1px solid var(--dsw-alias-border-l2, rgba(0, 0, 0, 0.08)); } body[data-ds-dark-theme] .me-diff-table th, body[data-ds-dark-theme] .me-diff-table td { border-color: var(--dsw-alias-border-l3, rgba(255, 255, 255, 0.1)); } .me-val-new { color: var(--dsw-alias-state-success-primary, #10b981); font-weight: 500; } `; // src/client/CodexModelSelect.tsx var import_react = __toESM(require("react"), 1); // src/client/i18n.ts var I18N_DICT = { zh: { // ModelListEditor & Badges batchBtn: "\u4E00\u952E\u8865\u5168", batchBtnBusy: "\u8865\u5168\u4E2D...", batchBtnTitle: "\u6839\u636E\u6A21\u578B ID \u4ECE models.dev \u81EA\u52A8\u5339\u914D\u5E76\u9884\u586B\u5145\u7F3A\u5931\u53C2\u6570", singleBtn: "\u667A\u80FD\u8865\u5168", singleBtnBusy: "\u8865\u5168\u4E2D", singleBtnTitle: "\u4ECE models.dev \u83B7\u53D6\u8BE5\u6A21\u578B\u63A8\u8350\u53C2\u6570", badgeVision: "\u56FE\u50CF", badgeVisionTitle: "\u652F\u6301\u56FE\u50CF\u8F93\u5165 (Vision)", badgeThinking: "\u601D\u8003", badgeThinkingTitle: "\u601D\u8003\u6863\u4F4D: {levels}", defaultEffort: "\u9ED8\u8BA4", modalitiesTitle: "\u8F93\u5165\u6A21\u6001\u652F\u6301 (Input Modalities)", modalityText: "\u6587\u672C\u8F93\u5165 (Text)", modalityVision: "\u56FE\u50CF\u8F93\u5165 (Vision)", reasoningTitle: "\u63A8\u7406\u601D\u8003\u6863\u4F4D (Reasoning Efforts)", enableReasoning: "\u542F\u7528\u6DF1\u5EA6\u601D\u8003", saveBlockedHint: "\u4FDD\u5B58\u53D7\u963B\u63D0\u793A\uFF1A\u6A21\u578B {index} {reason}", fillNoIdError: "\u5217\u8868\u4E2D\u6CA1\u6709\u586B\u5199\u6A21\u578B ID \u7684\u6709\u6548\u6A21\u578B", fillSuccessNotice: "\u4E00\u952E\u8865\u5168\u5B8C\u6210\uFF1A\u5DF2\u5339\u914D\u5E76\u66F4\u65B0 {count}/{total} \u4E2A\u6A21\u578B", fillFailedNotice: "\u4E00\u952E\u8865\u5168\u5931\u8D25: {message}", singleFillRequireId: "\u8BF7\u5148\u586B\u5199\u6A21\u578B ID", singleFillNotFound: '\u672A\u5728 models.dev \u4E2D\u627E\u5230\u4E0E "{id}" \u5339\u914D\u7684\u6A21\u578B\u4FE1\u606F', singleFillFetchFailed: "\u83B7\u53D6 models.dev \u5931\u8D25: {message}", singleFillApplied: '\u5DF2\u9884\u586B\u5145 "{id}" \u63A8\u8350\u53C2\u6570', // PrefillModal & Footer Settings enhancerTitle: "Model Enhancer (\u591A\u6A21\u6001\u4E0E\u63A8\u7406\u53C2\u6570\u589E\u5F3A)", enhancerIntro: "\u914D\u7F6E models.dev \u9884\u586B\u5145\u3001\u8F93\u5165\u6A21\u6001\u4E0E\u63A8\u7406\u601D\u8003\u6863\u4F4D\uFF0C\u5E76\u53EF\u9009\u62E9\u76EE\u6807 Provider \u4E00\u952E\u5E94\u7528\u589E\u5F3A\u914D\u7F6E\u3002", targetProvider: "\u76EE\u6807 Provider\uFF1A", refreshSettings: "\u5237\u65B0\u914D\u7F6E", activeEnhancerNotice: "\u5F53\u524D\u6B63\u5728\u5BF9\u300C{provider}\u300D\u751F\u6548\u589E\u5F3A\u529F\u80FD\u3002", modalTitle: "models.dev \u9884\u586B\u5145\u786E\u8BA4\u4E0E\u9009\u62E9", matchedModelLabel: "\u68C0\u7D22\u5230\u5339\u914D\u6A21\u578B\uFF1A", thSelect: "\u9009\u7528", thField: "\u914D\u7F6E\u9879", thCurrent: "\u5F53\u524D\u8BBE\u7F6E", thRecommended: "models.dev \u63A8\u8350\u503C", fieldName: "\u663E\u793A\u540D\u79F0", fieldContext: "\u4E0A\u4E0B\u6587\u957F\u5EA6", fieldMaxTokens: "\u6700\u5927\u8F93\u51FA", fieldInput: "\u56FE\u50CF\u8F93\u5165", fieldReasoning: "\u63A8\u7406\u601D\u8003\u7B49\u7EA7", fieldUnset: "(\u672A\u8BBE\u7F6E)", fieldDefault: "(\u9ED8\u8BA4)", visionSupported: "\u652F\u6301\u56FE\u50CF", visionOnlyText: "\u4EC5\u6587\u672C", thinkingOff: "\u5173\u95ED\u601D\u8003", thinkingOn: "\u5F00\u542F", cancel: "\u53D6\u6D88", applySelected: "\u5E94\u7528\u5DF2\u9009\u63A8\u8350\u9879", // Codex Slider effortOff: "\u5173", effortMinimal: "\u6781\u4F4E", effortLow: "\u4F4E", effortMedium: "\u4E2D", effortHigh: "\u9AD8", effortXHigh: "\u8D85\u9AD8", effortMax: "\u6700\u5927", effortReasoningTitle: "\u63A8\u7406\u5F3A\u5EA6", effortSelectModelTip: "\u70B9\u51FB\u5207\u6362\u6A21\u578B", effortResetTip: "\u6062\u590D\u9ED8\u8BA4\u6863\u4F4D", effortChooseModel: "\u9009\u62E9\u6A21\u578B", commandsTitle: "\u547D\u4EE4\u83DC\u5355 (/)" }, en: { // ModelListEditor & Badges batchBtn: "Auto-Fill All", batchBtnBusy: "Filling\u2026", batchBtnTitle: "Auto-match and prefill missing parameters from models.dev", singleBtn: "Auto-Fill", singleBtnBusy: "Filling\u2026", singleBtnTitle: "Fetch recommended parameters for this model from models.dev", badgeVision: "Vision", badgeVisionTitle: "Supports Image/Vision input", badgeThinking: "Reasoning", badgeThinkingTitle: "Reasoning efforts: {levels}", defaultEffort: "Default", modalitiesTitle: "Input Modalities", modalityText: "Text Input", modalityVision: "Vision Input", reasoningTitle: "Reasoning Efforts", enableReasoning: "Enable Deep Reasoning", saveBlockedHint: "Save blocked: Model {index} {reason}", fillNoIdError: "No valid models with a Model ID found in the list", fillSuccessNotice: "Auto-fill complete: matched & updated {count}/{total} models", fillFailedNotice: "Auto-fill failed: {message}", singleFillRequireId: "Please enter a Model ID first", singleFillNotFound: 'No matching model found on models.dev for "{id}"', singleFillFetchFailed: "Failed to fetch models.dev: {message}", singleFillApplied: 'Prefilled recommended parameters for "{id}"', // PrefillModal & Footer Settings enhancerTitle: "Model Enhancer Settings", enhancerIntro: "Configure models.dev auto-fill, input modalities and reasoning effort levels across providers.", targetProvider: "Target Provider:", refreshSettings: "Refresh", activeEnhancerNotice: 'Enhancer active on "{provider}".', modalTitle: "models.dev Prefill Confirmation", matchedModelLabel: "Matched Model: ", thSelect: "Apply", thField: "Property", thCurrent: "Current Setting", thRecommended: "models.dev Value", fieldName: "Display Name", fieldContext: "Context Window", fieldMaxTokens: "Max Output Tokens", fieldInput: "Vision Input", fieldReasoning: "Reasoning Efforts", fieldUnset: "(Unset)", fieldDefault: "(Default)", visionSupported: "Vision Supported", visionOnlyText: "Text Only", thinkingOff: "Disabled", thinkingOn: "Enabled", cancel: "Cancel", applySelected: "Apply Selected", // Codex Slider effortOff: "Off", effortMinimal: "Minimal", effortLow: "Low", effortMedium: "Medium", effortHigh: "High", effortXHigh: "X-High", effortMax: "Max", effortReasoningTitle: "Reasoning Effort", effortSelectModelTip: "Click to switch model", effortResetTip: "Reset to default effort", effortChooseModel: "Select model", commandsTitle: "Commands (/)" } }; function isZhLocale() { if (typeof navigator !== "undefined") { const lang = (navigator.language || "").toLowerCase(); if (lang.startsWith("zh")) return true; } return false; } function getTranslation(key, isZh = isZhLocale(), params) { const dict = isZh ? I18N_DICT.zh : I18N_DICT.en; let str = dict[key] || I18N_DICT.en[key] || key; if (params) { for (const [k, v] of Object.entries(params)) { str = str.replace(new RegExp(`\\{${k}\\}`, "g"), String(v)); } } return str; } // src/client/CodexModelSelect.tsx function CodexModelSelect(props) { const { directory, load, select, available, locked } = props; const state = (0, import_react.useSyncExternalStore)(directory.subscribe, directory.getSnapshot); const [open, setOpen] = (0, import_react.useState)(false); const [showModelPicker, setShowModelPicker] = (0, import_react.useState)(false); const rootRef = (0, import_react.useRef)(null); const isZh = isZhLocale(); const codexLevels = isZh ? CODEX_LEVELS_ZH : CODEX_LEVELS_EN; (0, import_react.useEffect)(() => { if (available) load(); }, [available]); (0, import_react.useEffect)(() => { if (!open) return; const onMouseDown = (e) => { if (!rootRef.current?.contains(e.target)) { setOpen(false); setShowModelPicker(false); } }; document.addEventListener("mousedown", onMouseDown); return () => document.removeEventListener("mousedown", onMouseDown); }, [open]); const choices = (0, import_react.useMemo)(() => (state.groups || []).flatMap((g) => (g.models || []).map((m) => ({ group: g, model: m }))), [state.groups]); const currentChoice = choices.find((c) => c.group.id === state.current?.provider && c.model.id === state.current?.model); const currentModel = currentChoice?.model; const reasoning = currentModel?.reasoning; const availableEfforts = (0, import_react.useMemo)(() => { if (!reasoning || !reasoning.efforts || reasoning.efforts.length === 0) return []; return reasoning.efforts.map((e) => { const found = codexLevels.find((l) => l.id === e.id); return { id: e.id, label: found?.label || e.name || e.id, short: found?.short || e.name || e.id }; }); }, [reasoning, isZh]); const effectiveEffort = state.current?.reasoningEffort ?? reasoning?.defaultEffort; const currentEffortIndex = (0, import_react.useMemo)(() => { if (availableEfforts.length === 0) return 0; const idx = availableEfforts.findIndex((e) => e.id === effectiveEffort); return idx === -1 ? 0 : idx; }, [availableEfforts, effectiveEffort]); const currentEffortObj = availableEfforts[currentEffortIndex]; const effortDisplayLabel = currentEffortObj ? currentEffortObj.label : isZh ? "\u4E2D" : "Medium"; const triggerModelName = currentModel?.name || (isZh ? "\u9009\u62E9\u6A21\u578B" : "Select model"); const triggerEffortLabel = reasoning ? currentEffortObj ? currentEffortObj.short : isZh ? "\u9ED8\u8BA4" : "Default" : null; const onSelectEffortByIndex = (idx) => { if (!currentChoice || !availableEfforts[idx]) return; const effort = availableEfforts[idx].id; select({ provider: currentChoice.group.id, model: currentChoice.model.id, reasoningEffort: effort }); }; const onResetDefault = () => { if (!currentChoice) return; select({ provider: currentChoice.group.id, model: currentChoice.model.id, reasoningEffort: reasoning?.defaultEffort }); }; const onTrackClick = (e) => { if (availableEfforts.length <= 1) return; const rect = e.currentTarget.getBoundingClientRect(); const ratio = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width)); const idx = Math.round(ratio * (availableEfforts.length - 1)); onSelectEffortByIndex(idx); }; if (!available) return null; return import_react.default.createElement( "div", { ref: rootRef, style: { position: "relative", display: "inline-flex", alignItems: "center" } }, import_react.default.createElement( "button", { type: "button", className: `me-codex-trigger ${open ? "active-open" : ""}`, disabled: locked, onClick: () => setOpen(!open) }, import_react.default.createElement("span", null, triggerModelName), triggerEffortLabel ? import_react.default.createElement("span", { style: { color: "#3b82f6", fontWeight: 600 } }, "\xB7 ", triggerEffortLabel) : null, import_react.default.createElement("svg", { className: `me-codex-trigger-chevron ${open ? "open" : ""}`, width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.8" }, import_react.default.createElement("path", { d: "M4 6l4 4 4-4" })) ), open ? import_react.default.createElement( "div", { className: "me-codex-popup" }, import_react.default.createElement( "div", { className: "me-codex-topbar" }, import_react.default.createElement( "div", { className: "me-codex-icon-btn", title: isZh ? "\u63A8\u7406\u5F3A\u5EA6" : "Reasoning Effort" }, import_react.default.createElement("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2" }, import_react.default.createElement("path", { d: "M13 2L3 14h9l-1 8 10-12h-9l1-8z" })) ), import_react.default.createElement( "div", { className: "me-codex-center", onClick: () => setShowModelPicker(!showModelPicker), title: isZh ? "\u70B9\u51FB\u5207\u6362\u6A21\u578B" : "Click to switch model" }, import_react.default.createElement( "div", { className: "me-codex-effort-title" }, effortDisplayLabel, import_react.default.createElement("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", style: { transform: showModelPicker ? "rotate(90deg)" : void 0, transition: "transform 140ms ease" } }, import_react.default.createElement("path", { d: "M6 3.5L10.5 8L6 12.5" })) ), import_react.default.createElement("div", { className: "me-codex-model-name" }, currentModel?.name || (isZh ? "\u9009\u62E9\u6A21\u578B" : "Select model")) ), import_react.default.createElement( "button", { type: "button", className: "me-codex-icon-btn", title: isZh ? "\u6062\u590D\u9ED8\u8BA4\u6863\u4F4D" : "Reset to default effort", onClick: onResetDefault }, import_react.default.createElement("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2" }, import_react.default.createElement("path", { d: "M3 12a9 9 0 109-9 9.75 9.75 0 00-6.74 2.74L3 8m0 0V3m0 5h5" })) ) ), showModelPicker ? import_react.default.createElement( "div", { className: "me-model-picker-list" }, (state.groups || []).map((group) => import_react.default.createElement( "div", { key: group.id, className: "me-model-group-section" }, import_react.default.createElement( "div", { className: "me-model-picker-group" }, import_react.default.createElement("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.8" }, import_react.default.createElement("path", { d: "M2 4h12M2 8h12M2 12h8" })), group.name ), (group.models || []).map((m) => { const active = state.current?.provider === group.id && state.current?.model === m.id; return import_react.default.createElement( "button", { key: m.id, type: "button", className: `me-model-picker-item ${active ? "active" : ""}`, onClick: () => { select({ provider: group.id, model: m.id, reasoningEffort: m.reasoning?.defaultEffort }); setShowModelPicker(false); } }, import_react.default.createElement("span", null, m.name), active ? import_react.default.createElement("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "#38bdf8", strokeWidth: "2" }, import_react.default.createElement("path", { d: "M3.5 8.5l3 3 6-6" })) : null ); }) )) ) : import_react.default.createElement( "div", { className: "me-slider-track-wrap", onClick: onTrackClick }, import_react.default.createElement( "div", { className: "me-slider-track" }, import_react.default.createElement("div", { className: "me-slider-active-fill", style: { width: availableEfforts.length <= 1 ? "100%" : `calc(16px + (100% - 32px) * ${currentEffortIndex / (availableEfforts.length - 1)})` } }), import_react.default.createElement( "div", { className: "me-slider-dots-layer" }, availableEfforts.map((eff, i) => import_react.default.createElement("div", { key: eff.id, className: `me-slider-dot ${i <= currentEffortIndex ? "lit" : ""}` })) ), import_react.default.createElement("div", { className: "me-slider-thumb", style: { left: availableEfforts.length <= 1 ? "calc(100% - 16px)" : `calc(16px + (100% - 32px) * ${currentEffortIndex / (availableEfforts.length - 1)})` } }) ) ) ) : null ); } // src/client/ModelsFooterSettings.tsx var import_react2 = __toESM(require("react"), 1); // src/client/modelsDev.ts var THINKING_LEVELS_ALL = ["minimal", "low", "medium", "high", "xhigh", "max"]; var modelsDevGlobalCache = null; var modelsDevGlobalPromise = null; async function fetchAllModelsDev() { if (modelsDevGlobalCache) return modelsDevGlobalCache; if (modelsDevGlobalPromise) return modelsDevGlobalPromise; modelsDevGlobalPromise = (async () => { const endpoints = ["/api/models-dev/models", "https://models.dev/api.json"]; let lastError = null; for (const url of endpoints) { try { const res = await fetch(url); if (res.ok) { const json = await res.json(); const list = []; for (const [pId, p] of Object.entries(json)) { if (p && p.models) { for (const [mId, m] of Object.entries(p.models)) { list.push({ providerKey: pId, providerName: p.name || pId, id: m.id || mId, rawKey: mId, ...m }); } } } modelsDevGlobalCache = list; return list; } } catch (e) { lastError = e; } } throw lastError || new Error("Failed to load models.dev"); })(); try { return await modelsDevGlobalPromise; } finally { modelsDevGlobalPromise = null; } } function normModelKey(key) { if (!key || typeof key !== "string") return ""; return key.toLowerCase().replace(/^[a-z0-9_-]+\//, "").replace(/[-_.:/]/g, "").replace(/\d{8}$/, ""); } function findDevModel(queryId, allList) { if (!queryId || !allList) return null; const q = queryId.trim().toLowerCase(); const qNorm = normModelKey(q); let m = allList.find((x) => x.id?.toLowerCase() === q || x.rawKey?.toLowerCase() === q); if (m) return m; m = allList.find((x) => x.id?.split("/").pop()?.toLowerCase() === q); if (m) return m; m = allList.find((x) => normModelKey(x.id) === qNorm || normModelKey(x.name || "") === qNorm); if (m) return m; m = allList.find((x) => { const n = normModelKey(x.id); return n.length >= 3 && (n.includes(qNorm) || qNorm.includes(n)); }); return m || null; } // src/client/ModelsFooterSettings.tsx function ModelsFooterSettings({ ctx }) { const isZh = isZhLocale(); const [loading, setLoading] = (0, import_react2.useState)(false); const [providerList, setProviderList] = (0, import_react2.useState)([]); const [selectedProvider, setSelectedProvider] = (0, import_react2.useState)(""); const [statusMsg, setStatusMsg] = (0, import_react2.useState)(null); const [batching, setBatching] = (0, import_react2.useState)(false); const loadProviders = async () => { try { setLoading(true); const res = await ctx.remote?.llm?.listConfigurableProviders?.(); if (res?.ok && Array.isArray(res.value)) { setProviderList(res.value); if (res.value.length > 0 && !selectedProvider) { setSelectedProvider(res.value[0].provider); } } } catch (e) { console.error("[model-enhancer] Failed to list providers:", e); } finally { setLoading(false); } }; (0, import_react2.useEffect)(() => { loadProviders(); }, []); const handleBatchDevMatch = async () => { if (!selectedProvider) return; setBatching(true); setStatusMsg(null); try { const descRes = await ctx.remote?.settings?.describe?.(); const namespaces = descRes?.ok ? descRes.value.namespaces : []; const piAiNs = namespaces.find((n) => n.ns === "llm-pi-ai"); if (!piAiNs) { setStatusMsg({ type: "err", text: "llm-pi-ai settings namespace not found." }); return; } const provConfig = piAiNs.value?.providers?.[selectedProvider] || {}; const models = Array.isArray(provConfig.models) ? provConfig.models : []; if (models.length === 0) { setStatusMsg({ type: "err", text: getTranslation("fillNoIdError", isZh) }); return; } const allDevModels = await fetchAllModelsDev(); let count = 0; const nextModels = models.map((m) => { if (!m || !m.id) return m; const matched = findDevModel(m.id, allDevModels); if (!matched) return m; count++; const hasImage = Boolean(matched.modalities?.input?.includes("image")); const hasReasoning = Boolean(matched.reasoning); let reasoningLevels = void 0; if (hasReasoning) { reasoningLevels = { off: "none" }; let added = false; if (Array.isArray(matched.reasoning_options)) { for (const opt of matched.reasoning_options) { if (opt.type === "effort" && Array.isArray(opt.values)) { for (const val of opt.values) { if (val === "none" || val === "off") reasoningLevels.off = "none"; else if (THINKING_LEVELS_ALL.includes(val)) { reasoningLevels[val] = val; added = true; } } } } } if (!added) { reasoningLevels.low = "low"; reasoningLevels.medium = "medium"; reasoningLevels.high = "high"; } } return { ...m, name: m.name || matched.name, contextWindow: m.contextWindow || matched.limit?.context, maxTokens: m.maxTokens || matched.limit?.output, input: m.input || (hasImage ? ["text", "image"] : ["text"]), reasoningEfforts: m.reasoningEfforts !== void 0 ? m.reasoningEfforts : hasReasoning ? reasoningLevels : false }; }); const ops = [{ op: "set", path: ["providers", selectedProvider, "models"], value: nextModels }]; const mutateRes = await ctx.remote.settings.mutate("llm-pi-ai", ops, piAiNs.revision); if (mutateRes?.ok) { setStatusMsg({ type: "ok", text: getTranslation("fillSuccessNotice", isZh, { count, total: models.length }) }); } else { setStatusMsg({ type: "err", text: mutateRes?.error?.message || "Failed to mutate settings" }); } } catch (err) { setStatusMsg({ type: "err", text: err.message || String(err) }); } finally { setBatching(false); } }; return import_react2.default.createElement( "div", { className: "me-footer-card" }, import_react2.default.createElement( "div", { className: "me-footer-title" }, import_react2.default.createElement("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2" }, import_react2.default.createElement("path", { d: "M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5" })), import_react2.default.createElement("span", null, getTranslation("enhancerTitle", isZh)) ), import_react2.default.createElement("div", { className: "me-footer-desc" }, getTranslation("enhancerIntro", isZh)), import_react2.default.createElement( "div", { style: { display: "flex", alignItems: "center", gap: "12px", flexWrap: "wrap" } }, import_react2.default.createElement( "label", { style: { display: "inline-flex", alignItems: "center", gap: "6px", fontSize: "13px", fontWeight: 500 } }, import_react2.default.createElement("span", null, getTranslation("targetProvider", isZh)), import_react2.default.createElement( "select", { value: selectedProvider, onChange: (e) => setSelectedProvider(e.target.value), style: { height: "32px", borderRadius: "6px", border: "1px solid var(--dsw-alias-border-l2, #ccc)", background: "var(--dsw-alias-bg-module-platform, #fff)", color: "var(--dsw-alias-label-primary, #000)", padding: "0 8px", fontSize: "13px" } }, providerList.map((p) => import_react2.default.createElement("option", { key: p.provider, value: p.provider }, `${p.displayName || p.provider} (${p.settingsNs || "generic"})`)) ) ), import_react2.default.createElement( "button", { type: "button", disabled: batching || !selectedProvider, onClick: handleBatchDevMatch, style: { height: "32px", borderRadius: "16px", border: "none", background: "#2563eb", color: "#fff", padding: "0 14px", fontSize: "13px", fontWeight: 500, cursor: batching || !selectedProvider ? "not-allowed" : "pointer", opacity: batching || !selectedProvider ? 0.6 : 1, display: "inline-flex", alignItems: "center", gap: "6px" } }, batching ? getTranslation("batchBtnBusy", isZh) : getTranslation("batchBtn", isZh) ), import_react2.default.createElement("button", { type: "button", disabled: loading, onClick: loadProviders, style: { height: "32px", borderRadius: "16px", border: "1px solid var(--dsw-alias-border-l2, #ccc)", background: "transparent", color: "var(--dsw-alias-label-secondary, #666)", padding: "0 12px", fontSize: "13px", cursor: "pointer" } }, getTranslation("refreshSettings", isZh)) ), statusMsg ? import_react2.default.createElement("div", { style: { fontSize: "12px", padding: "6px 10px", borderRadius: "6px", background: statusMsg.type === "ok" ? "rgba(16, 185, 129, 0.1)" : "rgba(239, 68, 68, 0.1)", color: statusMsg.type === "ok" ? "#10b981" : "#ef4444" } }, statusMsg.text) : null ); } // src/client/ProviderCardExtras.tsx var import_react3 = __toESM(require("react"), 1); function ProviderCardExtras({ provider, configured, keyConfigured, ctx }) { const isZh = isZhLocale(); const [matching, setMatching] = (0, import_react3.useState)(false); const [notice, setNotice] = (0, import_react3.useState)(null); if (provider.settingsNs !== "llm-pi-ai") { return null; } const handleAutoFillProvider = async () => { setMatching(true); setNotice(null); try { const descRes = await ctx.remote?.settings?.describe?.(); const namespaces = descRes?.ok ? descRes.value.namespaces : []; const piAiNs = namespaces.find((n) => n.ns === "llm-pi-ai"); if (!piAiNs) { setNotice({ type: "err", text: "llm-pi-ai namespace missing." }); return; } const provKey = provider.provider; const provConfig = piAiNs.value?.providers?.[provKey] || {}; const models = Array.isArray(provConfig.models) ? provConfig.models : []; if (models.length === 0) { setNotice({ type: "err", text: getTranslation("fillNoIdError", isZh) }); return; } const allDevModels = await fetchAllModelsDev(); let count = 0; const nextModels = models.map((m) => { if (!m || !m.id) return m; const matched = findDevModel(m.id, allDevModels); if (!matched) return m; count++; const hasImage = Boolean(matched.modalities?.input?.includes("image")); const hasReasoning = Boolean(matched.reasoning); let reasoningLevels = void 0; if (hasReasoning) { reasoningLevels = { off: "none" }; let added = false; if (Array.isArray(matched.reasoning_options)) { for (const opt of matched.reasoning_options) { if (opt.type === "effort" && Array.isArray(opt.values)) { for (const val of opt.values) { if (val === "none" || val === "off") reasoningLevels.off = "none"; else if (THINKING_LEVELS_ALL.includes(val)) { reasoningLevels[val] = val; added = true; } } } } } if (!added) { reasoningLevels.low = "low"; reasoningLevels.medium = "medium"; reasoningLevels.high = "high"; } } return { ...m, name: m.name || matched.name, contextWindow: m.contextWindow || matched.limit?.context, maxTokens: m.maxTokens || matched.limit?.output, input: m.input || (hasImage ? ["text", "image"] : ["text"]), reasoningEfforts: m.reasoningEfforts !== void 0 ? m.reasoningEfforts : hasReasoning ? reasoningLevels : false }; }); const ops = [{ op: "set", path: ["providers", provKey, "models"], value: nextModels }]; const mutateRes = await ctx.remote.settings.mutate("llm-pi-ai", ops, piAiNs.revision); if (mutateRes?.ok) { setNotice({ type: "ok", text: getTranslation("fillSuccessNotice", isZh, { count, total: models.length }) }); } else { setNotice({ type: "err", text: mutateRes?.error?.message || "Mutation rejected" }); } } catch (e) { setNotice({ type: "err", text: e.message || String(e) }); } finally { setMatching(false); } }; return import_react3.default.createElement( "div", { style: { padding: "8px 12px", marginTop: "4px", background: "var(--dsw-alias-bg-module-platform, rgba(0, 0, 0, 0.02))", borderRadius: "8px", border: "1px dashed var(--dsw-alias-border-l2, rgba(0, 0, 0, 0.1))", display: "flex", alignItems: "center", justifyContent: "space-between", gap: "8px" } }, import_react3.default.createElement("span", { style: { fontSize: "12px", color: "var(--dsw-alias-label-secondary, #666)" } }, getTranslation("activeEnhancerNotice", isZh, { provider: provider.displayName })), import_react3.default.createElement("button", { type: "button", disabled: matching, onClick: handleAutoFillProvider, style: { height: "26px", padding: "0 10px", borderRadius: "13px", border: "none", background: "#2563eb", color: "#fff", fontSize: "12px", fontWeight: 500, cursor: matching ? "not-allowed" : "pointer", opacity: matching ? 0.7 : 1 } }, matching ? getTranslation("singleBtnBusy", isZh) : getTranslation("batchBtn", isZh)), notice ? import_react3.default.createElement("span", { style: { fontSize: "11px", color: notice.type === "ok" ? "#10b981" : "#ef4444", marginLeft: "8px" } }, notice.text) : null ); } // src/client/index.ts var name = "dsh-plugin-model-enhancer"; var inject = [ "slots", "remote", "remote.settings", "remote.llm", "modelDirectories", "sessions" ]; function apply(ctx) { if (typeof document !== "undefined" && !document.querySelector("style[data-plugin='dsh-model-enhancer']")) { const tag = document.createElement("style"); tag.dataset.plugin = "dsh-model-enhancer"; tag.textContent = ENHANCER_CSS; document.head.appendChild(tag); } ctx.inject(["slots"], (scope) => { const sessions = ctx.get("sessions"); scope.slots.inject("conversation.input.right", () => scope.slots.register({ name: "conversation.input.right", id: "me-codex-model-selector", order: 100, inject: (sessionId) => { const dirSvc = ctx.get("modelDirectories"); const directory = dirSvc ? dirSvc.directoryFor(sessionId) : null; const available = sessions ? sessions.subagentAddress(sessionId) === void 0 : true; return { available: available && Boolean(directory), directory: directory ? directory.store : { subscribe: () => () => { }, getSnapshot: () => ({ status: "idle", groups: [], current: null }) }, load: () => { if (available && directory) directory.load().catch(() => { }); }, select: (selection) => available && directory ? directory.select(selection).then(() => true, () => false) : Promise.resolve(false) }; } }, CodexModelSelect)); }); ctx.inject(["slots"], (scope) => { scope.slots.inject("settings.models.footer", () => scope.slots.register({ name: "settings.models.footer", id: "me-models-footer", order: 50, inject: () => ({ ctx }) }, ModelsFooterSettings)); }); ctx.inject(["slots"], (scope) => { scope.slots.inject("settings.models.provider-card", () => scope.slots.register({ name: "settings.models.provider-card", key: "llm-pi-ai", inject: (ownerProps) => ({ ...ownerProps, ctx }) }, ProviderCardExtras)); }); } return module.exports; } });