dsh-model-groups 0.3.8 → 0.3.9
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/CHANGELOG.md +56 -0
- package/README.md +11 -1
- package/docs/maintenance.md +20 -0
- package/lib/client.js +25 -3
- package/native/pi-ai.patch.json +385 -4
- package/native/settings-models.patch.json +533 -1
- package/package.json +2 -1
- package/scripts/settings-reorder-patch.mjs +49 -0
- package/scripts/settings-reorder.mjs +170 -0
- package/src/hierarchy.js +23 -1
- package/src/settings-page.js +1 -1
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"packageName": "@deepseek-ai/dsh-client-ui-settings-models",
|
|
4
4
|
"target": "node_modules/@deepseek-ai/dsh-client-ui-settings-models/lib/client.js",
|
|
5
5
|
"baseSha256": "e111ecefea8262e0426f528864b9681d818068042e93d053bcb0b6884b317278",
|
|
6
|
-
"resultSha256": "
|
|
6
|
+
"resultSha256": "2fac0f7bf6f7affa2cdfd10a8a57c6d14166207e5f376f69bb4a46cb2a2a66ab",
|
|
7
7
|
"replacements": [
|
|
8
8
|
{
|
|
9
9
|
"before": "\t\t//#region lib/types/client/CustomProviderCard.js",
|
|
@@ -216,6 +216,58 @@
|
|
|
216
216
|
{
|
|
217
217
|
"before": "const zh = {\n",
|
|
218
218
|
"after": "const zh = {\n\t\t\tmultiKeyExpand: \"展开详情\",\n\t\t\tmultiKeyCollapse: \"收起详情\",\n\t\t\tmultiKeyUnsaved: \"未保存\",\n\t\t\tmultiKeyProtocol: \"分组 API 协议\",\n\t\t\tmultiKeyProtocolInherit: \"跟随供应商({protocol})\",\n\t\t\tmultiKeyProtocolDefault: \"默认协议\",\n\t\t\tmultiKeyProtocolHelp: \"仅影响此密钥分组,请按中转站支持的协议选择,不按模型名称自动切换。\",\n\t\t\tmultiKeyInvalidProtocol: \"不支持此密钥分组协议。\",\n\t\t\tmultiKeyRemoveGroup: \"移除此密钥分组\",\n\t\t\tmultiKeyRemoveTitle: \"移除密钥分组“{name}”?\",\n\t\t\tmultiKeyRemoveHelp: \"移除整个密钥分组及其模型列表,不是仅移除上方一个模型。已保存的密钥凭据会保留。\",\n\t\t\tmultiKeyRemoveDescription: \"此操作从编辑草稿移除该分组及其全部模型条目,其他分组和已保存的密钥凭据不变,不会自动切换现有会话。点击“应用”后才生效;取消编辑可放弃更改。\",\n"
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"before": "const MULTI_KEY_ENTRY_ID =",
|
|
222
|
+
"after": "function orderedKeyEntries(entries) {\n const rank = entry => Number.isSafeInteger(entry?.sortOrder) && entry.sortOrder >= 0 ? entry.sortOrder : Infinity;\n return Object.entries(entries ?? {}).sort(([, left], [, right]) => {\n const a = rank(left), b = rank(right);\n return a === b ? 0 : a < b ? -1 : 1;\n });\n}\n\t\tfunction createSettingsReorder({ handle, row, selector, commit, delay = 400 }) {\n const doc = handle.ownerDocument;\n const win = doc.defaultView;\n const list = row.parentElement;\n const rows = () => [...list.querySelectorAll(selector)].filter(item => item.parentElement === list);\n const original = rows();\n let active = false, stopped = false, timer, frame, target, half;\n let x, y, startX, startY, pointerId;\n const oldOutline = row.style.outline;\n const oldOpacity = row.style.opacity;\n let targetShadow, marker;\n function clearTarget() {\n marker?.remove(); marker = undefined;\n if (target) target.style.boxShadow = targetShadow;\n target = undefined;\n }\n function locate() {\n clearTarget();\n const bounds = list.getBoundingClientRect();\n if (x < bounds.left - 40 || x > bounds.right + 40) return;\n const candidates = rows().filter(item => item !== row && item.getBoundingClientRect().height > 0);\n target = candidates.find(item => y < item.getBoundingClientRect().bottom) ?? candidates.at(-1);\n if (!target) return;\n const rect = target.getBoundingClientRect();\n half = y < rect.top + rect.height / 2 ? 'before' : 'after';\n targetShadow = target.style.boxShadow;\n target.style.boxShadow = `inset 0 ${half === 'before' ? 3 : -3}px 0 #3987ff`;\n // A viewport overlay stays above card borders and does not move the rows.\n const edge = half === 'before' ? rect.top : rect.bottom;\n if (edge < 0 || edge > win.innerHeight) return;\n const visibleEdge = Math.max(4, Math.min(win.innerHeight - 4, edge));\n marker = doc.createElement('div');\n marker.setAttribute('data-settings-reorder-marker', '');\n marker.setAttribute('aria-hidden', 'true');\n Object.assign(marker.style, {\n position: 'fixed', pointerEvents: 'none', zIndex: '2147483647',\n left: `${Math.max(8, bounds.left)}px`, right: `${Math.max(8, win.innerWidth - bounds.right)}px`,\n top: `${visibleEdge - 2}px`, height: '4px', borderRadius: '4px',\n background: '#3987ff', boxShadow: '0 0 0 2px #fff, 0 2px 8px #0008'\n });\n const label = doc.createElement('span');\n label.textContent = doc.documentElement.lang?.startsWith('en') ? 'Release to place here' : '松手后放在这里';\n Object.assign(label.style, {\n position: 'absolute', right: '4px', top: edge < 44 ? '8px' : '-30px',\n padding: '4px 10px', borderRadius: '6px', color: '#fff', background: '#175fc9',\n font: 'bold 13px/20px sans-serif', whiteSpace: 'nowrap', boxShadow: '0 2px 8px #0005'\n });\n marker.appendChild(label); doc.body.appendChild(marker);\n }\n const scrollParent = () => {\n for (let node = list; node && node !== doc.documentElement; node = node.parentElement) {\n if (node.scrollHeight > node.clientHeight && /auto|scroll/.test(win.getComputedStyle(node).overflowY)) return node;\n }\n return doc.scrollingElement;\n };\n function tick() {\n if (!active || stopped) return;\n const scroll = scrollParent();\n if (scroll) {\n const viewport = scroll === doc.scrollingElement;\n const rect = viewport ? { top: 0, bottom: win.innerHeight } : scroll.getBoundingClientRect();\n const top = Math.max(0, rect.top), bottom = Math.min(win.innerHeight, rect.bottom);\n const speed = y < top + 56 ? -Math.min(14, (top + 56 - y) / 3) : y > bottom - 56 ? Math.min(14, (y - bottom + 56) / 3) : 0;\n if (speed) { scroll.scrollTop += speed; locate(); }\n }\n frame = win.requestAnimationFrame(tick);\n }\n function cancel() { finish(false); }\n function move(event) {\n if (event.pointerId !== pointerId) { cancel(); return; }\n x = event.clientX; y = event.clientY;\n if (!active) {\n // A swipe before activation is never interpreted as a reorder.\n if (Math.hypot(x - startX, y - startY) > 10) cancel();\n return;\n }\n event.preventDefault();\n locate();\n }\n function up(event) {\n if (event.pointerId !== pointerId) return;\n if (Number.isFinite(event.clientX)) x = event.clientX;\n if (Number.isFinite(event.clientY)) y = event.clientY;\n if (active) locate();\n finish(true);\n }\n function escape(event) { if (event.key === 'Escape') { event.preventDefault(); cancel(); } }\n function context(event) { event.preventDefault(); }\n function finish(save) {\n if (stopped) return;\n stopped = true;\n win.clearTimeout(timer); win.cancelAnimationFrame(frame);\n doc.removeEventListener('pointermove', move, true);\n doc.removeEventListener('pointerup', up, true);\n doc.removeEventListener('pointercancel', cancel, true);\n doc.removeEventListener('pointerdown', secondPointer, true);\n doc.removeEventListener('keydown', escape, true);\n doc.removeEventListener('contextmenu', context, true);\n win.removeEventListener('blur', cancel);\n doc.removeEventListener('visibilitychange', cancel);\n const destination = target;\n clearTarget(); row.style.outline = oldOutline; row.style.opacity = oldOpacity;\n if (handle.hasPointerCapture?.(pointerId)) handle.releasePointerCapture(pointerId);\n const current = rows();\n // Do not apply an offset to a list changed by another control while held.\n if (!save || !active || !destination || current.length !== original.length || current.some((item, index) => item !== original[index])) return;\n const from = current.indexOf(row), at = current.indexOf(destination);\n const insertion = at + (half === 'after' ? 1 : 0);\n const to = insertion > from ? insertion - 1 : insertion;\n if (from >= 0 && to >= 0 && to !== from) commit(to - from);\n }\n function secondPointer(event) { if (event.pointerId !== pointerId) cancel(); }\n return {\n start(event) {\n if (event.button !== 0 || event.isPrimary === false) return;\n pointerId = event.pointerId; x = startX = event.clientX; y = startY = event.clientY;\n handle.setPointerCapture?.(pointerId);\n doc.addEventListener('pointermove', move, { capture: true, passive: false });\n doc.addEventListener('pointerup', up, true);\n doc.addEventListener('pointercancel', cancel, true);\n doc.addEventListener('pointerdown', secondPointer, true);\n doc.addEventListener('keydown', escape, true);\n doc.addEventListener('contextmenu', context, true);\n win.addEventListener('blur', cancel);\n doc.addEventListener('visibilitychange', cancel);\n timer = win.setTimeout(() => {\n if (stopped || !row.isConnected) { cancel(); return; }\n active = true;\n row.style.outline = '2px solid var(--dsw-alias-label-primary, #679cff)';\n row.style.opacity = '0.65';\n locate(); tick();\n }, delay);\n }, cancel\n };\n}\n\t\tfunction useSettingsReorder(config) {\n const latest = (0, react.useRef)(config);\n latest.current = config;\n const gesture = (0, react.useRef)();\n (0, react.useEffect)(() => {\n if (config.disabled) gesture.current?.cancel();\n return () => gesture.current?.cancel();\n }, [config.disabled]);\n return id => ({\n draggable: false,\n style: { minWidth: 44, minHeight: 44, touchAction: 'none', userSelect: 'none', WebkitTouchCallout: 'none', cursor: 'grab', flexShrink: 0 },\n onContextMenu: event => event.preventDefault(),\n onClick: event => { event.preventDefault(); event.stopPropagation(); },\n onPointerDown: event => {\n if (latest.current.disabled || event.button !== 0 || event.isPrimary === false) return;\n gesture.current?.cancel();\n const handle = event.currentTarget;\n const row = handle.closest(latest.current.selector);\n if (!row) return;\n gesture.current = createSettingsReorder({ handle, row, selector: latest.current.selector, commit: offset => {\n if (!latest.current.disabled) latest.current.move(id, offset);\n } });\n gesture.current.start(event);\n },\n onLostPointerCapture: () => gesture.current?.cancel(),\n onKeyDown: event => {\n if (latest.current.disabled || (event.key !== 'ArrowUp' && event.key !== 'ArrowDown')) return;\n event.preventDefault(); event.stopPropagation();\n latest.current.move(id, event.key === 'ArrowUp' ? -1 : 1);\n }\n });\n}\n\t\tconst MULTI_KEY_ENTRY_ID ="
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
"before": "children: [Object.entries(entries).map(([id, candidate], index) => {",
|
|
226
|
+
"after": "children: [orderedKeyEntries(entries).map(([id, candidate], index) => {"
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
"before": "return Object.fromEntries(Object.entries(entries).map(([id, entry]) => {",
|
|
230
|
+
"after": "return Object.fromEntries(orderedKeyEntries(entries).map(([id, entry]) => {"
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
"before": "const anyBusy = Object.values(busyEntries).some(Boolean);",
|
|
234
|
+
"after": "const anyBusy = Object.values(busyEntries).some(Boolean);\n\t\t\tconst savedEntryOrder = orderedKeyEntries(props.savedEntries ?? props.persistedEntries ?? {}).map(([id]) => id);\n\t\t\tconst reorder = useSettingsReorder({ disabled: disabled || anyBusy, selector: \"[data-key-entry-id]\", move: (id, offset) => {\n\t\t\t\tconst ordered = orderedKeyEntries(entries), from = ordered.findIndex(([key]) => key === id), to = from + offset;\n\t\t\t\tif (from < 0 || to < 0 || to >= ordered.length) return;\n\t\t\t\tconst [moved] = ordered.splice(from, 1); ordered.splice(to, 0, moved);\n\t\t\t\tonChange(Object.fromEntries(ordered.map(([key, entry], sortOrder) => [key, { ...entry, sortOrder }])));\n\t\t\t} });"
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"before": "const dirty = multiKeyEntryDirty(entry, props.savedEntries?.[id] ?? props.persistedEntries?.[id], draft);",
|
|
238
|
+
"after": "const dirty = savedEntryOrder.indexOf(id) !== index || multiKeyEntryDirty(entry, props.savedEntries?.[id] ?? props.persistedEntries?.[id], draft);"
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
"before": "children: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowName\"],",
|
|
242
|
+
"after": "children: [(0, react_jsx_runtime.jsx)(\"button\", {\n\t\t\t\t\t\t\t\ttype: \"button\", className: ModelsSection_module_css_default[\"iconButton\"],\n\t\t\t\t\t\t\t\t\"data-key-entry-handle\": id, \"aria-label\": t(\"multiKeyReorder\") + \" \" + heading,\n\t\t\t\t\t\t\t\t\"aria-keyshortcuts\": \"ArrowUp ArrowDown\", \"aria-description\": t(\"multiKeyReorderHelp\"), title: t(\"multiKeyReorderHelp\"),\n\t\t\t\t\t\t\t\tdisabled: disabled || anyBusy, ...reorder(id),\n\t\t\t\t\t\t\t\tchildren: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconDragHandleOutlineRegular, { size: 14 })\n\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowName\"],"
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
"before": "const preview = (0, _deepseek_ai_dsh_client_ui_primitives.useRowDragPreview)(ModelsSection_module_css_default[\"modelDragPreview\"]);",
|
|
246
|
+
"after": "const reorder = useSettingsReorder({ disabled, selector: \"[data-row-key]\", move: (_key, offset) => props.order.onMove(offset) });"
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
"before": "\n\t\t\t\tonDragOver: (event) => {\n\t\t\t\t\tif (!props.order.canDrop) return;\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.dataTransfer.dropEffect = \"move\";\n\t\t\t\t\tprops.order.onOver(rowHalf(event));\n\t\t\t\t},\n\t\t\t\tonDragLeave: (event) => {\n\t\t\t\t\tif (event.relatedTarget instanceof Node && event.currentTarget.contains(event.relatedTarget)) return;\n\t\t\t\t\tprops.order.onLeave();\n\t\t\t\t},\n\t\t\t\tonDrop: (event) => {\n\t\t\t\t\tif (!props.order.canDrop) return;\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tprops.order.onDrop(rowHalf(event));\n\t\t\t\t},",
|
|
250
|
+
"after": "\n\t\t\t\t// Reordering is handled by the pointer handle below."
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"before": "\n\t\t\t\t\t\t\t\tdraggable: !disabled,\n\t\t\t\t\t\t\t\tonDragStart: (event) => {\n\t\t\t\t\t\t\t\t\tevent.dataTransfer.effectAllowed = \"move\";\n\t\t\t\t\t\t\t\t\tevent.dataTransfer.setData(\"application/x-dsh-model-order\", String(position));\n\t\t\t\t\t\t\t\t\tprops.order.onStart();\n\t\t\t\t\t\t\t\t\tpreview.start(event, event.currentTarget.closest(\"[data-row-key]\"));\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tonDragEnd: () => {\n\t\t\t\t\t\t\t\t\tif (preview.clear()) props.order.onEnd();\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tonKeyDown: (event) => {\n\t\t\t\t\t\t\t\t\tif (event.key !== \"ArrowUp\" && event.key !== \"ArrowDown\") return;\n\t\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\tprops.order.onMove(event.key === \"ArrowUp\" ? -1 : 1);\n\t\t\t\t\t\t\t\t},",
|
|
254
|
+
"after": "\n\t\t\t\t\t\t\t\t...reorder(props.rowKey),"
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"before": "label: t(\"reorderModelHelp\"),",
|
|
258
|
+
"after": "label: t(\"modelReorderTouchHelp\"),"
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
"before": "\"aria-description\": t(\"reorderModelHelp\"),",
|
|
262
|
+
"after": "\"aria-description\": t(\"modelReorderTouchHelp\"),"
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
"before": "const en = {\n",
|
|
266
|
+
"after": "const en = {\n\t\t\tmultiKeyReorder: \"Reorder key group\",\n\t\t\tmultiKeyReorderHelp: \"Hold the handle to reorder; or use Arrow Up/Down. Save with the other edits.\",\n\t\t\tmodelReorderTouchHelp: \"Hold the handle to reorder; or use Arrow Up/Down. Save with the other edits.\",\n"
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
"before": "const zh = {\n",
|
|
270
|
+
"after": "const zh = {\n\t\t\tmultiKeyReorder: \"调整密钥分组顺序\",\n\t\t\tmultiKeyReorderHelp: \"长按手柄拖动,或用上下方向键调整;与其他改动一起保存。\",\n\t\t\tmodelReorderTouchHelp: \"长按手柄拖动,或用上下方向键调整;与其他改动一起保存。\",\n"
|
|
219
271
|
}
|
|
220
272
|
],
|
|
221
273
|
"current": true,
|
|
@@ -551,6 +603,486 @@
|
|
|
551
603
|
"after": "\t\tconst zh = {\n\t\t\tmultiKey: \"多密钥配置\",\n\t\t\tmultiKeyHelp: \"各配置共享 Provider ID、API 地址与协议,分别管理名称、API 密钥和模型。关闭后恢复原单密钥配置,已保存的配置与密钥不会删除。\",\n\t\t\tmultiKeySharedSettings: \"公共设置\",\n\t\t\tmultiKeyAdd: \"添加密钥配置\",\n\t\t\tmultiKeyRemove: \"移除\",\n\t\t\tmultiKeyEntryName: \"配置名称\",\n\t\t\tmultiKeyDefaultName: \"密钥配置\",\n\t\t\tmultiKeyDisableTitle: \"关闭多密钥配置?\",\n\t\t\tmultiKeyDisableDescription: \"应用后,此供应商将使用原单密钥配置,已保存的密钥配置与凭据不会删除。正在使用密钥配置的会话需要重新开启,或手动选择单密钥模型;不会自动换用其他密钥。\",\n\t\t\tmultiKeyKeepEnabled: \"保持开启\",\n\t\t\tmultiKeyDisableConfirm: \"确认关闭(待应用)\",\n\t\t\tmultiKeyUnsavedTitle: \"请先保存新输入的密钥\",\n\t\t\tmultiKeyUnsavedKeys: \"当前有尚未保存的 API 密钥输入。关闭后直接应用不会保存这些输入,因此开关将保持开启。请返回密钥配置并应用保存,再重新打开此卡片关闭;当前输入与已存储的密钥均未删除。\",\n\t\t\tmultiKeyReturnToEdit: \"返回密钥配置\",\n\t\t\tmultiKeyRef: \"密钥引用:{ref}\",\n\t\t\tmultiKeySaved: \"引用已保存,尚未检查密钥状态;输入留空可保留原密钥。\",\n\t\t\tmultiKeyNew: \"尚未保存;输入留空不会创建密钥。\",\n\t\t\tmultiKeyConfigured: \"已确认密钥已配置;留空可保留。\",\n\t\t\tmultiKeyMissing: \"已确认此引用缺少密钥,请输入或在环境中配置。\",\n\t\t\tmultiKeyKeepCredentials: \"移除密钥配置不会删除已存储的密钥。\",\n\t\t\tmultiKeyNeedsEntries: \"请至少添加一个密钥配置。\",\n\t\t\tmultiKeyInvalidId: \"密钥配置 ID 无效,请重新打开此卡片或修正配置。\",\n\t\t\tmultiKeyInvalidName: \"每个配置名称须为 1–120 个字符。\",\n\t\t\tmultiKeyInvalidRef: \"密钥引用无效。\",\n\t\t\tmultiKeyDuplicateRef: \"多个密钥配置使用了相同的密钥引用;每个配置必须使用独立引用。\",\n\t\t\tmultiKeyNeedsModels: \"每个密钥配置至少需要一个模型。\",\n\t\t\tmultiKeyReplaceConfirm: \"确认替换 {ref} 的密钥;共用此引用的其他配置也会受到影响。\",\n\t\t\tmultiKeyConfirmRequired: \"请先确认替换已引用的密钥,再应用。\",\n\t\t\tmultiKeyProbeNeedsKey: \"保存前请先输入此配置的 API 密钥再获取模型;不会使用供应商原来的密钥。\",\n\t\t\tmultiKeySaveFailed: \"保存尚未完成。请保留此卡片并重试;已成功写入的密钥不会重复写入。\","
|
|
552
604
|
}
|
|
553
605
|
]
|
|
606
|
+
},
|
|
607
|
+
{
|
|
608
|
+
"baseSha256": "e111ecefea8262e0426f528864b9681d818068042e93d053bcb0b6884b317278",
|
|
609
|
+
"resultSha256": "334a4011920fab3d196ded7dd945cea7d375e806b9d843a47ef6d307c00c59ca",
|
|
610
|
+
"replacements": [
|
|
611
|
+
{
|
|
612
|
+
"before": "\t\t//#region lib/types/client/CustomProviderCard.js",
|
|
613
|
+
"after": "\t\t//#region dsh-model-groups/native/multikey\n\t\t// Entries live under one native provider. Secrets exist only in local drafts\n\t\t// and credentials/set; profile mutations contain credential references only.\n\t\tconst MULTI_KEY_ENTRY_ID = /^[A-Za-z0-9][A-Za-z0-9_-]{0,79}$/;\n\t\tconst MULTI_KEY_REF = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\t\tconst MULTI_KEY_UNSAFE_IDS = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\n\t\tfunction supportsMultiKeySchema(namespace, schema, path) {\n\t\t\tif (!namespace || !schema) return false;\n\t\t\tconst root = schema.rehydrate(namespace.schema);\n\t\t\tconst profile = schema.nodeAtPath(root, path);\n\t\t\treturn profile?.dict?.multiKey !== void 0 && profile?.dict?.keyEntries !== void 0;\n\t\t}\n\t\tfunction multiKeyRef(route, id) {\n\t\t\tconst normalized = route.toUpperCase().replace(/[^A-Z0-9]+/g, \"_\");\n\t\t\tconst stem = /^[A-Z_]/.test(normalized) ? normalized : `DSH_${normalized}`;\n\t\t\treturn `${stem}_MULTKEY_${id.toUpperCase().replace(/[^A-Z0-9]+/g, \"_\")}_API_KEY`;\n\t\t}\n\t\tfunction newMultiKeyEntry(route, source = {}) {\n\t\t\tconst id = `k${crypto.randomUUID()}`;\n\t\t\treturn [id, {\n\t\t\t\tname: source.name ?? \"\",\n\t\t\t\t...(typeof source.apiKeyEnv === \"string\" && source.apiKeyEnv.length > 0 ? { apiKeyEnv: source.apiKeyEnv } : {}),\n\t\t\t\tmodels: modelDrafts(source.models).map((model) => structuredClone(model))\n\t\t\t}];\n\t\t}\n\t\tfunction normalizedMultiKeyEntries(route, entries) {\n\t\t\treturn Object.fromEntries(Object.entries(entries).map(([id, entry]) => [id, {\n\t\t\t\t...entry,\n\t\t\t\tname: typeof entry?.name === \"string\" ? entry.name.trim() : \"\",\n\t\t\t\tapiKeyEnv: typeof entry?.apiKeyEnv === \"string\" && entry.apiKeyEnv.length > 0 ? entry.apiKeyEnv : multiKeyRef(route, id),\n\t\t\t\tmodels: modelDrafts(entry?.models).map((model) => structuredClone(model))\n\t\t\t}]));\n\t\t}\n\t\tfunction multiKeyFailure(route, entries, drafts, confirmations, t) {\n\t\t\tif (!entries || typeof entries !== \"object\" || Array.isArray(entries) || Object.keys(entries).length === 0) return t(\"multiKeyNeedsEntries\");\n\t\t\tconst refs = new Set();\n\t\t\tfor (const [id, entry] of Object.entries(entries)) {\n\t\t\t\tif (!MULTI_KEY_ENTRY_ID.test(id) || MULTI_KEY_UNSAFE_IDS.has(id)) return t(\"multiKeyInvalidId\");\n\t\t\t\tif (!entry || typeof entry.name !== \"string\" || entry.name.trim().length === 0 || entry.name.trim().length > 120) return t(\"multiKeyInvalidName\");\n\t\t\t\tconst ref = entry.apiKeyEnv ?? multiKeyRef(route, id);\n\t\t\t\tif (typeof ref !== \"string\" || !MULTI_KEY_REF.test(ref)) return t(\"multiKeyInvalidRef\");\n\t\t\t\tif (refs.has(ref)) return t(\"multiKeyDuplicateRef\");\n\t\t\t\trefs.add(ref);\n\t\t\t\tconst keyFailure = apiKeyFailure(drafts[id] ?? \"\");\n\t\t\t\tif (keyFailure !== void 0) return `${entry.name}: ${t(keyFailure)}`;\n\t\t\t\tif ((drafts[id] ?? \"\").trim().length > 0 && ref !== multiKeyRef(route, id) && confirmations[id] !== true) return `${entry.name}: ${t(\"multiKeyConfirmRequired\")}`;\n\t\t\t\tif (!Array.isArray(entry.models) || entry.models.length === 0) return `${entry.name}: ${t(\"multiKeyNeedsModels\")}`;\n\t\t\t\tconst modelFailure = validateDeepSeekModels(entry.models) ?? validateReasoningEfforts(entry.models);\n\t\t\t\tif (modelFailure !== void 0) return `${entry.name}: ${t(\"model\")} ${String(modelFailure.index + 1)}: ${t(modelFailure.key)}`;\n\t\t\t}\n\t\t}\n\t\tasync function storeMultiKeyDrafts(operations, entries, drafts, setDrafts) {\n\t\t\tfor (const [id, entry] of Object.entries(entries)) {\n\t\t\t\tconst draft = Object.hasOwn(drafts, id) ? drafts[id] : \"\";\n\t\t\t\tif (draft.trim().length === 0) continue;\n\t\t\t\tconst failure = await operations.storeCredential(entry.apiKeyEnv, draft.trim());\n\t\t\t\tif (failure !== void 0) return failure;\n\t\t\t\t// Clear only successful, unchanged drafts: partial failures retry just\n\t\t\t\t// the unfinished credentials without rewriting the provider profile.\n\t\t\t\tsetDrafts((current) => current[id] === draft ? { ...current, [id]: \"\" } : current);\n\t\t\t}\n\t\t}\n\t\tfunction hasMultiKeyDrafts(drafts) {\n\t\t\treturn Object.values(drafts).some((value) => typeof value === \"string\" && value.length > 0);\n\t\t}\n\t\tfunction MultiKeyToggle({ t, checked, disabled, onChange, hasUnsavedKeys = false }) {\n\t\t\tconst [confirmOff, setConfirmOff] = (0, react.useState)(false);\n\t\t\t(0, react.useEffect)(() => {\n\t\t\t\tif (!checked || disabled) setConfirmOff(false);\n\t\t\t}, [checked, disabled]);\n\t\t\tconst close = () => setConfirmOff(false);\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\"data-multi-key-toggle\": true,\n\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\tchildren: [(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\tclassName: ModelsSection_module_css_default[\"modelReasoningHead\"],\n\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"], children: t(\"multiKey\")\n\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {\n\t\t\t\t\t\tchecked, label: t(\"multiKey\"), disabled,\n\t\t\t\t\t\tonChange: (enabled) => {\n\t\t\t\t\t\t\tif (disabled || enabled === checked) return;\n\t\t\t\t\t\t\tif (!enabled) setConfirmOff(true);\n\t\t\t\t\t\t\telse onChange(true);\n\t\t\t\t\t\t}\n\t\t\t\t\t})]\n\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"], children: t(\"multiKeyHelp\")\n\t\t\t\t}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {\n\t\t\t\t\topen: confirmOff && checked && !disabled, onClose: close,\n\t\t\t\t\ttitle: t(hasUnsavedKeys ? \"multiKeyUnsavedTitle\" : \"multiKeyDisableTitle\"),\n\t\t\t\t\tcloseLabel: t(\"close\"),\n\t\t\t\t\tdescription: t(hasUnsavedKeys ? \"multiKeyUnsavedKeys\" : \"multiKeyDisableDescription\"),\n\t\t\t\t\tclassName: ModelsSection_module_css_default[\"deleteDialog\"],\n\t\t\t\t\tfooter: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [\n\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {\n\t\t\t\t\t\t\tvariant: \"outline\", \"data-modal-autofocus\": true, onClick: close,\n\t\t\t\t\t\t\tchildren: t(hasUnsavedKeys ? \"multiKeyReturnToEdit\" : \"multiKeyKeepEnabled\")\n\t\t\t\t\t\t}), hasUnsavedKeys ? null : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {\n\t\t\t\t\t\t\tvariant: \"outline\", disabled,\n\t\t\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\t\t\tif (disabled || !checked || hasUnsavedKeys) return;\n\t\t\t\t\t\t\t\tclose(); onChange(false);\n\t\t\t\t\t\t\t}, children: t(\"multiKeyDisableConfirm\")\n\t\t\t\t\t\t})\n\t\t\t\t\t] })\n\t\t\t\t})]\n\t\t\t});\n\t\t}\n\t\tfunction MultiKeyEntriesEditor(props) {\n\t\t\tconst { route, entries, keyDrafts, confirmations, onChange, onKeyDraftsChange, onConfirmationsChange, operations, t, disabled } = props;\n\t\t\tconst [busyEntries, setBusyEntries] = (0, react.useState)({});\n\t\t\tconst anyBusy = Object.values(busyEntries).some(Boolean);\n\t\t\tconst { onBusyChange } = props;\n\t\t\t(0, react.useEffect)(() => {\n\t\t\t\tonBusyChange?.(anyBusy);\n\t\t\t}, [anyBusy, onBusyChange]);\n\t\t\t(0, react.useEffect)(() => () => onBusyChange?.(false), [onBusyChange]);\n\t\t\tconst update = (id, patch) => onChange({ ...entries, [id]: { ...entries[id], ...patch } });\n\t\t\tconst remove = (id) => {\n\t\t\t\tconst { [id]: removed, ...remaining } = entries;\n\t\t\t\tonChange(remaining);\n\t\t\t\tonKeyDraftsChange((current) => { const { [id]: removed, ...rest } = current; return rest; });\n\t\t\t\tonConfirmationsChange((current) => { const { [id]: removed, ...rest } = current; return rest; });\n\t\t\t\tsetBusyEntries((current) => { const { [id]: removed, ...rest } = current; return rest; });\n\t\t\t};\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\"data-multi-key-entries\": true,\n\t\t\t\tclassName: ModelsSection_module_css_default[\"modelList\"],\n\t\t\t\tchildren: [Object.entries(entries).map(([id, candidate], index) => {\n\t\t\t\t\tconst entry = candidate && typeof candidate === \"object\" && !Array.isArray(candidate) ? candidate : {};\n\t\t\t\t\tconst ref = entry.apiKeyEnv ?? multiKeyRef(route, id);\n\t\t\t\t\tconst draft = Object.hasOwn(keyDrafts, id) ? keyDrafts[id] : \"\";\n\t\t\t\t\tconst keyFailure = apiKeyFailure(draft);\n\t\t\t\t\tconst persisted = Object.hasOwn(props.persistedEntries ?? {}, id) && props.persistedEntries[id]?.apiKeyEnv === ref;\n\t\t\t\t\tconst info = props.credentialChecks?.[ref];\n\t\t\t\t\tconst status = info?.configured === true ? \"multiKeyConfigured\" : info?.configured === false ? \"multiKeyMissing\" : persisted ? \"multiKeySaved\" : \"multiKeyNew\";\n\t\t\t\t\tconst needsConfirmation = draft.trim().length > 0 && ref !== multiKeyRef(route, id);\n\t\t\t\t\tconst canUseStored = persisted && props.probe.provider !== void 0;\n\t\t\t\t\tconst probe = {\n\t\t\t\t\t\t...props.probe,\n\t\t\t\t\t\t...(canUseStored ? { keyEntryId: id } : {}),\n\t\t\t\t\t\t...(draft.trim().length > 0 ? { apiKey: draft.trim() } : {})\n\t\t\t\t\t};\n\t\t\t\t\tconst heading = typeof entry.name === \"string\" && entry.name.trim().length > 0 ? entry.name.trim() : `${t(\"multiKeyDefaultName\")} ${String(index + 1)}`;\n\t\t\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\"data-key-entry-id\": id, role: \"group\", \"aria-label\": heading,\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowCard\"],\n\t\t\t\t\t\tstyle: { minWidth: 0 },\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\"data-key-entry-heading\": true,\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowHead\"],\n\t\t\t\t\t\t\tstyle: { flexWrap: \"wrap\" },\n\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowName\"],\n\t\t\t\t\t\t\t\tstyle: { minWidth: 0, overflowWrap: \"anywhere\", flex: \"1 1 120px\" }, children: heading\n\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowActions\"],\n\t\t\t\t\t\t\t\tchildren: (0, react_jsx_runtime.jsx)(\"button\", {\n\t\t\t\t\t\t\t\t\ttype: \"button\", className: ModelsSection_module_css_default[\"secondaryButton\"], disabled,\n\t\t\t\t\t\t\t\t\tonClick: () => remove(id), children: t(\"multiKeyRemove\")\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"label\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", { className: ModelsSection_module_css_default[\"fieldLabel\"], children: t(\"multiKeyEntryName\") }),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"], type: \"text\", value: entry.name ?? \"\", maxLength: 120,\n\t\t\t\t\t\t\t\t\t\t\"aria-label\": `${t(\"multiKeyEntryName\")} ${String(index + 1)}`, disabled,\n\t\t\t\t\t\t\t\t\t\tonChange: (event) => update(id, { name: event.target.value })\n\t\t\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", { className: ModelsSection_module_css_default[\"fieldLabel\"], children: t(\"keyInput\") }),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ApiKeyInput, {\n\t\t\t\t\t\t\t\t\t\tt, value: draft, placeholder: t(persisted ? \"keyPlaceholderSaved\" : \"keyPlaceholder\"),\n\t\t\t\t\t\t\t\t\t\t\"aria-label\": `${t(\"keyInput\")} ${String(index + 1)}`, \"aria-invalid\": keyFailure !== void 0,\n\t\t\t\t\t\t\t\t\t\tdisabled: props.keyDisabled ?? disabled,\n\t\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\t\tconst value = event.target.value;\n\t\t\t\t\t\t\t\t\t\t\tonKeyDraftsChange((current) => ({ ...current, [id]: value }));\n\t\t\t\t\t\t\t\t\t\t\tonConfirmationsChange((current) => ({ ...current, [id]: false }));\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], children: t(status) }),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], style: { overflowWrap: \"anywhere\" }, children: t(\"multiKeyRef\").replace(\"{ref}\", () => ref) }),\n\t\t\t\t\t\t\t\t\tkeyFailure === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"error\"], children: t(keyFailure) })]\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tneedsConfirmation ? (0, react_jsx_runtime.jsxs)(\"label\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\tstyle: { display: \"flex\", alignItems: \"flex-start\", gap: 8, overflowWrap: \"anywhere\" },\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\ttype: \"checkbox\", \"data-confirm-entry\": id, \"aria-label\": t(\"multiKeyReplaceConfirm\").replace(\"{ref}\", () => ref),\n\t\t\t\t\t\t\t\t\tchecked: confirmations[id] === true, disabled: props.keyDisabled ?? disabled,\n\t\t\t\t\t\t\t\t\tonChange: (event) => onConfirmationsChange((current) => ({ ...current, [id]: event.target.checked }))\n\t\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"span\", { children: t(\"multiKeyReplaceConfirm\").replace(\"{ref}\", () => ref) })]\n\t\t\t\t\t\t\t}) : null,\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ModelListEditor, {\n\t\t\t\t\t\t\t\tmodels: modelDrafts(entry.models), onChange: (models) => update(id, { models }),\n\t\t\t\t\t\t\t\treasoningLevels: props.reasoningLevels, probe,\n\t\t\t\t\t\t\t\tprobeBlocked: keyFailure ?? props.probeBlocked ?? (!canUseStored && draft.trim().length === 0 ? \"multiKeyProbeNeedsKey\" : void 0),\n\t\t\t\t\t\t\t\toperations, t, disabled,\n\t\t\t\t\t\t\t\tonBusyChange: (value) => setBusyEntries((current) => current[id] === value ? current : { ...current, [id]: value })\n\t\t\t\t\t\t\t})]\n\t\t\t\t\t}, id);\n\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"button\", {\n\t\t\t\t\ttype: \"button\", className: ModelsSection_module_css_default[\"addModelButton\"], disabled,\n\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\tlet id, entry;\n\t\t\t\t\t\tdo { [id, entry] = newMultiKeyEntry(route, { name: `${t(\"multiKeyDefaultName\")} ${String(Object.keys(entries).length + 1)}` }); } while (Object.hasOwn(entries, id) || Object.values(entries).some((other) => other.apiKeyEnv === multiKeyRef(route, id)));\n\t\t\t\t\t\tonChange({ ...entries, [id]: entry });\n\t\t\t\t\t}, children: t(\"multiKeyAdd\")\n\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], children: t(\"multiKeyKeepCredentials\") })]\n\t\t\t});\n\t\t}\n\t\t//#endregion\n\n\t\t//#region lib/types/client/CustomProviderCard.js"
|
|
614
|
+
},
|
|
615
|
+
{
|
|
616
|
+
"before": "\t\t\t\t\t...probe.provider === void 0 ? {} : { provider: probe.provider },",
|
|
617
|
+
"after": "\t\t\t\t\t...probe.provider === void 0 ? {} : { provider: probe.provider },\n\t\t\t\t\t...probe.keyEntryId === void 0 ? {} : { keyEntryId: probe.keyEntryId },"
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
"before": "const { taken, protocols, reasoningLevels, operations, t, onBusyChange } = props;",
|
|
621
|
+
"after": "const { taken, protocols, reasoningLevels, operations, t, onBusyChange } = props;\n\t\t\tconst supportsMultiKey = supportsMultiKeySchema(props.namespace, props.schema, [\"providers\", PROBE_ROUTE]);"
|
|
622
|
+
},
|
|
623
|
+
{
|
|
624
|
+
"before": "const [models, setModels] = (0, react.useState)([]);\n\t\t\tconst [busy, setBusy]",
|
|
625
|
+
"after": "const [models, setModels] = (0, react.useState)([]);\n\t\t\tconst [multiKey, setMultiKey] = (0, react.useState)(false);\n\t\t\tconst [keyEntries, setKeyEntries] = (0, react.useState)({});\n\t\t\tconst [entryKeyDrafts, setEntryKeyDrafts] = (0, react.useState)({});\n\t\t\tconst [entryConfirmations, setEntryConfirmations] = (0, react.useState)({});\n\t\t\tconst saving = (0, react.useRef)(false);\n\t\t\tconst [busy, setBusy]"
|
|
626
|
+
},
|
|
627
|
+
{
|
|
628
|
+
"before": "const modelFailure = validateDeepSeekModels(models) ?? validateReasoningEfforts(models);\n\t\t\tconst keyFailure = apiKeyFailure(keyDraft);",
|
|
629
|
+
"after": "const modelFailure = multiKey ? void 0 : validateDeepSeekModels(models) ?? validateReasoningEfforts(models);\n\t\t\tconst entryFailure = multiKey ? multiKeyFailure(route, keyEntries, entryKeyDrafts, entryConfirmations, t) : void 0;\n\t\t\tconst keyFailure = multiKey ? void 0 : apiKeyFailure(keyDraft);"
|
|
630
|
+
},
|
|
631
|
+
{
|
|
632
|
+
"before": "const ready = route.length > 0 && !routeInvalid && !routeTaken && normalizedBaseURL.length > 0 && !baseUrlInvalid && models.length > 0 && modelFailure === void 0 && keyFailure === void 0;",
|
|
633
|
+
"after": "const ready = (committed || route.length > 0 && !routeInvalid && !routeTaken) && normalizedBaseURL.length > 0 && !baseUrlInvalid && (multiKey ? entryFailure === void 0 : models.length > 0 && modelFailure === void 0 && keyFailure === void 0);"
|
|
634
|
+
},
|
|
635
|
+
{
|
|
636
|
+
"before": "const hint = failure !== void 0 || ready || keyFailure !== void 0 || route.length === 0 || routeInvalid || routeTaken || baseUrlInvalid ? void 0 : normalizedBaseURL.length === 0 ? t(\"customNeedsBaseUrl\") : modelFailure !== void 0 ? `${t(\"model\")} ${String(modelFailure.index + 1)}: ${t(modelFailure.key)}` : t(\"customNeedsModels\");",
|
|
637
|
+
"after": "const hint = entryFailure ?? (failure !== void 0 || ready || keyFailure !== void 0 || route.length === 0 || routeInvalid || routeTaken || baseUrlInvalid ? void 0 : normalizedBaseURL.length === 0 ? t(\"customNeedsBaseUrl\") : modelFailure !== void 0 ? `${t(\"model\")} ${String(modelFailure.index + 1)}: ${t(modelFailure.key)}` : t(\"customNeedsModels\"));"
|
|
638
|
+
},
|
|
639
|
+
{
|
|
640
|
+
"before": "const keyRef = deriveKeyRef(route);\n\t\t\t\tconst storesKey = keyValue.length > 0;",
|
|
641
|
+
"after": "const entries = normalizedMultiKeyEntries(route, keyEntries);\n\t\t\t\tconst firstEntry = Object.values(entries)[0];\n\t\t\t\tconst keyRef = multiKey ? firstEntry?.apiKeyEnv : deriveKeyRef(route);\n\t\t\t\tconst storesKey = !multiKey && keyValue.length > 0;\n\t\t\t\tif (multiKey && entryFailure !== void 0) return entryFailure;"
|
|
642
|
+
},
|
|
643
|
+
{
|
|
644
|
+
"before": "...storesKey ? { apiKeyEnv: keyRef } : {},\n\t\t\t\t\t\tapi: protocol,\n\t\t\t\t\t\tbaseURL: normalizedBaseURL,\n\t\t\t\t\t\tmodels: models.map((model) => ({ ...model }))",
|
|
645
|
+
"after": "...storesKey || multiKey ? { apiKeyEnv: keyRef } : {},\n\t\t\t\t\t\tapi: protocol,\n\t\t\t\t\t\tbaseURL: normalizedBaseURL,\n\t\t\t\t\t\tmodels: (multiKey ? firstEntry.models : models).map((model) => ({ ...model })),\n\t\t\t\t\t\t...(multiKey || Object.keys(keyEntries).length > 0 ? { multiKey, keyEntries: entries } : {})"
|
|
646
|
+
},
|
|
647
|
+
{
|
|
648
|
+
"before": "\t\t\t\tif (storesKey) {\n\t\t\t\t\tconst stored = await operations.storeCredential(keyRef, keyValue);\n\t\t\t\t\tif (stored !== void 0) return stored;\n\t\t\t\t}\n\t\t\t};",
|
|
649
|
+
"after": "\t\t\t\tif (multiKey) return storeMultiKeyDrafts(operations, entries, entryKeyDrafts, setEntryKeyDrafts);\n\t\t\t\tif (storesKey) {\n\t\t\t\t\tconst stored = await operations.storeCredential(keyRef, keyValue);\n\t\t\t\t\tif (stored !== void 0) return stored;\n\t\t\t\t\tsetKeyDraft(\"\");\n\t\t\t\t}\n\t\t\t};"
|
|
650
|
+
},
|
|
651
|
+
{
|
|
652
|
+
"before": "const create = async () => {\n\t\t\t\tsetBusy(true);",
|
|
653
|
+
"after": "const create = async () => {\n\t\t\t\tif (saving.current || !ready || props.readOnly || listBusy) return;\n\t\t\t\tsaving.current = true;\n\t\t\t\tsetBusy(true);"
|
|
654
|
+
},
|
|
655
|
+
{
|
|
656
|
+
"before": "props.onClose(true);\n\t\t\t\t} finally {\n\t\t\t\t\tsetBusy(false);\n\t\t\t\t}\n\t\t\t};\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {",
|
|
657
|
+
"after": "props.onClose(true);\n\t\t\t\t} catch {\n\t\t\t\t\tsetFailure(t(\"multiKeySaveFailed\"));\n\t\t\t\t} finally {\n\t\t\t\t\tsaving.current = false;\n\t\t\t\t\tsetBusy(false);\n\t\t\t\t}\n\t\t\t};\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {"
|
|
658
|
+
},
|
|
659
|
+
{
|
|
660
|
+
"before": "\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\tchildren: t(\"keyInput\")",
|
|
661
|
+
"after": "\t\t\t\t\tsupportsMultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyToggle, {\n\t\t\t\t\t\tt, checked: multiKey, disabled: profileDisabled || listBusy, hasUnsavedKeys: hasMultiKeyDrafts(entryKeyDrafts),\n\t\t\t\t\t\tonChange: (enabled) => {\n\t\t\t\t\t\t\tif (enabled && Object.keys(keyEntries).length === 0) {\n\t\t\t\t\t\t\t\tconst [id, entry] = newMultiKeyEntry(route, { name: displayName || route || t(\"multiKeyDefaultName\"), models });\n\t\t\t\t\t\t\t\tsetKeyEntries({ [id]: entry });\n\t\t\t\t\t\t\t\tif (keyDraft.length > 0) setEntryKeyDrafts({ [id]: keyDraft });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsetMultiKey(enabled);\n\t\t\t\t\t\t}\n\t\t\t\t\t}) : null,\n\t\t\t\t\tmultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyEntriesEditor, {\n\t\t\t\t\t\troute, entries: keyEntries, onChange: setKeyEntries,\n\t\t\t\t\t\tkeyDrafts: entryKeyDrafts, onKeyDraftsChange: setEntryKeyDrafts,\n\t\t\t\t\t\tconfirmations: entryConfirmations, onConfirmationsChange: setEntryConfirmations,\n\t\t\t\t\t\tpersistedEntries: committed ? normalizedMultiKeyEntries(route, keyEntries) : {},\n\t\t\t\t\t\tprobe: { settingsNs: NS$1, ...(committed ? { provider: route } : {}), baseURL: normalizedBaseURL, api: protocol },\n\t\t\t\t\t\tprobeBlocked: baseUrlInvalid ? \"customBaseUrlInvalid\" : normalizedBaseURL.length === 0 ? \"customNeedsBaseUrl\" : void 0,\n\t\t\t\t\t\treasoningLevels, operations, t, disabled: profileDisabled || listBusy, keyDisabled: disabled || listBusy, onBusyChange: setListBusy\n\t\t\t\t\t}) : null,\n\t\t\t\t\tmultiKey ? null : (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\tchildren: t(\"keyInput\")"
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
"before": "\t\t\t\t\t(0, react_jsx_runtime.jsx)(ModelListEditor, {\n\t\t\t\t\t\tmodels,\n\t\t\t\t\t\tonChange: setModels,",
|
|
665
|
+
"after": "\t\t\t\t\t!multiKey ? (0, react_jsx_runtime.jsx)(ModelListEditor, {\n\t\t\t\t\t\tmodels,\n\t\t\t\t\t\tonChange: setModels,"
|
|
666
|
+
},
|
|
667
|
+
{
|
|
668
|
+
"before": "\t\t\t\t\t\tonBusyChange: setListBusy\n\t\t\t\t\t}),\n\t\t\t\t\tfailure !== void 0",
|
|
669
|
+
"after": "\t\t\t\t\t\tonBusyChange: setListBusy\n\t\t\t\t\t}) : null,\n\t\t\t\t\tfailure !== void 0"
|
|
670
|
+
},
|
|
671
|
+
{
|
|
672
|
+
"before": "submitDisabled: disabled || !ready,",
|
|
673
|
+
"after": "submitDisabled: disabled || listBusy || !ready,"
|
|
674
|
+
},
|
|
675
|
+
{
|
|
676
|
+
"before": "taken: state.rows.map((row) => row.entry.provider),\n\t\t\t\t\t\t\t\t\t\tprotocols,",
|
|
677
|
+
"after": "taken: state.rows.map((row) => row.entry.provider),\n\t\t\t\t\t\t\t\t\t\tnamespace: piAi,\n\t\t\t\t\t\t\t\t\t\tschema,\n\t\t\t\t\t\t\t\t\t\tprotocols,"
|
|
678
|
+
},
|
|
679
|
+
{
|
|
680
|
+
"before": "const [draft, setDraft] = (0, react.useState)(() => draftAt(schema, namespace, settingsPath));",
|
|
681
|
+
"after": "const [draft, setDraft] = (0, react.useState)(() => draftAt(schema, namespace, settingsPath));\n\t\t\tconst [entryKeyDrafts, setEntryKeyDrafts] = (0, react.useState)({});\n\t\t\tconst [entryConfirmations, setEntryConfirmations] = (0, react.useState)({});\n\t\t\tconst saving = (0, react.useRef)(false);"
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
"before": "const keyRef = refFor(schema, namespace, settingsPath, props.provider);",
|
|
685
|
+
"after": "const keyRef = refFor(schema, namespace, settingsPath, props.provider);\n\t\t\tconst supportsMultiKey = layout === \"pi-ai\" && props.declared === true && props.credentialOnly !== true && supportsMultiKeySchema(namespace, schema, settingsPath);\n\t\t\tconst multiKey = supportsMultiKey && (draft.multiKey ?? fallback?.multiKey) === true;\n\t\t\tconst keyEntries = draft.keyEntries ?? fallback?.keyEntries ?? {};\n\t\t\tconst entryFailure = multiKey ? multiKeyFailure(props.provider, keyEntries, entryKeyDrafts, entryConfirmations, t) : void 0;"
|
|
686
|
+
},
|
|
687
|
+
{
|
|
688
|
+
"before": "const modelFailure = validateModels(schema.getPath(draft, [\"models\"]));\n\t\t\tconst keyFailure = apiKeyFailure(keyDraft);",
|
|
689
|
+
"after": "const modelFailure = multiKey ? void 0 : validateModels(schema.getPath(draft, [\"models\"]));\n\t\t\tconst keyFailure = multiKey ? void 0 : apiKeyFailure(keyDraft);"
|
|
690
|
+
},
|
|
691
|
+
{
|
|
692
|
+
"before": "const next = layout === \"pi-ai\" && stringAt(draft, \"apiKeyEnv\") === void 0 && stringAt(fallback, \"apiKeyEnv\") === void 0 && keyValue.length > 0 ? schema.setPath(draft, [\"apiKeyEnv\"], keyRef) : draft;",
|
|
693
|
+
"after": "const normalizedDraft = supportsMultiKey && schema.hasPath(draft, [\"keyEntries\"]) ? schema.setPath(draft, [\"keyEntries\"], normalizedMultiKeyEntries(props.provider, keyEntries)) : draft;\n\t\t\t\tconst next = multiKey ? schema.setPath(normalizedDraft, [\"keyEntries\"], normalizedMultiKeyEntries(props.provider, keyEntries)) : layout === \"pi-ai\" && stringAt(draft, \"apiKeyEnv\") === void 0 && stringAt(fallback, \"apiKeyEnv\") === void 0 && keyValue.length > 0 ? schema.setPath(normalizedDraft, [\"apiKeyEnv\"], keyRef) : normalizedDraft;\n\t\t\t\tif (entryFailure !== void 0) return entryFailure;"
|
|
694
|
+
},
|
|
695
|
+
{
|
|
696
|
+
"before": "if (props.credentialOnly !== true) {\n\t\t\t\t\tconst failure = validateModels",
|
|
697
|
+
"after": "if (props.credentialOnly !== true && !multiKey) {\n\t\t\t\t\tconst failure = validateModels"
|
|
698
|
+
},
|
|
699
|
+
{
|
|
700
|
+
"before": "\t\t\t\tif (keyValue.length > 0) {\n\t\t\t\t\tconst stored = await operations.storeCredential(keyRef, keyValue);",
|
|
701
|
+
"after": "\t\t\t\tif (multiKey) return storeMultiKeyDrafts(operations, next.keyEntries, entryKeyDrafts, setEntryKeyDrafts);\n\t\t\t\tif (keyValue.length > 0) {\n\t\t\t\t\tconst stored = await operations.storeCredential(keyRef, keyValue);"
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
"before": "const apply = async () => {\n\t\t\t\tsetBusy(true);",
|
|
705
|
+
"after": "const apply = async () => {\n\t\t\t\tif (saving.current || props.readOnly || listBusy || entryFailure !== void 0) return;\n\t\t\t\tsaving.current = true;\n\t\t\t\tsetBusy(true);"
|
|
706
|
+
},
|
|
707
|
+
{
|
|
708
|
+
"before": "props.onClose(true);\n\t\t\t\t} finally {\n\t\t\t\t\tsetBusy(false);\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (node === void 0)",
|
|
709
|
+
"after": "props.onClose(true);\n\t\t\t\t} catch {\n\t\t\t\t\tsetFailure(t(\"multiKeySaveFailed\"));\n\t\t\t\t} finally {\n\t\t\t\t\tsaving.current = false;\n\t\t\t\t\tsetBusy(false);\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (node === void 0)"
|
|
710
|
+
},
|
|
711
|
+
{
|
|
712
|
+
"before": "return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [keylessNativeAuth ? null :",
|
|
713
|
+
"after": "return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [supportsMultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyToggle, {\n\t\t\t\t\tt, checked: multiKey, disabled: disabled || listBusy, hasUnsavedKeys: hasMultiKeyDrafts(entryKeyDrafts),\n\t\t\t\t\tonChange: (enabled) => {\n\t\t\t\t\t\tlet updated = schema.setPath(draft, [\"multiKey\"], enabled);\n\t\t\t\t\t\tif (enabled && Object.keys(keyEntries).length === 0) {\n\t\t\t\t\t\t\tconst namedRef = stringAt(draft, \"apiKeyEnv\") ?? stringAt(fallback, \"apiKeyEnv\");\n\t\t\t\t\t\t\tconst [id, entry] = newMultiKeyEntry(props.provider, {\n\t\t\t\t\t\t\t\tname: stringAt(draft, \"displayName\") ?? stringAt(fallback, \"displayName\") ?? props.displayName ?? props.provider,\n\t\t\t\t\t\t\t\tapiKeyEnv: namedRef,\n\t\t\t\t\t\t\t\tmodels: draft.models ?? fallback?.models ?? inheritedModels()\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (keyDraft.length > 0) {\n\t\t\t\t\t\t\t\tsetEntryKeyDrafts({ [id]: keyDraft });\n\t\t\t\t\t\t\t\tif (namedRef === void 0) updated = schema.setPath(updated, [\"apiKeyEnv\"], multiKeyRef(props.provider, id));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tupdated = schema.setPath(updated, [\"keyEntries\"], { [id]: entry });\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsetDraft(updated);\n\t\t\t\t\t}\n\t\t\t\t}) : null, multiKey ? (0, react_jsx_runtime.jsx)(MultiKeyEntriesEditor, {\n\t\t\t\t\troute: props.provider, entries: keyEntries,\n\t\t\t\t\tonChange: (entries) => setDraft((current) => schema.setPath(current, [\"keyEntries\"], entries)),\n\t\t\t\t\tkeyDrafts: entryKeyDrafts, onKeyDraftsChange: setEntryKeyDrafts,\n\t\t\t\t\tconfirmations: entryConfirmations, onConfirmationsChange: setEntryConfirmations,\n\t\t\t\t\tpersistedEntries: schema.getPath(committedOriginal, [\"keyEntries\"]) ?? fallback?.keyEntries ?? {},\n\t\t\t\t\tcredentialChecks: props.credentialChecks,\n\t\t\t\t\tprobe: { settingsNs: namespace.ns, provider: props.provider, ...(probeBaseURL === void 0 ? {} : { baseURL: probeBaseURL }), ...(probeApi === void 0 ? {} : { api: probeApi }) },\n\t\t\t\t\treasoningLevels, operations, t, disabled: disabled || listBusy, onBusyChange: setListBusy\n\t\t\t\t}) : null, multiKey || keylessNativeAuth ? null :"
|
|
714
|
+
},
|
|
715
|
+
{
|
|
716
|
+
"before": "family === \"deepseek\" ? (0, react_jsx_runtime.jsx)(DeepSeekModelsEditor, {",
|
|
717
|
+
"after": "multiKey ? null : family === \"deepseek\" ? (0, react_jsx_runtime.jsx)(DeepSeekModelsEditor, {"
|
|
718
|
+
},
|
|
719
|
+
{
|
|
720
|
+
"before": "\t\t\t\t\tfailure !== void 0 ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: failure\n\t\t\t\t\t}) : null,\n\t\t\t\t\tprops.credentialOnly",
|
|
721
|
+
"after": "\t\t\t\t\t(failure ?? entryFailure) !== void 0 ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: failure ?? entryFailure\n\t\t\t\t\t}) : null,\n\t\t\t\t\tprops.credentialOnly"
|
|
722
|
+
},
|
|
723
|
+
{
|
|
724
|
+
"before": "submitDisabled: disabled || layout === \"unknown\" || props.credentialOnly !== true && modelFailure !== void 0 || shownKeyFailure !== void 0 || props.credentialRequired === true && keyValue.length === 0,",
|
|
725
|
+
"after": "submitDisabled: disabled || listBusy || layout === \"unknown\" || entryFailure !== void 0 || props.credentialOnly !== true && modelFailure !== void 0 || !multiKey && (shownKeyFailure !== void 0 || props.credentialRequired === true && keyValue.length === 0),"
|
|
726
|
+
},
|
|
727
|
+
{
|
|
728
|
+
"before": "return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [supportsMultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyToggle, {",
|
|
729
|
+
"after": "const credentials = (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [supportsMultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyToggle, {"
|
|
730
|
+
},
|
|
731
|
+
{
|
|
732
|
+
"before": "\t\t\t\t}), props.credentialOnly === true ? null : (0, react_jsx_runtime.jsxs)(\"details\", {\n\t\t\t\t\tclassName: ModelsSection_module_css_default[\"customized\"],",
|
|
733
|
+
"after": "\t\t\t\t})] });\n\t\t\t\tconst customization = props.credentialOnly === true ? null : (0, react_jsx_runtime.jsxs)(\"details\", {\n\t\t\t\t\tclassName: ModelsSection_module_css_default[\"customized\"],\n\t\t\t\t\topen: supportsMultiKey ? true : void 0,\n\t\t\t\t\t\"data-multi-key-shared-settings\": supportsMultiKey ? true : void 0,"
|
|
734
|
+
},
|
|
735
|
+
{
|
|
736
|
+
"before": "children: t(\"customized\")\n\t\t\t\t\t}), (0, react_jsx_runtime.jsxs)(\"div\", {",
|
|
737
|
+
"after": "children: t(supportsMultiKey ? \"multiKeySharedSettings\" : \"customized\")\n\t\t\t\t\t}), (0, react_jsx_runtime.jsxs)(\"div\", {"
|
|
738
|
+
},
|
|
739
|
+
{
|
|
740
|
+
"before": "\t\t\t\t})] });\n\t\t\t};\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\tclassName: props.credentialOnly",
|
|
741
|
+
"after": "\t\t\t\t});\n\t\t\t\treturn (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: supportsMultiKey ? [customization, credentials] : [credentials, customization] });\n\t\t\t};\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\tclassName: props.credentialOnly"
|
|
742
|
+
},
|
|
743
|
+
{
|
|
744
|
+
"before": "\t\tconst en = {",
|
|
745
|
+
"after": "\t\tconst en = {\n\t\t\tmultiKey: \"Multiple key configurations\",\n\t\t\tmultiKeyHelp: \"Configurations share one provider ID, endpoint and protocol; each has its own name, API key and models. Turning this off restores the original single-key configuration without deleting entries or credentials.\",\n\t\t\tmultiKeySharedSettings: \"Shared settings\",\n\t\t\tmultiKeyAdd: \"Add key configuration\",\n\t\t\tmultiKeyRemove: \"Remove\",\n\t\t\tmultiKeyEntryName: \"Configuration name\",\n\t\t\tmultiKeyDefaultName: \"Key configuration\",\n\t\t\tmultiKeyDisableTitle: \"Turn off multiple key configurations?\",\n\t\t\tmultiKeyDisableDescription: \"After applying, this provider will use its original single-key configuration. Saved configurations and credentials will not be deleted. Sessions using a key configuration will need you to re-enable it or select a single-key model; no other key will be chosen automatically.\",\n\t\t\tmultiKeyKeepEnabled: \"Keep enabled\",\n\t\t\tmultiKeyDisableConfirm: \"Turn off in draft\",\n\t\t\tmultiKeyUnsavedTitle: \"Save the API keys before turning this off\",\n\t\t\tmultiKeyUnsavedKeys: \"Some API keys have been typed but not saved. Turning this off and applying would not store those inputs, so the switch will stay on. Return to the configurations and apply to save them, then reopen this card to turn it off. Nothing has been deleted.\",\n\t\t\tmultiKeyReturnToEdit: \"Return to configurations\",\n\t\t\tmultiKeyRef: \"Credential reference: {ref}\",\n\t\t\tmultiKeySaved: \"Saved reference; credential status not checked. Leave the key blank to keep it.\",\n\t\t\tmultiKeyNew: \"Not saved yet. An empty key does not create a credential.\",\n\t\t\tmultiKeyConfigured: \"Credential confirmed configured; leave blank to keep it.\",\n\t\t\tmultiKeyMissing: \"Credential confirmed missing. Enter a key or configure this reference.\",\n\t\t\tmultiKeyKeepCredentials: \"Removing a key configuration does not delete its stored credential.\",\n\t\t\tmultiKeyNeedsEntries: \"Add at least one key configuration.\",\n\t\t\tmultiKeyInvalidId: \"Invalid key-configuration ID; reopen this card or fix the profile.\",\n\t\t\tmultiKeyInvalidName: \"Each key configuration needs a name of 1–120 characters.\",\n\t\t\tmultiKeyInvalidRef: \"Invalid credential reference.\",\n\t\t\tmultiKeyDuplicateRef: \"Two configurations use the same credential reference. Each configuration must have its own reference.\",\n\t\t\tmultiKeyNeedsModels: \"Each key configuration needs at least one model.\",\n\t\t\tmultiKeyReplaceConfirm: \"Replace the key at {ref}. Other configurations sharing this reference will also be affected.\",\n\t\t\tmultiKeyConfirmRequired: \"Confirm the credential replacement before applying.\",\n\t\t\tmultiKeyProbeNeedsKey: \"Enter this configuration’s API key to discover models before saving. The provider’s original key will not be used.\",\n\t\t\tmultiKeySaveFailed: \"Saving did not complete. Keep this card open and retry; successful credential writes will not be repeated.\","
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
"before": "\t\tconst zh = {",
|
|
749
|
+
"after": "\t\tconst zh = {\n\t\t\tmultiKey: \"多密钥配置\",\n\t\t\tmultiKeyHelp: \"各配置共享 Provider ID、API 地址与协议,分别管理名称、API 密钥和模型。关闭后恢复原单密钥配置,已保存的配置与密钥不会删除。\",\n\t\t\tmultiKeySharedSettings: \"公共设置\",\n\t\t\tmultiKeyAdd: \"添加密钥配置\",\n\t\t\tmultiKeyRemove: \"移除\",\n\t\t\tmultiKeyEntryName: \"配置名称\",\n\t\t\tmultiKeyDefaultName: \"密钥配置\",\n\t\t\tmultiKeyDisableTitle: \"关闭多密钥配置?\",\n\t\t\tmultiKeyDisableDescription: \"应用后,此供应商将使用原单密钥配置,已保存的密钥配置与凭据不会删除。正在使用密钥配置的会话需要重新开启,或手动选择单密钥模型;不会自动换用其他密钥。\",\n\t\t\tmultiKeyKeepEnabled: \"保持开启\",\n\t\t\tmultiKeyDisableConfirm: \"确认关闭(待应用)\",\n\t\t\tmultiKeyUnsavedTitle: \"请先保存新输入的密钥\",\n\t\t\tmultiKeyUnsavedKeys: \"当前有尚未保存的 API 密钥输入。关闭后直接应用不会保存这些输入,因此开关将保持开启。请返回密钥配置并应用保存,再重新打开此卡片关闭;当前输入与已存储的密钥均未删除。\",\n\t\t\tmultiKeyReturnToEdit: \"返回密钥配置\",\n\t\t\tmultiKeyRef: \"密钥引用:{ref}\",\n\t\t\tmultiKeySaved: \"引用已保存,尚未检查密钥状态;输入留空可保留原密钥。\",\n\t\t\tmultiKeyNew: \"尚未保存;输入留空不会创建密钥。\",\n\t\t\tmultiKeyConfigured: \"已确认密钥已配置;留空可保留。\",\n\t\t\tmultiKeyMissing: \"已确认此引用缺少密钥,请输入或在环境中配置。\",\n\t\t\tmultiKeyKeepCredentials: \"移除密钥配置不会删除已存储的密钥。\",\n\t\t\tmultiKeyNeedsEntries: \"请至少添加一个密钥配置。\",\n\t\t\tmultiKeyInvalidId: \"密钥配置 ID 无效,请重新打开此卡片或修正配置。\",\n\t\t\tmultiKeyInvalidName: \"每个配置名称须为 1–120 个字符。\",\n\t\t\tmultiKeyInvalidRef: \"密钥引用无效。\",\n\t\t\tmultiKeyDuplicateRef: \"多个密钥配置使用了相同的密钥引用;每个配置必须使用独立引用。\",\n\t\t\tmultiKeyNeedsModels: \"每个密钥配置至少需要一个模型。\",\n\t\t\tmultiKeyReplaceConfirm: \"确认替换 {ref} 的密钥;共用此引用的其他配置也会受到影响。\",\n\t\t\tmultiKeyConfirmRequired: \"请先确认替换已引用的密钥,再应用。\",\n\t\t\tmultiKeyProbeNeedsKey: \"保存前请先输入此配置的 API 密钥再获取模型;不会使用供应商原来的密钥。\",\n\t\t\tmultiKeySaveFailed: \"保存尚未完成。请保留此卡片并重试;已成功写入的密钥不会重复写入。\","
|
|
750
|
+
},
|
|
751
|
+
{
|
|
752
|
+
"before": "const MULTI_KEY_ENTRY_ID =",
|
|
753
|
+
"after": "const MULTI_KEY_PROTOCOLS = new Set([\"openai-completions\", \"openai-responses\", \"anthropic-messages\"]);\n\t\tconst MULTI_KEY_ENTRY_ID ="
|
|
754
|
+
},
|
|
755
|
+
{
|
|
756
|
+
"before": "name: source.name ?? \"\",",
|
|
757
|
+
"after": "name: source.name ?? \"\",\n\t\t\t\t...(source.api === void 0 ? {} : { api: source.api }),"
|
|
758
|
+
},
|
|
759
|
+
{
|
|
760
|
+
"before": "return Object.fromEntries(Object.entries(entries).map(([id, entry]) => [id, {\n\t\t\t\t...entry,\n\t\t\t\tname: typeof entry?.name === \"string\" ? entry.name.trim() : \"\",\n\t\t\t\tapiKeyEnv: typeof entry?.apiKeyEnv === \"string\" && entry.apiKeyEnv.length > 0 ? entry.apiKeyEnv : multiKeyRef(route, id),\n\t\t\t\tmodels: modelDrafts(entry?.models).map((model) => structuredClone(model))\n\t\t\t}]));",
|
|
761
|
+
"after": "return Object.fromEntries(Object.entries(entries).map(([id, entry]) => {\n\t\t\t\tconst { api, ...rest } = entry;\n\t\t\t\treturn [id, {\n\t\t\t\t\t...rest,\n\t\t\t\t\t...(api === void 0 || api === \"\" ? {} : { api }),\n\t\t\t\t\tname: typeof entry?.name === \"string\" ? entry.name.trim() : \"\",\n\t\t\t\t\tapiKeyEnv: typeof entry?.apiKeyEnv === \"string\" && entry.apiKeyEnv.length > 0 ? entry.apiKeyEnv : multiKeyRef(route, id),\n\t\t\t\t\tmodels: modelDrafts(entry?.models).map((model) => structuredClone(model))\n\t\t\t\t}];\n\t\t\t}));"
|
|
762
|
+
},
|
|
763
|
+
{
|
|
764
|
+
"before": "return t(\"multiKeyInvalidName\");\n\t\t\t\tconst ref = entry.apiKeyEnv ?? multiKeyRef(route, id);",
|
|
765
|
+
"after": "return t(\"multiKeyInvalidName\");\n\t\t\t\tif (entry.api !== void 0 && !MULTI_KEY_PROTOCOLS.has(entry.api)) return t(\"multiKeyInvalidProtocol\");\n\t\t\t\tconst ref = entry.apiKeyEnv ?? multiKeyRef(route, id);"
|
|
766
|
+
},
|
|
767
|
+
{
|
|
768
|
+
"before": "...(canUseStored ? { keyEntryId: id } : {}),",
|
|
769
|
+
"after": "...(canUseStored ? { keyEntryId: id } : {}),\n\t\t\t\t\t\t...(entry.api === void 0 ? {} : { api: entry.api }),"
|
|
770
|
+
},
|
|
771
|
+
{
|
|
772
|
+
"before": "\t\tfunction MultiKeyEntriesEditor(props) {",
|
|
773
|
+
"after": "\t\tfunction multiKeyEntryDirty(entry, saved, draft) {\n\t\t\treturn saved === void 0 || JSON.stringify(entry) !== JSON.stringify(saved) || (draft ?? \"\").length > 0;\n\t\t}\n\t\tfunction MultiKeyEntriesEditor(props) {"
|
|
774
|
+
},
|
|
775
|
+
{
|
|
776
|
+
"before": "const [busyEntries, setBusyEntries] = (0, react.useState)({});",
|
|
777
|
+
"after": "const [busyEntries, setBusyEntries] = (0, react.useState)({});\n\t\t\tconst [expandedEntries, setExpandedEntries] = (0, react.useState)({});\n\t\t\tconst [removeTarget, setRemoveTarget] = (0, react.useState)(void 0);\n\t\t\tconst detailsPrefix = (0, react.useId)();\n\t\t\tconst previousSave = (0, react.useRef)(props.saveState);\n\t\t\t(0, react.useEffect)(() => {\n\t\t\t\tconst save = props.saveState;\n\t\t\t\tif (save === previousSave.current) return;\n\t\t\t\tpreviousSave.current = save;\n\t\t\t\tif (!save) return;\n\t\t\t\tsetExpandedEntries((current) => {\n\t\t\t\t\tconst next = { ...current };\n\t\t\t\t\tfor (const id of Object.keys(save.entries)) {\n\t\t\t\t\t\t// Only collapse the exact snapshot acknowledged by this save.\n\t\t\t\t\t\tif (!save.ok || !multiKeyEntryDirty(entries[id], save.entries[id], keyDrafts[id])) next[id] = !save.ok;\n\t\t\t\t\t}\n\t\t\t\t\treturn next;\n\t\t\t\t});\n\t\t\t}, [props.saveState, entries, keyDrafts]);\n\t\t\tconst invalidRows = Object.keys(entries).filter((id) => multiKeyFailure(route, { [id]: entries[id] }, keyDrafts, confirmations, t) !== void 0);\n\t\t\tconst invalidEntries = invalidRows.length > 0 ? invalidRows : multiKeyFailure(route, entries, keyDrafts, confirmations, t) !== void 0 ? Object.keys(entries) : [];\n\t\t\tconst invalidSignature = JSON.stringify(invalidEntries);\n\t\t\t(0, react.useEffect)(() => {\n\t\t\t\tif (invalidEntries.length > 0) setExpandedEntries((current) => ({ ...current, ...Object.fromEntries(invalidEntries.map((id) => [id, true])) }));\n\t\t\t}, [invalidSignature]);"
|
|
778
|
+
},
|
|
779
|
+
{
|
|
780
|
+
"before": "const anyBusy = Object.values(busyEntries).some(Boolean);",
|
|
781
|
+
"after": "const anyBusy = Object.values(busyEntries).some(Boolean);\n\t\t\t(0, react.useEffect)(() => {\n\t\t\t\tif (disabled || anyBusy || removeTarget !== void 0 && !Object.hasOwn(entries, removeTarget)) setRemoveTarget(void 0);\n\t\t\t}, [disabled, anyBusy, removeTarget, entries]);\n\t\t\tconst removeName = typeof entries[removeTarget]?.name === \"string\" && entries[removeTarget].name.trim() ? entries[removeTarget].name.trim() : t(\"multiKeyDefaultName\");"
|
|
782
|
+
},
|
|
783
|
+
{
|
|
784
|
+
"before": "const remove = (id) => {",
|
|
785
|
+
"after": "const remove = (id) => {\n\t\t\t\tif (disabled || anyBusy || !Object.hasOwn(entries, id)) return;"
|
|
786
|
+
},
|
|
787
|
+
{
|
|
788
|
+
"before": "const heading = typeof entry.name === \"string\"",
|
|
789
|
+
"after": "const dirty = multiKeyEntryDirty(entry, props.savedEntries?.[id] ?? props.persistedEntries?.[id], draft);\n\t\t\t\t\tconst expanded = expandedEntries[id] ?? !Object.hasOwn(props.persistedEntries ?? {}, id);\n\t\t\t\t\tconst detailsId = detailsPrefix + \"-\" + id;\n\t\t\t\t\tconst heading = typeof entry.name === \"string\""
|
|
790
|
+
},
|
|
791
|
+
{
|
|
792
|
+
"before": "\"data-key-entry-id\": id, role: \"group\", \"aria-label\": heading,",
|
|
793
|
+
"after": "\"data-key-entry-id\": id, \"data-key-entry-expanded\": expanded, \"data-key-entry-dirty\": dirty, role: \"group\", \"aria-label\": heading,"
|
|
794
|
+
},
|
|
795
|
+
{
|
|
796
|
+
"before": "\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\"data-key-entry-heading\": true,\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowHead\"],\n\t\t\t\t\t\t\tstyle: { flexWrap: \"wrap\" },\n\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowName\"],\n\t\t\t\t\t\t\t\tstyle: { minWidth: 0, overflowWrap: \"anywhere\", flex: \"1 1 120px\" }, children: heading\n\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowActions\"],\n\t\t\t\t\t\t\t\tchildren: (0, react_jsx_runtime.jsx)(\"button\", {\n\t\t\t\t\t\t\t\t\ttype: \"button\", className: ModelsSection_module_css_default[\"secondaryButton\"], disabled,\n\t\t\t\t\t\t\t\t\tonClick: () => remove(id), children: t(\"multiKeyRemove\")\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"label\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", { className: ModelsSection_module_css_default[\"fieldLabel\"], children: t(\"multiKeyEntryName\") }),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"], type: \"text\", value: entry.name ?? \"\", maxLength: 120,\n\t\t\t\t\t\t\t\t\t\t\"aria-label\": `${t(\"multiKeyEntryName\")} ${String(index + 1)}`, disabled,\n\t\t\t\t\t\t\t\t\t\tonChange: (event) => update(id, { name: event.target.value })\n\t\t\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", { className: ModelsSection_module_css_default[\"fieldLabel\"], children: t(\"keyInput\") }),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ApiKeyInput, {\n\t\t\t\t\t\t\t\t\t\tt, value: draft, placeholder: t(persisted ? \"keyPlaceholderSaved\" : \"keyPlaceholder\"),\n\t\t\t\t\t\t\t\t\t\t\"aria-label\": `${t(\"keyInput\")} ${String(index + 1)}`, \"aria-invalid\": keyFailure !== void 0,\n\t\t\t\t\t\t\t\t\t\tdisabled: props.keyDisabled ?? disabled,\n\t\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\t\tconst value = event.target.value;\n\t\t\t\t\t\t\t\t\t\t\tonKeyDraftsChange((current) => ({ ...current, [id]: value }));\n\t\t\t\t\t\t\t\t\t\t\tonConfirmationsChange((current) => ({ ...current, [id]: false }));\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], children: t(status) }),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], style: { overflowWrap: \"anywhere\" }, children: t(\"multiKeyRef\").replace(\"{ref}\", () => ref) }),\n\t\t\t\t\t\t\t\t\tkeyFailure === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"error\"], children: t(keyFailure) })]\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tneedsConfirmation ? (0, react_jsx_runtime.jsxs)(\"label\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\tstyle: { display: \"flex\", alignItems: \"flex-start\", gap: 8, overflowWrap: \"anywhere\" },\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\ttype: \"checkbox\", \"data-confirm-entry\": id, \"aria-label\": t(\"multiKeyReplaceConfirm\").replace(\"{ref}\", () => ref),\n\t\t\t\t\t\t\t\t\tchecked: confirmations[id] === true, disabled: props.keyDisabled ?? disabled,\n\t\t\t\t\t\t\t\t\tonChange: (event) => onConfirmationsChange((current) => ({ ...current, [id]: event.target.checked }))\n\t\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"span\", { children: t(\"multiKeyReplaceConfirm\").replace(\"{ref}\", () => ref) })]\n\t\t\t\t\t\t\t}) : null,\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ModelListEditor, {\n\t\t\t\t\t\t\t\tmodels: modelDrafts(entry.models), onChange: (models) => update(id, { models }),\n\t\t\t\t\t\t\t\treasoningLevels: props.reasoningLevels, probe,\n\t\t\t\t\t\t\t\tprobeBlocked: keyFailure ?? props.probeBlocked ?? (!canUseStored && draft.trim().length === 0 ? \"multiKeyProbeNeedsKey\" : void 0),\n\t\t\t\t\t\t\t\toperations, t, disabled,\n\t\t\t\t\t\t\t\tonBusyChange: (value) => setBusyEntries((current) => current[id] === value ? current : { ...current, [id]: value })\n\t\t\t\t\t\t\t})]",
|
|
797
|
+
"after": "\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\"data-key-entry-heading\": true,\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowHead\"], style: { flexWrap: \"wrap\" },\n\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowName\"],\n\t\t\t\t\t\t\t\tstyle: { minWidth: 0, overflowWrap: \"anywhere\", flex: \"1 1 120px\" }, children: heading\n\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowActions\"],\n\t\t\t\t\t\t\t\tchildren: [dirty ? (0, react_jsx_runtime.jsx)(\"span\", { className: ModelsSection_module_css_default[\"rowTag\"], \"data-key-entry-unsaved\": true, children: t(\"multiKeyUnsaved\") }) : null,\n\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"button\", {\n\t\t\t\t\t\t\t\t\ttype: \"button\", className: ModelsSection_module_css_default[\"secondaryButton\"],\n\t\t\t\t\t\t\t\t\t\"aria-expanded\": expanded, \"aria-controls\": detailsId,\n\t\t\t\t\t\t\t\t\tonClick: () => setExpandedEntries((current) => ({ ...current, [id]: !expanded })),\n\t\t\t\t\t\t\t\t\tchildren: t(expanded ? \"multiKeyCollapse\" : \"multiKeyExpand\")\n\t\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", { className: ModelsSection_module_css_default[\"fieldLabel\"], children: t(\"keyInput\") }),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ApiKeyInput, {\n\t\t\t\t\t\t\t\t\t\tt, value: draft, placeholder: t(persisted ? \"keyPlaceholderSaved\" : \"keyPlaceholder\"),\n\t\t\t\t\t\t\t\t\t\t\"aria-label\": `${t(\"keyInput\")} ${String(index + 1)}`, \"aria-invalid\": keyFailure !== void 0,\n\t\t\t\t\t\t\t\t\t\tdisabled: props.keyDisabled ?? disabled,\n\t\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\t\tconst value = event.target.value;\n\t\t\t\t\t\t\t\t\t\t\tonKeyDraftsChange((current) => ({ ...current, [id]: value }));\n\t\t\t\t\t\t\t\t\t\t\tonConfirmationsChange((current) => ({ ...current, [id]: false }));\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], children: t(status) }),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], style: { overflowWrap: \"anywhere\" }, children: t(\"multiKeyRef\").replace(\"{ref}\", () => ref) }),\n\t\t\t\t\t\t\t\t\tkeyFailure === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"error\"], children: t(keyFailure) })]\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tneedsConfirmation ? (0, react_jsx_runtime.jsxs)(\"label\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\tstyle: { display: \"flex\", alignItems: \"flex-start\", gap: 8, overflowWrap: \"anywhere\" },\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\ttype: \"checkbox\", \"data-confirm-entry\": id, \"aria-label\": t(\"multiKeyReplaceConfirm\").replace(\"{ref}\", () => ref),\n\t\t\t\t\t\t\t\t\tchecked: confirmations[id] === true, disabled: props.keyDisabled ?? disabled,\n\t\t\t\t\t\t\t\t\tonChange: (event) => onConfirmationsChange((current) => ({ ...current, [id]: event.target.checked }))\n\t\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"span\", { children: t(\"multiKeyReplaceConfirm\").replace(\"{ref}\", () => ref) })]\n\t\t\t\t\t\t\t}) : null,\n\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\tid: detailsId, \"data-key-entry-details\": true, hidden: !expanded,\n\t\t\t\t\t\t\tstyle: { display: expanded ? \"flex\" : \"none\", flexDirection: \"column\", gap: 12, minWidth: 0, borderTop: \"0.5px solid var(--dsw-alias-settings-card-stroke)\", paddingTop: 12 },\n\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\t\"data-key-entry-fields\": true, style: { display: \"grid\", gridTemplateColumns: \"repeat(auto-fit, minmax(min(100%, 220px), 1fr))\", gap: 12, minWidth: 0 }, children: [\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"label\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", { className: ModelsSection_module_css_default[\"fieldLabel\"], children: t(\"multiKeyEntryName\") }),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"], type: \"text\", value: entry.name ?? \"\", maxLength: 120,\n\t\t\t\t\t\t\t\t\t\t\"aria-label\": `${t(\"multiKeyEntryName\")} ${String(index + 1)}`, disabled,\n\t\t\t\t\t\t\t\t\t\tonChange: (event) => update(id, { name: event.target.value })\n\t\t\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"label\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", { className: ModelsSection_module_css_default[\"fieldLabel\"], children: t(\"multiKeyProtocol\") }),\n\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"select\", {\n\t\t\t\t\t\t\t\t\t\"data-key-entry-protocol\": id, \"aria-label\": t(\"multiKeyProtocol\") + \" \" + heading,\n\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"] + \" \" + ModelsSection_module_css_default[\"selectInput\"],\n\t\t\t\t\t\t\t\t\tstyle: { maxWidth: \"none\" }, value: entry.api ?? \"\", disabled: disabled || anyBusy,\n\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\tconst value = event.target.value;\n\t\t\t\t\t\t\t\t\t\tif (disabled || anyBusy || value !== \"\" && !MULTI_KEY_PROTOCOLS.has(value)) return;\n\t\t\t\t\t\t\t\t\t\tconst { api, ...inherited } = entries[id];\n\t\t\t\t\t\t\t\t\t\tonChange({ ...entries, [id]: value === \"\" ? inherited : { ...inherited, api: value } });\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"option\", { value: \"\", children: t(\"multiKeyProtocolInherit\").replace(\"{protocol}\", () => props.probe.api ? protocolLabel(t, props.probe.api) : t(\"multiKeyProtocolDefault\")) }),\n\t\t\t\t\t\t\t\t\t...(props.protocols ?? [...MULTI_KEY_PROTOCOLS]).map((choice) => (0, react_jsx_runtime.jsx)(\"option\", { value: choice, children: protocolLabel(t, choice) }, choice))]\n\t\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"span\", { className: ModelsSection_module_css_default[\"advancedHint\"], children: t(\"multiKeyProtocolHelp\") })]\n\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ModelListEditor, {\n\t\t\t\t\t\t\t\tmodels: modelDrafts(entry.models), onChange: (models) => update(id, { models }),\n\t\t\t\t\t\t\t\treasoningLevels: props.reasoningLevels, probe,\n\t\t\t\t\t\t\t\tprobeBlocked: keyFailure ?? props.probeBlocked ?? (!canUseStored && draft.trim().length === 0 ? \"multiKeyProbeNeedsKey\" : void 0),\n\t\t\t\t\t\t\t\toperations, t, disabled,\n\t\t\t\t\t\t\t\tonBusyChange: (value) => setBusyEntries((current) => current[id] === value ? current : { ...current, [id]: value })\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\t\"data-key-entry-danger-zone\": true,\n\t\t\t\t\t\t\t\tstyle: { display: \"flex\", flexDirection: \"column\", gap: 6, borderTop: \"0.5px solid var(--dsw-alias-settings-card-stroke)\", paddingTop: 12 },\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], children: t(\"multiKeyRemoveHelp\") }),\n\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"button\", {\n\t\t\t\t\t\t\t\t\ttype: \"button\", \"data-key-entry-remove\": id,\n\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"dangerButton\"], style: { alignSelf: \"flex-start\" }, disabled: disabled || anyBusy,\n\t\t\t\t\t\t\t\t\tonClick: () => { if (!disabled && !anyBusy) setRemoveTarget(id); }, children: t(\"multiKeyRemoveGroup\")\n\t\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t})]"
|
|
798
|
+
},
|
|
799
|
+
{
|
|
800
|
+
"before": "}), (0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], children: t(\"multiKeyKeepCredentials\") })]",
|
|
801
|
+
"after": "}), (0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], children: t(\"multiKeyKeepCredentials\") }),\n\t\t\t\t(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {\n\t\t\t\t\topen: removeTarget !== void 0 && Object.hasOwn(entries, removeTarget) && !disabled && !anyBusy,\n\t\t\t\t\t\"data-key-entry-remove-dialog\": true, onClose: () => setRemoveTarget(void 0),\n\t\t\t\t\ttitle: t(\"multiKeyRemoveTitle\").replace(\"{name}\", () => removeName), closeLabel: t(\"close\"),\n\t\t\t\t\tdescription: t(\"multiKeyRemoveDescription\"), className: ModelsSection_module_css_default[\"deleteDialog\"],\n\t\t\t\t\tfooter: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [\n\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, { variant: \"outline\", \"data-modal-autofocus\": true, onClick: () => setRemoveTarget(void 0), children: t(\"cancel\") }),\n\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {\n\t\t\t\t\t\t\tvariant: \"outline\", className: ModelsSection_module_css_default[\"deleteConfirm\"], disabled: disabled || anyBusy,\n\t\t\t\t\t\t\tonClick: () => { if (removeTarget === void 0 || disabled || anyBusy) return; remove(removeTarget); setRemoveTarget(void 0); }, children: t(\"multiKeyRemoveGroup\")\n\t\t\t\t\t\t})]\n\t\t\t\t\t})\n\t\t\t\t})]"
|
|
802
|
+
},
|
|
803
|
+
{
|
|
804
|
+
"before": "function CustomProviderCard(props) {\n\t\t\tconst { taken, protocols, reasoningLevels, operations, t, onBusyChange } = props;\n\t\t\tconst supportsMultiKey = supportsMultiKeySchema(props.namespace, props.schema, [\"providers\", PROBE_ROUTE]);\n\t\t\tconst [openedAt] = (0, react.useState)(() => props.revision);\n\t\t\tconst [route, setRoute] = (0, react.useState)(\"\");\n\t\t\tconst [displayName, setDisplayName] = (0, react.useState)(\"\");\n\t\t\tconst [baseURL, setBaseURL] = (0, react.useState)(\"\");\n\t\t\tconst [protocol, setProtocol] = (0, react.useState)(protocols[0] ?? \"\");\n\t\t\tconst [keyDraft, setKeyDraft] = (0, react.useState)(\"\");\n\t\t\tconst [models, setModels] = (0, react.useState)([]);\n\t\t\tconst [multiKey, setMultiKey] = (0, react.useState)(false);\n\t\t\tconst [keyEntries, setKeyEntries] = (0, react.useState)({});\n\t\t\tconst [entryKeyDrafts, setEntryKeyDrafts] = (0, react.useState)({});\n\t\t\tconst [entryConfirmations, setEntryConfirmations] = (0, react.useState)({});\n\t\t\tconst saving = (0, react.useRef)(false);\n\t\t\tconst [busy, setBusy] = (0, react.useState)(false);\n\t\t\tconst [listBusy, setListBusy] = (0, react.useState)(false);\n\t\t\t(0, react.useEffect)(() => {\n\t\t\t\tonBusyChange?.(busy || listBusy);\n\t\t\t}, [\n\t\t\t\tbusy,\n\t\t\t\tlistBusy,\n\t\t\t\tonBusyChange\n\t\t\t]);\n\t\t\tconst [failure, setFailure] = (0, react.useState)(void 0);\n\t\t\t/**\n\t\t\t* The profile write landed. Only the key write can still be outstanding, so\n\t\t\t* the fields that describe the provider are settled and the retry path is\n\t\t\t* the credential alone.\n\t\t\t*/\n\t\t\tconst [committed, setCommitted] = (0, react.useState)(false);\n\t\t\tconst disabled = props.readOnly || busy;\n\t\t\t/** Everything but the key stops being editable once the provider exists. */\n\t\t\tconst profileDisabled = disabled || committed;\n\t\t\tconst routeInvalid = route.length > 0 && !ROUTE_PATTERN.test(route);\n\t\t\tconst routeTaken = taken.includes(route);\n\t\t\tconst normalizedBaseURL = baseURL.trim();\n\t\t\tconst baseUrlInvalid = baseURL.length > 0 && !isHttpUrl(normalizedBaseURL);\n\t\t\tconst modelFailure = multiKey ? void 0 : validateDeepSeekModels(models) ?? validateReasoningEfforts(models);\n\t\t\tconst entryFailure = multiKey ? multiKeyFailure(route, keyEntries, entryKeyDrafts, entryConfirmations, t) : void 0;\n\t\t\tconst keyFailure = multiKey ? void 0 : apiKeyFailure(keyDraft);\n\t\t\tconst keyValue = keyDraft.trim();\n\t\t\tconst ready = (committed || route.length > 0 && !routeInvalid && !routeTaken) && normalizedBaseURL.length > 0 && !baseUrlInvalid && (multiKey ? entryFailure === void 0 : models.length > 0 && modelFailure === void 0 && keyFailure === void 0);\n\t\t\tconst hint = entryFailure ?? (failure !== void 0 || ready || keyFailure !== void 0 || route.length === 0 || routeInvalid || routeTaken || baseUrlInvalid ? void 0 : normalizedBaseURL.length === 0 ? t(\"customNeedsBaseUrl\") : modelFailure !== void 0 ? `${t(\"model\")} ${String(modelFailure.index + 1)}: ${t(modelFailure.key)}` : t(\"customNeedsModels\"));\n\t\t\t/** Perform the create, returning a failure message or undefined. */\n\t\t\tconst createOnce = async () => {\n\t\t\t\tconst entries = normalizedMultiKeyEntries(route, keyEntries);\n\t\t\t\tconst firstEntry = Object.values(entries)[0];\n\t\t\t\tconst keyRef = multiKey ? firstEntry?.apiKeyEnv : deriveKeyRef(route);\n\t\t\t\tconst storesKey = !multiKey && keyValue.length > 0;\n\t\t\t\tif (multiKey && entryFailure !== void 0) return entryFailure;\n\t\t\t\tif (!committed) {\n\t\t\t\t\tconst profile = {\n\t\t\t\t\t\t...displayName.length === 0 ? {} : { displayName },\n\t\t\t\t\t\t...storesKey || multiKey ? { apiKeyEnv: keyRef } : {},\n\t\t\t\t\t\tapi: protocol,\n\t\t\t\t\t\tbaseURL: normalizedBaseURL,\n\t\t\t\t\t\tmodels: (multiKey ? firstEntry.models : models).map((model) => ({ ...model })),\n\t\t\t\t\t\t...(multiKey || Object.keys(keyEntries).length > 0 ? { multiKey, keyEntries: entries } : {})\n\t\t\t\t\t};\n\t\t\t\t\tconst written = await operations.writeSettings(NS$1, [{\n\t\t\t\t\t\top: \"set\",\n\t\t\t\t\t\tpath: [\"providers\", route],\n\t\t\t\t\t\tvalue: profile\n\t\t\t\t\t}], openedAt);\n\t\t\t\t\tif (written.kind !== \"written\") return written.kind === \"conflict\" ? t(\"conflict\") : written.message;\n\t\t\t\t\tsetCommitted(true);\n\t\t\t\t}\n\t\t\t\tif (multiKey) return storeMultiKeyDrafts(operations, entries, entryKeyDrafts, setEntryKeyDrafts);\n\t\t\t\tif (storesKey) {\n\t\t\t\t\tconst stored = await operations.storeCredential(keyRef, keyValue);\n\t\t\t\t\tif (stored !== void 0) return stored;\n\t\t\t\t\tsetKeyDraft(\"\");\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst create = async () => {\n\t\t\t\tif (saving.current || !ready || props.readOnly || listBusy) return;\n\t\t\t\tsaving.current = true;\n\t\t\t\tsetBusy(true);\n\t\t\t\tsetFailure(void 0);\n\t\t\t\ttry {\n\t\t\t\t\tconst outcome = await createOnce();\n\t\t\t\t\tif (outcome !== void 0) {\n\t\t\t\t\t\tsetFailure(outcome);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tprops.onClose(true);\n\t\t\t\t} catch {\n\t\t\t\t\tsetFailure(t(\"multiKeySaveFailed\"));\n\t\t\t\t} finally {\n\t\t\t\t\tsaving.current = false;\n\t\t\t\t\tsetBusy(false);\n\t\t\t\t}\n\t\t\t};\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\tclassName: ModelsSection_module_css_default[\"editor\"],\n\t\t\t\tchildren: [\n\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: t(\"customRoute\")\n\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\tvalue: route,\n\t\t\t\t\t\t\tplaceholder: \"acme-gateway\",\n\t\t\t\t\t\t\t\"aria-label\": t(\"customRoute\"),\n\t\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetRoute(event.target.value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})]\n\t\t\t\t\t}),\n\t\t\t\t\trouteInvalid || routeTaken ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: t(routeInvalid ? \"customRouteInvalid\" : \"customRouteTaken\")\n\t\t\t\t\t}) : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\tchildren: t(\"customRouteHint\")\n\t\t\t\t\t}),\n\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: t(\"customDisplayName\")\n\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\tvalue: displayName,\n\t\t\t\t\t\t\tplaceholder: route.length === 0 ? t(\"customDisplayName\") : route,\n\t\t\t\t\t\t\t\"aria-label\": t(\"customDisplayName\"),\n\t\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetDisplayName(event.target.value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})]\n\t\t\t\t\t}),\n\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: t(\"baseUrl\")\n\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\tvalue: baseURL,\n\t\t\t\t\t\t\tplaceholder: t(protocol === \"anthropic-messages\" ? \"customAnthropicBaseUrlPlaceholder\" : \"customBaseUrlPlaceholder\"),\n\t\t\t\t\t\t\t\"aria-label\": t(\"baseUrl\"),\n\t\t\t\t\t\t\t\"aria-invalid\": baseUrlInvalid,\n\t\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetBaseURL(event.target.value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})]\n\t\t\t\t\t}),\n\t\t\t\t\tbaseUrlInvalid ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: t(\"customBaseUrlInvalid\")\n\t\t\t\t\t}) : null,\n\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: t(\"customApi\")\n\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"select\", {\n\t\t\t\t\t\t\tclassName: `${ModelsSection_module_css_default[\"input\"]} ${ModelsSection_module_css_default[\"selectInput\"]}`,\n\t\t\t\t\t\t\tvalue: protocol,\n\t\t\t\t\t\t\t\"aria-label\": t(\"customApi\"),\n\t\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetProtocol(event.target.value);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tchildren: protocols.map((choice) => (0, react_jsx_runtime.jsx)(\"option\", {\n\t\t\t\t\t\t\t\tvalue: choice,\n\t\t\t\t\t\t\t\tchildren: protocolLabel(t, choice)\n\t\t\t\t\t\t\t}, choice))\n\t\t\t\t\t\t})]\n\t\t\t\t\t}),\n\t\t\t\t\tsupportsMultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyToggle, {\n\t\t\t\t\t\tt, checked: multiKey, disabled: profileDisabled || listBusy, hasUnsavedKeys: hasMultiKeyDrafts(entryKeyDrafts),\n\t\t\t\t\t\tonChange: (enabled) => {\n\t\t\t\t\t\t\tif (enabled && Object.keys(keyEntries).length === 0) {\n\t\t\t\t\t\t\t\tconst [id, entry] = newMultiKeyEntry(route, { name: displayName || route || t(\"multiKeyDefaultName\"), models });\n\t\t\t\t\t\t\t\tsetKeyEntries({ [id]: entry });\n\t\t\t\t\t\t\t\tif (keyDraft.length > 0) setEntryKeyDrafts({ [id]: keyDraft });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsetMultiKey(enabled);\n\t\t\t\t\t\t}\n\t\t\t\t\t}) : null,\n\t\t\t\t\tmultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyEntriesEditor, {\n\t\t\t\t\t\troute, entries: keyEntries, onChange: setKeyEntries,\n\t\t\t\t\t\tkeyDrafts: entryKeyDrafts, onKeyDraftsChange: setEntryKeyDrafts,\n\t\t\t\t\t\tconfirmations: entryConfirmations, onConfirmationsChange: setEntryConfirmations,\n\t\t\t\t\t\tpersistedEntries: committed ? normalizedMultiKeyEntries(route, keyEntries) : {},\n\t\t\t\t\t\tprobe: { settingsNs: NS$1, ...(committed ? { provider: route } : {}), baseURL: normalizedBaseURL, api: protocol },\n\t\t\t\t\t\tprobeBlocked: baseUrlInvalid ? \"customBaseUrlInvalid\" : normalizedBaseURL.length === 0 ? \"customNeedsBaseUrl\" : void 0,\n\t\t\t\t\t\treasoningLevels, operations, t, disabled: profileDisabled || listBusy, keyDisabled: disabled || listBusy, onBusyChange: setListBusy\n\t\t\t\t\t}) : null,\n\t\t\t\t\tmultiKey ? null : (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\tchildren: t(\"keyInput\")\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ApiKeyInput, {\n\t\t\t\t\t\t\t\tt,\n\t\t\t\t\t\t\t\tvalue: keyDraft,\n\t\t\t\t\t\t\t\tplaceholder: t(\"keyPlaceholder\"),\n\t\t\t\t\t\t\t\t\"aria-label\": t(\"keyInput\"),\n\t\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\tsetKeyDraft(event.target.value);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tkeyFailure === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\t\t\tchildren: t(keyFailure === \"keyBlank\" ? \"keyBlankNew\" : keyFailure)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t]\n\t\t\t\t\t}),\n\t\t\t\t\t!multiKey ? (0, react_jsx_runtime.jsx)(ModelListEditor, {\n\t\t\t\t\t\tmodels,\n\t\t\t\t\t\tonChange: setModels,\n\t\t\t\t\t\treasoningLevels,\n\t\t\t\t\t\tprobe: {\n\t\t\t\t\t\t\tsettingsNs: NS$1,\n\t\t\t\t\t\t\tbaseURL: normalizedBaseURL,\n\t\t\t\t\t\t\tapi: protocol,\n\t\t\t\t\t\t\t...keyValue.length === 0 ? {} : { apiKey: keyValue }\n\t\t\t\t\t\t},\n\t\t\t\t\t\tprobeBlocked: baseUrlInvalid ? \"customBaseUrlInvalid\" : keyFailure === \"keyBlank\" ? \"keyBlankNew\" : keyFailure,\n\t\t\t\t\t\toperations,\n\t\t\t\t\t\tt,\n\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\tonBusyChange: setListBusy\n\t\t\t\t\t}) : null,\n\t\t\t\t\tfailure !== void 0 ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: failure\n\t\t\t\t\t}) : null,\n\t\t\t\t\thint === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\tchildren: hint\n\t\t\t\t\t}),\n\t\t\t\t\t(0, react_jsx_runtime.jsx)(EditorFooter, {\n\t\t\t\t\t\tt,\n\t\t\t\t\t\tbusy,\n\t\t\t\t\t\tsubmitDisabled: disabled || listBusy || !ready,\n\t\t\t\t\t\tsubmitLabelKey: \"create\",\n\t\t\t\t\t\tsubmitBusyLabelKey: \"creating\",\n\t\t\t\t\t\tonCancel: () => {\n\t\t\t\t\t\t\tprops.onClose(committed);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonSubmit: () => {\n\t\t\t\t\t\t\tcreate();\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t]\n\t\t\t});\n\t\t}",
|
|
805
|
+
"after": "function CustomProviderCard(props) {\n\t\t\tconst { taken, protocols, reasoningLevels, operations, t, onBusyChange } = props;\n\t\t\tconst supportsMultiKey = supportsMultiKeySchema(props.namespace, props.schema, [\"providers\", PROBE_ROUTE]);\n\t\t\tconst [openedAt] = (0, react.useState)(() => props.revision);\n\t\t\tconst [route, setRoute] = (0, react.useState)(\"\");\n\t\t\tconst [displayName, setDisplayName] = (0, react.useState)(\"\");\n\t\t\tconst [baseURL, setBaseURL] = (0, react.useState)(\"\");\n\t\t\tconst [protocol, setProtocol] = (0, react.useState)(protocols[0] ?? \"\");\n\t\t\tconst [keyDraft, setKeyDraft] = (0, react.useState)(\"\");\n\t\t\tconst [models, setModels] = (0, react.useState)([]);\n\t\t\tconst [multiKey, setMultiKey] = (0, react.useState)(false);\n\t\t\tconst [keyEntries, setKeyEntries] = (0, react.useState)({});\n\t\t\tconst [entryKeyDrafts, setEntryKeyDrafts] = (0, react.useState)({});\n\t\t\tconst [entryConfirmations, setEntryConfirmations] = (0, react.useState)({});\n\t\t\tconst [entrySaveState, setEntrySaveState] = (0, react.useState)(void 0);\n\t\t\tconst saving = (0, react.useRef)(false);\n\t\t\tconst [busy, setBusy] = (0, react.useState)(false);\n\t\t\tconst [listBusy, setListBusy] = (0, react.useState)(false);\n\t\t\t(0, react.useEffect)(() => {\n\t\t\t\tonBusyChange?.(busy || listBusy);\n\t\t\t}, [\n\t\t\t\tbusy,\n\t\t\t\tlistBusy,\n\t\t\t\tonBusyChange\n\t\t\t]);\n\t\t\tconst [failure, setFailure] = (0, react.useState)(void 0);\n\t\t\t/**\n\t\t\t* The profile write landed. Only the key write can still be outstanding, so\n\t\t\t* the fields that describe the provider are settled and the retry path is\n\t\t\t* the credential alone.\n\t\t\t*/\n\t\t\tconst [committed, setCommitted] = (0, react.useState)(false);\n\t\t\tconst disabled = props.readOnly || busy;\n\t\t\t/** Everything but the key stops being editable once the provider exists. */\n\t\t\tconst profileDisabled = disabled || committed;\n\t\t\tconst routeInvalid = route.length > 0 && !ROUTE_PATTERN.test(route);\n\t\t\tconst routeTaken = taken.includes(route);\n\t\t\tconst normalizedBaseURL = baseURL.trim();\n\t\t\tconst baseUrlInvalid = baseURL.length > 0 && !isHttpUrl(normalizedBaseURL);\n\t\t\tconst modelFailure = multiKey ? void 0 : validateDeepSeekModels(models) ?? validateReasoningEfforts(models);\n\t\t\tconst entryFailure = multiKey ? multiKeyFailure(route, keyEntries, entryKeyDrafts, entryConfirmations, t) : void 0;\n\t\t\tconst keyFailure = multiKey ? void 0 : apiKeyFailure(keyDraft);\n\t\t\tconst keyValue = keyDraft.trim();\n\t\t\tconst ready = (committed || route.length > 0 && !routeInvalid && !routeTaken) && normalizedBaseURL.length > 0 && !baseUrlInvalid && (multiKey ? entryFailure === void 0 : models.length > 0 && modelFailure === void 0 && keyFailure === void 0);\n\t\t\tconst hint = entryFailure ?? (failure !== void 0 || ready || keyFailure !== void 0 || route.length === 0 || routeInvalid || routeTaken || baseUrlInvalid ? void 0 : normalizedBaseURL.length === 0 ? t(\"customNeedsBaseUrl\") : modelFailure !== void 0 ? `${t(\"model\")} ${String(modelFailure.index + 1)}: ${t(modelFailure.key)}` : t(\"customNeedsModels\"));\n\t\t\t/** Perform the create, returning a failure message or undefined. */\n\t\t\tconst createOnce = async () => {\n\t\t\t\tconst entries = normalizedMultiKeyEntries(route, keyEntries);\n\t\t\t\tconst firstEntry = Object.values(entries)[0];\n\t\t\t\tconst keyRef = multiKey ? firstEntry?.apiKeyEnv : deriveKeyRef(route);\n\t\t\t\tconst storesKey = !multiKey && keyValue.length > 0;\n\t\t\t\tif (multiKey && entryFailure !== void 0) return entryFailure;\n\t\t\t\tif (!committed) {\n\t\t\t\t\tconst profile = {\n\t\t\t\t\t\t...displayName.length === 0 ? {} : { displayName },\n\t\t\t\t\t\t...storesKey || multiKey ? { apiKeyEnv: keyRef } : {},\n\t\t\t\t\t\tapi: protocol,\n\t\t\t\t\t\tbaseURL: normalizedBaseURL,\n\t\t\t\t\t\tmodels: (multiKey ? firstEntry.models : models).map((model) => ({ ...model })),\n\t\t\t\t\t\t...(multiKey || Object.keys(keyEntries).length > 0 ? { multiKey, keyEntries: entries } : {})\n\t\t\t\t\t};\n\t\t\t\t\tconst written = await operations.writeSettings(NS$1, [{\n\t\t\t\t\t\top: \"set\",\n\t\t\t\t\t\tpath: [\"providers\", route],\n\t\t\t\t\t\tvalue: profile\n\t\t\t\t\t}], openedAt);\n\t\t\t\t\tif (written.kind !== \"written\") return written.kind === \"conflict\" ? t(\"conflict\") : written.message;\n\t\t\t\t\tsetCommitted(true);\n\t\t\t\t}\n\t\t\t\tif (multiKey) return storeMultiKeyDrafts(operations, entries, entryKeyDrafts, setEntryKeyDrafts);\n\t\t\t\tif (storesKey) {\n\t\t\t\t\tconst stored = await operations.storeCredential(keyRef, keyValue);\n\t\t\t\t\tif (stored !== void 0) return stored;\n\t\t\t\t\tsetKeyDraft(\"\");\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst create = async () => {\n\t\t\t\tif (saving.current || !ready || props.readOnly || listBusy) return;\n\t\t\t\tsaving.current = true;\n\t\t\t\tsetBusy(true);\n\t\t\t\tsetFailure(void 0);\n\t\t\t\ttry {\n\t\t\t\t\tconst outcome = await createOnce();\n\t\t\t\t\tif (multiKey) setEntrySaveState({ ok: outcome === void 0, entries: structuredClone(outcome === void 0 ? normalizedMultiKeyEntries(route, keyEntries) : keyEntries) });\n\t\t\t\t\tif (outcome !== void 0) {\n\t\t\t\t\t\tsetFailure(outcome);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tprops.onClose(true);\n\t\t\t\t} catch {\n\t\t\t\t\tif (multiKey) setEntrySaveState({ ok: false, entries: structuredClone(keyEntries) });\n\t\t\t\t\tsetFailure(t(\"multiKeySaveFailed\"));\n\t\t\t\t} finally {\n\t\t\t\t\tsaving.current = false;\n\t\t\t\t\tsetBusy(false);\n\t\t\t\t}\n\t\t\t};\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\tclassName: ModelsSection_module_css_default[\"editor\"],\n\t\t\t\tchildren: [\n\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: t(\"customRoute\")\n\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\tvalue: route,\n\t\t\t\t\t\t\tplaceholder: \"acme-gateway\",\n\t\t\t\t\t\t\t\"aria-label\": t(\"customRoute\"),\n\t\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetRoute(event.target.value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})]\n\t\t\t\t\t}),\n\t\t\t\t\trouteInvalid || routeTaken ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: t(routeInvalid ? \"customRouteInvalid\" : \"customRouteTaken\")\n\t\t\t\t\t}) : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\tchildren: t(\"customRouteHint\")\n\t\t\t\t\t}),\n\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: t(\"customDisplayName\")\n\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\tvalue: displayName,\n\t\t\t\t\t\t\tplaceholder: route.length === 0 ? t(\"customDisplayName\") : route,\n\t\t\t\t\t\t\t\"aria-label\": t(\"customDisplayName\"),\n\t\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetDisplayName(event.target.value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})]\n\t\t\t\t\t}),\n\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: t(\"baseUrl\")\n\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\tvalue: baseURL,\n\t\t\t\t\t\t\tplaceholder: t(protocol === \"anthropic-messages\" ? \"customAnthropicBaseUrlPlaceholder\" : \"customBaseUrlPlaceholder\"),\n\t\t\t\t\t\t\t\"aria-label\": t(\"baseUrl\"),\n\t\t\t\t\t\t\t\"aria-invalid\": baseUrlInvalid,\n\t\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetBaseURL(event.target.value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})]\n\t\t\t\t\t}),\n\t\t\t\t\tbaseUrlInvalid ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: t(\"customBaseUrlInvalid\")\n\t\t\t\t\t}) : null,\n\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: t(\"customApi\")\n\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"select\", {\n\t\t\t\t\t\t\tclassName: `${ModelsSection_module_css_default[\"input\"]} ${ModelsSection_module_css_default[\"selectInput\"]}`,\n\t\t\t\t\t\t\tvalue: protocol,\n\t\t\t\t\t\t\t\"aria-label\": t(\"customApi\"),\n\t\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetProtocol(event.target.value);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tchildren: protocols.map((choice) => (0, react_jsx_runtime.jsx)(\"option\", {\n\t\t\t\t\t\t\t\tvalue: choice,\n\t\t\t\t\t\t\t\tchildren: protocolLabel(t, choice)\n\t\t\t\t\t\t\t}, choice))\n\t\t\t\t\t\t})]\n\t\t\t\t\t}),\n\t\t\t\t\tsupportsMultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyToggle, {\n\t\t\t\t\t\tt, checked: multiKey, disabled: profileDisabled || listBusy, hasUnsavedKeys: hasMultiKeyDrafts(entryKeyDrafts),\n\t\t\t\t\t\tonChange: (enabled) => {\n\t\t\t\t\t\t\tif (enabled && Object.keys(keyEntries).length === 0) {\n\t\t\t\t\t\t\t\tconst [id, entry] = newMultiKeyEntry(route, { name: displayName || route || t(\"multiKeyDefaultName\"), models });\n\t\t\t\t\t\t\t\tsetKeyEntries({ [id]: entry });\n\t\t\t\t\t\t\t\tif (keyDraft.length > 0) setEntryKeyDrafts({ [id]: keyDraft });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsetMultiKey(enabled);\n\t\t\t\t\t\t}\n\t\t\t\t\t}) : null,\n\t\t\t\t\tmultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyEntriesEditor, {\n\t\t\t\t\t\troute, entries: keyEntries, protocols, saveState: entrySaveState, savedEntries: entrySaveState?.ok ? entrySaveState.entries : void 0, onChange: setKeyEntries,\n\t\t\t\t\t\tkeyDrafts: entryKeyDrafts, onKeyDraftsChange: setEntryKeyDrafts,\n\t\t\t\t\t\tconfirmations: entryConfirmations, onConfirmationsChange: setEntryConfirmations,\n\t\t\t\t\t\tpersistedEntries: committed ? normalizedMultiKeyEntries(route, keyEntries) : {},\n\t\t\t\t\t\tprobe: { settingsNs: NS$1, ...(committed ? { provider: route } : {}), baseURL: normalizedBaseURL, api: protocol },\n\t\t\t\t\t\tprobeBlocked: baseUrlInvalid ? \"customBaseUrlInvalid\" : normalizedBaseURL.length === 0 ? \"customNeedsBaseUrl\" : void 0,\n\t\t\t\t\t\treasoningLevels, operations, t, disabled: profileDisabled || listBusy, keyDisabled: disabled || listBusy, onBusyChange: setListBusy\n\t\t\t\t\t}) : null,\n\t\t\t\t\tmultiKey ? null : (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\tchildren: t(\"keyInput\")\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ApiKeyInput, {\n\t\t\t\t\t\t\t\tt,\n\t\t\t\t\t\t\t\tvalue: keyDraft,\n\t\t\t\t\t\t\t\tplaceholder: t(\"keyPlaceholder\"),\n\t\t\t\t\t\t\t\t\"aria-label\": t(\"keyInput\"),\n\t\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\tsetKeyDraft(event.target.value);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tkeyFailure === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\t\t\tchildren: t(keyFailure === \"keyBlank\" ? \"keyBlankNew\" : keyFailure)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t]\n\t\t\t\t\t}),\n\t\t\t\t\t!multiKey ? (0, react_jsx_runtime.jsx)(ModelListEditor, {\n\t\t\t\t\t\tmodels,\n\t\t\t\t\t\tonChange: setModels,\n\t\t\t\t\t\treasoningLevels,\n\t\t\t\t\t\tprobe: {\n\t\t\t\t\t\t\tsettingsNs: NS$1,\n\t\t\t\t\t\t\tbaseURL: normalizedBaseURL,\n\t\t\t\t\t\t\tapi: protocol,\n\t\t\t\t\t\t\t...keyValue.length === 0 ? {} : { apiKey: keyValue }\n\t\t\t\t\t\t},\n\t\t\t\t\t\tprobeBlocked: baseUrlInvalid ? \"customBaseUrlInvalid\" : keyFailure === \"keyBlank\" ? \"keyBlankNew\" : keyFailure,\n\t\t\t\t\t\toperations,\n\t\t\t\t\t\tt,\n\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\tonBusyChange: setListBusy\n\t\t\t\t\t}) : null,\n\t\t\t\t\tfailure !== void 0 ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: failure\n\t\t\t\t\t}) : null,\n\t\t\t\t\thint === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\tchildren: hint\n\t\t\t\t\t}),\n\t\t\t\t\t(0, react_jsx_runtime.jsx)(EditorFooter, {\n\t\t\t\t\t\tt,\n\t\t\t\t\t\tbusy,\n\t\t\t\t\t\tsubmitDisabled: disabled || listBusy || !ready,\n\t\t\t\t\t\tsubmitLabelKey: \"create\",\n\t\t\t\t\t\tsubmitBusyLabelKey: \"creating\",\n\t\t\t\t\t\tonCancel: () => {\n\t\t\t\t\t\t\tprops.onClose(committed);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonSubmit: () => {\n\t\t\t\t\t\t\tcreate();\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t]\n\t\t\t});\n\t\t}"
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
"before": "function ProviderEditor(props) {\n\t\t\tconst { namespace, schema, settingsPath, operations, t } = props;\n\t\t\tconst [draft, setDraft] = (0, react.useState)(() => draftAt(schema, namespace, settingsPath));\n\t\t\tconst [entryKeyDrafts, setEntryKeyDrafts] = (0, react.useState)({});\n\t\t\tconst [entryConfirmations, setEntryConfirmations] = (0, react.useState)({});\n\t\t\tconst saving = (0, react.useRef)(false);\n\t\t\tconst [keyDraft, setKeyDraft] = (0, react.useState)(\"\");\n\t\t\tconst [busy, setBusy] = (0, react.useState)(false);\n\t\t\tconst [listBusy, setListBusy] = (0, react.useState)(false);\n\t\t\tconst { onBusyChange } = props;\n\t\t\t(0, react.useEffect)(() => {\n\t\t\t\tonBusyChange?.(busy || listBusy);\n\t\t\t}, [\n\t\t\t\tbusy,\n\t\t\t\tlistBusy,\n\t\t\t\tonBusyChange\n\t\t\t]);\n\t\t\tconst [failure, setFailure] = (0, react.useState)(void 0);\n\t\t\tconst [committedOriginal, setCommittedOriginal] = (0, react.useState)(() => schema.getPath(namespace.user, settingsPath));\n\t\t\tconst [expectedRevision, setExpectedRevision] = (0, react.useState)(() => namespace.revision);\n\t\t\tconst root = (0, react.useMemo)(() => schema.rehydrate(namespace.schema), [namespace.schema, schema]);\n\t\t\tconst node = (0, react.useMemo)(() => schema.nodeAtPath(root, settingsPath), [\n\t\t\t\troot,\n\t\t\t\tschema,\n\t\t\t\tsettingsPath\n\t\t\t]);\n\t\t\tconst fallback = schema.getPath(namespace.value, settingsPath);\n\t\t\tconst disabled = props.readOnly || busy;\n\t\t\tconst layout = layoutOf(namespace.ns);\n\t\t\tconst keyRef = refFor(schema, namespace, settingsPath, props.provider);\n\t\t\tconst supportsMultiKey = layout === \"pi-ai\" && props.declared === true && props.credentialOnly !== true && supportsMultiKeySchema(namespace, schema, settingsPath);\n\t\t\tconst multiKey = supportsMultiKey && (draft.multiKey ?? fallback?.multiKey) === true;\n\t\t\tconst keyEntries = draft.keyEntries ?? fallback?.keyEntries ?? {};\n\t\t\tconst entryFailure = multiKey ? multiKeyFailure(props.provider, keyEntries, entryKeyDrafts, entryConfirmations, t) : void 0;\n\t\t\tconst protocols = (0, react.useMemo)(() => layout === \"pi-ai\" ? protocolChoices(namespace, schema) : [], [\n\t\t\t\tlayout,\n\t\t\t\tnamespace,\n\t\t\t\tschema\n\t\t\t]);\n\t\t\tconst stringAt = (source, key) => {\n\t\t\t\tconst value = schema.getPath(source, [key]);\n\t\t\t\treturn typeof value === \"string\" && value.trim().length > 0 ? value : void 0;\n\t\t\t};\n\t\t\tconst setField = (key, next) => {\n\t\t\t\tconst value = next === void 0 || next.trim().length === 0 ? void 0 : next;\n\t\t\t\tsetDraft((current) => value === void 0 ? schema.deletePath(current, [key]) : schema.setPath(current, [key], value));\n\t\t\t};\n\t\t\tconst reasoningLevels = (0, react.useMemo)(() => layout === \"pi-ai\" && props.declared === true ? reasoningLevelChoices(namespace, schema) : [], [\n\t\t\t\tlayout,\n\t\t\t\tprops.declared,\n\t\t\t\tnamespace,\n\t\t\t\tschema\n\t\t\t]);\n\t\t\tconst editsReasoning = reasoningLevels.length > 0;\n\t\t\tconst validateModels = (value) => validateDeepSeekModels(value) ?? (editsReasoning ? validateReasoningEfforts(value) : void 0);\n\t\t\tconst modelFailure = multiKey ? void 0 : validateModels(schema.getPath(draft, [\"models\"]));\n\t\t\tconst keyFailure = multiKey ? void 0 : apiKeyFailure(keyDraft);\n\t\t\tconst keyValue = keyDraft.trim();\n\t\t\tconst shownKeyFailure = (props.credentialRequired === true && keyDraft.length > 0 && keyValue.length === 0 ? \"keyRequired\" : void 0) ?? keyFailure;\n\t\t\tconst probeApi = stringAt(draft, \"api\") ?? stringAt(fallback, \"api\");\n\t\t\tconst probeBaseURL = stringAt(draft, \"baseURL\") ?? stringAt(fallback, \"baseURL\");\n\t\t\tconst probe = {\n\t\t\t\tsettingsNs: namespace.ns,\n\t\t\t\tprovider: props.provider,\n\t\t\t\t...probeBaseURL === void 0 ? {} : { baseURL: probeBaseURL },\n\t\t\t\t...probeApi === void 0 ? {} : { api: probeApi },\n\t\t\t\t...keyValue.length === 0 ? {} : { apiKey: keyValue }\n\t\t\t};\n\t\t\t/**\n\t\t\t* The write for this card, or a failure message. Every edit travels as\n\t\t\t* path ops against the STORED section: the draft comes from the redacted\n\t\t\t* descriptor, so a wholesale replace rebuilt from it could delete fields\n\t\t\t* outside the card. Ops name only the fields this card can see.\n\t\t\t*/\n\t\t\tconst applyOnce = async () => {\n\t\t\t\tconst ns = namespace.ns;\n\t\t\t\tconst normalizedDraft = supportsMultiKey && schema.hasPath(draft, [\"keyEntries\"]) ? schema.setPath(draft, [\"keyEntries\"], normalizedMultiKeyEntries(props.provider, keyEntries)) : draft;\n\t\t\t\tconst next = multiKey ? schema.setPath(normalizedDraft, [\"keyEntries\"], normalizedMultiKeyEntries(props.provider, keyEntries)) : layout === \"pi-ai\" && stringAt(draft, \"apiKeyEnv\") === void 0 && stringAt(fallback, \"apiKeyEnv\") === void 0 && keyValue.length > 0 ? schema.setPath(normalizedDraft, [\"apiKeyEnv\"], keyRef) : normalizedDraft;\n\t\t\t\tif (entryFailure !== void 0) return entryFailure;\n\t\t\t\tif (props.credentialOnly !== true && !multiKey) {\n\t\t\t\t\tconst failure = validateModels(schema.getPath(next, [\"models\"]));\n\t\t\t\t\t/* v8 ignore next 3 -- unreachable from the card: the same failure disables submit */\n\t\t\t\t\tif (failure !== void 0) return `${t(\"model\")} ${String(failure.index + 1)}: ${t(failure.key)}`;\n\t\t\t\t}\n\t\t\t\t/* v8 ignore next -- apply is only reachable from the rendered card, which required a resolved node */\n\t\t\t\tif (props.credentialOnly !== true && node !== void 0 && settingsPath.length === 0) {\n\t\t\t\t\tconst sectionError = schema.validate(node, next);\n\t\t\t\t\tif (sectionError !== void 0) return sectionError;\n\t\t\t\t}\n\t\t\t\tconst materializesNativeProfile = layout === \"pi-ai\" && fallback === void 0 && committedOriginal === void 0 && Object.keys(next).length === 0;\n\t\t\t\tconst ops = props.credentialOnly === true ? [] : materializesNativeProfile ? [{\n\t\t\t\t\top: \"set\",\n\t\t\t\t\tpath: [...settingsPath],\n\t\t\t\t\tvalue: {}\n\t\t\t\t}] : pathOps(settingsPath, committedOriginal, next);\n\t\t\t\tif (ops.length > 0) {\n\t\t\t\t\tconst written = await operations.writeSettings(ns, ops, expectedRevision);\n\t\t\t\t\tif (written.kind !== \"written\") return written.kind === \"conflict\" ? t(\"conflict\") : written.message;\n\t\t\t\t\tsetCommittedOriginal(schema.getPath(written.view.user, settingsPath));\n\t\t\t\t\tsetExpectedRevision(written.view.revision);\n\t\t\t\t\tsetDraft(next);\n\t\t\t\t}\n\t\t\t\tif (multiKey) return storeMultiKeyDrafts(operations, next.keyEntries, entryKeyDrafts, setEntryKeyDrafts);\n\t\t\t\tif (keyValue.length > 0) {\n\t\t\t\t\tconst stored = await operations.storeCredential(keyRef, keyValue);\n\t\t\t\t\tif (stored !== void 0) return stored;\n\t\t\t\t}\n\t\t\t\tsetKeyDraft(\"\");\n\t\t\t};\n\t\t\tconst apply = async () => {\n\t\t\t\tif (saving.current || props.readOnly || listBusy || entryFailure !== void 0) return;\n\t\t\t\tsaving.current = true;\n\t\t\t\tsetBusy(true);\n\t\t\t\tsetFailure(void 0);\n\t\t\t\ttry {\n\t\t\t\t\tconst failure = await applyOnce();\n\t\t\t\t\tif (failure !== void 0) {\n\t\t\t\t\t\tsetFailure(failure);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tprops.onClose(true);\n\t\t\t\t} catch {\n\t\t\t\t\tsetFailure(t(\"multiKeySaveFailed\"));\n\t\t\t\t} finally {\n\t\t\t\t\tsaving.current = false;\n\t\t\t\t\tsetBusy(false);\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (node === void 0) return (0, react_jsx_runtime.jsxs)(\"p\", {\n\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\tchildren: [\n\t\t\t\t\tprops.provider,\n\t\t\t\t\t\": \",\n\t\t\t\t\tprops.t(\"settingsPathUnresolvable\")\n\t\t\t\t]\n\t\t\t});\n\t\t\t/**\n\t\t\t* The catalog beneath the user layer: what the composition entry pinned, or\n\t\t\t* else the schema default that `resolve` would supply. The effective value\n\t\t\t* cannot answer this — it still carries the stored override until the unset\n\t\t\t* is applied, so reading it would echo that override straight back the\n\t\t\t* moment reset drops it, leaving the rows unchanged until a reload.\n\t\t\t*/\n\t\t\tconst inheritedModels = () => {\n\t\t\t\treturn schema.getPath(namespace.base, [...settingsPath, \"models\"]) ?? schema.nodeAtPath(root, [...settingsPath, \"models\"])?.meta.default;\n\t\t\t};\n\t\t\t/**\n\t\t\t* The curated fields of one known adapter family. The family arrives\n\t\t\t* narrowed so the per-family branches below are total: an unknown namespace\n\t\t\t* renders the hint instead and never reaches this body.\n\t\t\t*/\n\t\t\tconst curatedFields = (family) => {\n\t\t\t\tconst ownsIdentity = family === \"pi-ai\" && props.declared === true;\n\t\t\t\tconst customModels = schema.getPath(draft, [\"models\"]);\n\t\t\t\tconst modelsOverridden = schema.hasPath(draft, [\"models\"]);\n\t\t\t\tconst models = modelDrafts(modelsOverridden ? customModels : inheritedModels());\n\t\t\t\tconst defaultContextWindow = schema.getPath(fallback, [\"defaultContextWindow\"]);\n\t\t\t\tconst defaultMaxTokens = schema.getPath(fallback, [\"maxTokens\"]);\n\t\t\t\tconst defaultInput = schema.getPath(fallback, [\"defaultInput\"]);\n\t\t\t\tconst baseURL = stringAt(fallback, \"baseURL\") ?? props.defaultBaseURL;\n\t\t\t\tconst endpointEnv = props.baseURLEnv ?? [];\n\t\t\t\tconst endpointHint = family === \"deepseek\" ? t(\"deepSeekEndpointHint\") : baseURL === void 0 && endpointEnv.length > 0 ? t(\"baseUrlEnvironment\").replace(\"{env}\", () => endpointEnv.join(\", \")) : void 0;\n\t\t\t\tconst namedRef = stringAt(fallback, \"apiKeyEnv\");\n\t\t\t\tconst nativeAuth = namedRef === void 0 ? props.nativeAuth : void 0;\n\t\t\t\tconst authRefs = namedRef === void 0 ? (nativeAuth?.env ?? []).filter((ref) => !endpointEnv.includes(ref)) : [namedRef];\n\t\t\t\tconst visibleRefs = authRefs.filter((ref) => !ref.toLowerCase().includes(\"oauth\"));\n\t\t\t\tconst keyHint = visibleRefs[0];\n\t\t\t\tconst checkedRefs = authRefs.map((ref) => [ref, props.credentialChecks?.[ref] ?? (ref === namedRef ? props.credential : void 0)]);\n\t\t\t\tconst detected = checkedRefs.find(([, info]) => info?.configured === true);\n\t\t\t\tconst detectedRef = detected?.[0];\n\t\t\t\tconst detectedVisibleRef = detectedRef === void 0 || !visibleRefs.includes(detectedRef) ? void 0 : detectedRef;\n\t\t\t\tconst missingRefs = checkedRefs.length > 0 && checkedRefs.every(([, info]) => info?.configured === false);\n\t\t\t\tconst savedCredential = detected?.[1]?.source === \"file\";\n\t\t\t\tconst credentialHint = keyDraft.length > 0 || savedCredential || keyHint === void 0 || props.credentialRequired === true ? void 0 : t(detectedRef === void 0 ? missingRefs ? \"keyFallbackMissing\" : \"keyFallbackUnchecked\" : detectedVisibleRef === void 0 ? \"keyFallbackDetectedHidden\" : \"keyFallbackDetected\").replace(\"{hint}\", () => detectedVisibleRef ?? keyHint);\n\t\t\t\tconst keyHelp = visibleRefs.length === 0 ? void 0 : t(\"keyHelp\").replace(\"{env}\", () => visibleRefs.join(\" / \"));\n\t\t\t\tconst authHelp = keyHelp === void 0 ? null : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {\n\t\t\t\t\tlabel: keyHelp,\n\t\t\t\t\tside: \"right\",\n\t\t\t\t\tdelayMs: 0,\n\t\t\t\t\tfocusDelayMs: 0,\n\t\t\t\t\tportal: true,\n\t\t\t\t\topenOnClick: true,\n\t\t\t\t\tchildren: (0, react_jsx_runtime.jsx)(\"button\", {\n\t\t\t\t\t\ttype: \"button\",\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"helpButton\"],\n\t\t\t\t\t\t\"aria-label\": t(\"authHelp\"),\n\t\t\t\t\t\tchildren: \"?\"\n\t\t\t\t\t})\n\t\t\t\t});\n\t\t\t\tconst keylessNativeAuth = nativeAuth?.env.length === 0 && nativeAuth.oauth;\n\t\t\t\tconst keyPlaceholder = keyHint === void 0 || props.credentialRequired === true ? t(\"keyPlaceholder\") : t(savedCredential ? \"keyPlaceholderSaved\" : \"keyPlaceholderFallback\").replace(\"{hint}\", () => keyHint);\n\t\t\t\t/** What both family editors take: the rows, whose layer owns them, and the two writes. */\n\t\t\t\tconst catalogProps = {\n\t\t\t\t\tmodels,\n\t\t\t\t\toverridden: modelsOverridden,\n\t\t\t\t\tt,\n\t\t\t\t\tdisabled,\n\t\t\t\t\tonChange: (next) => {\n\t\t\t\t\t\tsetDraft((current) => schema.setPath(current, [\"models\"], next));\n\t\t\t\t\t},\n\t\t\t\t\tonReset: () => {\n\t\t\t\t\t\tsetDraft((current) => schema.deletePath(current, [\"models\"]));\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tconst credentials = (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [supportsMultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyToggle, {\n\t\t\t\t\tt, checked: multiKey, disabled: disabled || listBusy, hasUnsavedKeys: hasMultiKeyDrafts(entryKeyDrafts),\n\t\t\t\t\tonChange: (enabled) => {\n\t\t\t\t\t\tlet updated = schema.setPath(draft, [\"multiKey\"], enabled);\n\t\t\t\t\t\tif (enabled && Object.keys(keyEntries).length === 0) {\n\t\t\t\t\t\t\tconst namedRef = stringAt(draft, \"apiKeyEnv\") ?? stringAt(fallback, \"apiKeyEnv\");\n\t\t\t\t\t\t\tconst [id, entry] = newMultiKeyEntry(props.provider, {\n\t\t\t\t\t\t\t\tname: stringAt(draft, \"displayName\") ?? stringAt(fallback, \"displayName\") ?? props.displayName ?? props.provider,\n\t\t\t\t\t\t\t\tapiKeyEnv: namedRef,\n\t\t\t\t\t\t\t\tmodels: draft.models ?? fallback?.models ?? inheritedModels()\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (keyDraft.length > 0) {\n\t\t\t\t\t\t\t\tsetEntryKeyDrafts({ [id]: keyDraft });\n\t\t\t\t\t\t\t\tif (namedRef === void 0) updated = schema.setPath(updated, [\"apiKeyEnv\"], multiKeyRef(props.provider, id));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tupdated = schema.setPath(updated, [\"keyEntries\"], { [id]: entry });\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsetDraft(updated);\n\t\t\t\t\t}\n\t\t\t\t}) : null, multiKey ? (0, react_jsx_runtime.jsx)(MultiKeyEntriesEditor, {\n\t\t\t\t\troute: props.provider, entries: keyEntries,\n\t\t\t\t\tonChange: (entries) => setDraft((current) => schema.setPath(current, [\"keyEntries\"], entries)),\n\t\t\t\t\tkeyDrafts: entryKeyDrafts, onKeyDraftsChange: setEntryKeyDrafts,\n\t\t\t\t\tconfirmations: entryConfirmations, onConfirmationsChange: setEntryConfirmations,\n\t\t\t\t\tpersistedEntries: schema.getPath(committedOriginal, [\"keyEntries\"]) ?? fallback?.keyEntries ?? {},\n\t\t\t\t\tcredentialChecks: props.credentialChecks,\n\t\t\t\t\tprobe: { settingsNs: namespace.ns, provider: props.provider, ...(probeBaseURL === void 0 ? {} : { baseURL: probeBaseURL }), ...(probeApi === void 0 ? {} : { api: probeApi }) },\n\t\t\t\t\treasoningLevels, operations, t, disabled: disabled || listBusy, onBusyChange: setListBusy\n\t\t\t\t}) : null, multiKey || keylessNativeAuth ? null : (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: [t(\"keyInput\"), authHelp]\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ApiKeyInput, {\n\t\t\t\t\t\t\tt,\n\t\t\t\t\t\t\tvalue: keyDraft,\n\t\t\t\t\t\t\tplaceholder: keyPlaceholder,\n\t\t\t\t\t\t\t\"aria-label\": t(\"keyInput\"),\n\t\t\t\t\t\t\t\"aria-invalid\": shownKeyFailure !== void 0,\n\t\t\t\t\t\t\t\"aria-describedby\": credentialHint === void 0 ? void 0 : `${props.provider}-credential-hint`,\n\t\t\t\t\t\t\trequired: props.credentialRequired === true,\n\t\t\t\t\t\t\tautoFocus: props.autoFocusCredential === true,\n\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetKeyDraft(event.target.value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tcredentialHint === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\t\tid: `${props.provider}-credential-hint`,\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[missingRefs ? \"notice\" : detectedRef === void 0 ? \"advancedHint\" : \"savedNotice\"],\n\t\t\t\t\t\t\tchildren: credentialHint\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tshownKeyFailure === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\t\tchildren: t(shownKeyFailure)\n\t\t\t\t\t\t})\n\t\t\t\t\t]\n\t\t\t\t})] });\n\t\t\t\tconst customization = props.credentialOnly === true ? null : (0, react_jsx_runtime.jsxs)(\"details\", {\n\t\t\t\t\tclassName: ModelsSection_module_css_default[\"customized\"],\n\t\t\t\t\topen: supportsMultiKey ? true : void 0,\n\t\t\t\t\t\"data-multi-key-shared-settings\": supportsMultiKey ? true : void 0,\n\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"summary\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"customizedSummary\"],\n\t\t\t\t\t\tchildren: t(supportsMultiKey ? \"multiKeySharedSettings\" : \"customized\")\n\t\t\t\t\t}), (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"customizedBody\"],\n\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\townsIdentity ? (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\t\tchildren: t(\"customDisplayName\")\n\t\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\tvalue: stringAt(draft, \"displayName\") ?? \"\",\n\t\t\t\t\t\t\t\t\tplaceholder: stringAt(schema.getPath(namespace.base, settingsPath), \"displayName\") ?? props.provider,\n\t\t\t\t\t\t\t\t\t\"aria-label\": t(\"customDisplayName\"),\n\t\t\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\tsetField(\"displayName\", event.target.value);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t}) : null,\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\t\t\tchildren: t(\"baseUrl\")\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\t\tvalue: stringAt(draft, \"baseURL\") ?? \"\",\n\t\t\t\t\t\t\t\t\t\tplaceholder: family === \"deepseek\" ? t(\"deepSeekBaseUrl\") : baseURL === void 0 ? t(endpointEnv.length > 0 ? \"baseUrlConfigured\" : \"baseUrlDefault\") : t(\"baseUrlPlaceholder\").replace(\"{url}\", () => baseURL),\n\t\t\t\t\t\t\t\t\t\t\"aria-describedby\": endpointHint === void 0 ? void 0 : `${props.provider}-endpoint-hint`,\n\t\t\t\t\t\t\t\t\t\t\"aria-label\": t(\"baseUrl\"),\n\t\t\t\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\t\tsetField(\"baseURL\", event.target.value === \"\" ? void 0 : event.target.value);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\tendpointHint === void 0 ? null : (0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\t\t\tid: `${props.provider}-endpoint-hint`,\n\t\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\t\t\t\t\tchildren: endpointHint\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\townsIdentity ? (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\t\tchildren: t(\"customApi\")\n\t\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsxs)(\"select\", {\n\t\t\t\t\t\t\t\t\tclassName: `${ModelsSection_module_css_default[\"input\"]} ${ModelsSection_module_css_default[\"selectInput\"]}`,\n\t\t\t\t\t\t\t\t\tvalue: probeApi ?? \"\",\n\t\t\t\t\t\t\t\t\t\"aria-label\": t(\"customApi\"),\n\t\t\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\tsetField(\"api\", event.target.value);\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tchildren: [probeApi === void 0 ? (0, react_jsx_runtime.jsx)(\"option\", {\n\t\t\t\t\t\t\t\t\t\tvalue: \"\",\n\t\t\t\t\t\t\t\t\t\tchildren: t(\"customApiUnset\")\n\t\t\t\t\t\t\t\t\t}) : null, protocols.map((choice) => (0, react_jsx_runtime.jsx)(\"option\", {\n\t\t\t\t\t\t\t\t\t\tvalue: choice,\n\t\t\t\t\t\t\t\t\t\tchildren: protocolLabel(t, choice)\n\t\t\t\t\t\t\t\t\t}, choice))]\n\t\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t}) : null,\n\t\t\t\t\t\t\tmultiKey ? null : family === \"deepseek\" ? (0, react_jsx_runtime.jsx)(DeepSeekModelsEditor, {\n\t\t\t\t\t\t\t\t...catalogProps,\n\t\t\t\t\t\t\t\tdefaultContextWindow: typeof defaultContextWindow === \"number\" ? defaultContextWindow : void 0,\n\t\t\t\t\t\t\t\tdefaultMaxTokens: typeof defaultMaxTokens === \"number\" ? defaultMaxTokens : void 0\n\t\t\t\t\t\t\t}) : (0, react_jsx_runtime.jsx)(ModelListEditor, {\n\t\t\t\t\t\t\t\t...catalogProps,\n\t\t\t\t\t\t\t\tcatalogProvider: props.declared === true ? void 0 : props.provider,\n\t\t\t\t\t\t\t\treasoningLevels,\n\t\t\t\t\t\t\t\tdefaultInput: Array.isArray(defaultInput) ? defaultInput : void 0,\n\t\t\t\t\t\t\t\tprobe,\n\t\t\t\t\t\t\t\tprobeBlocked: keyFailure,\n\t\t\t\t\t\t\t\toperations,\n\t\t\t\t\t\t\t\tonBusyChange: setListBusy\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t]\n\t\t\t\t\t})]\n\t\t\t\t});\n\t\t\t\treturn (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: supportsMultiKey ? [customization, credentials] : [credentials, customization] });\n\t\t\t};\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\tclassName: props.credentialOnly === true ? ModelsSection_module_css_default[\"addBlock\"] : ModelsSection_module_css_default[\"editor\"],\n\t\t\t\tchildren: [\n\t\t\t\t\tprops.hideTitle === true ? null : (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"editorHeader\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"editorTitle\"],\n\t\t\t\t\t\t\tchildren: props.displayName\n\t\t\t\t\t\t}), props.provider !== props.displayName ? (0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"editorRoute\"],\n\t\t\t\t\t\t\tchildren: props.provider\n\t\t\t\t\t\t}) : null]\n\t\t\t\t\t}),\n\t\t\t\t\tlayout === \"unknown\" ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\tchildren: `${t(\"advancedHint\")} (${namespace.ns})`\n\t\t\t\t\t}) : curatedFields(layout),\n\t\t\t\t\t(failure ?? entryFailure) !== void 0 ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: failure ?? entryFailure\n\t\t\t\t\t}) : null,\n\t\t\t\t\tprops.credentialOnly === true || modelFailure === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\tchildren: `${t(\"model\")} ${String(modelFailure.index + 1)}: ${t(modelFailure.key)}`\n\t\t\t\t\t}),\n\t\t\t\t\t(0, react_jsx_runtime.jsx)(EditorFooter, {\n\t\t\t\t\t\tt,\n\t\t\t\t\t\tbusy,\n\t\t\t\t\t\tsubmitDisabled: disabled || listBusy || layout === \"unknown\" || entryFailure !== void 0 || props.credentialOnly !== true && modelFailure !== void 0 || !multiKey && (shownKeyFailure !== void 0 || props.credentialRequired === true && keyValue.length === 0),\n\t\t\t\t\t\tsubmitLabelKey: props.submitLabelKey ?? \"apply\",\n\t\t\t\t\t\tsubmitBusyLabelKey: props.submitBusyLabelKey ?? \"applying\",\n\t\t\t\t\t\t...props.cancelLabelKey === void 0 ? {} : { cancelLabelKey: props.cancelLabelKey },\n\t\t\t\t\t\tonCancel: () => {\n\t\t\t\t\t\t\tprops.onClose(false);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonSubmit: () => {\n\t\t\t\t\t\t\tprops.onSubmitCredential?.();\n\t\t\t\t\t\t\tapply();\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t]\n\t\t\t});\n\t\t}",
|
|
809
|
+
"after": "function ProviderEditor(props) {\n\t\t\tconst { namespace, schema, settingsPath, operations, t } = props;\n\t\t\tconst [draft, setDraft] = (0, react.useState)(() => draftAt(schema, namespace, settingsPath));\n\t\t\tconst [entryKeyDrafts, setEntryKeyDrafts] = (0, react.useState)({});\n\t\t\tconst [entryConfirmations, setEntryConfirmations] = (0, react.useState)({});\n\t\t\tconst [entrySaveState, setEntrySaveState] = (0, react.useState)(void 0);\n\t\t\tconst saving = (0, react.useRef)(false);\n\t\t\tconst [keyDraft, setKeyDraft] = (0, react.useState)(\"\");\n\t\t\tconst [busy, setBusy] = (0, react.useState)(false);\n\t\t\tconst [listBusy, setListBusy] = (0, react.useState)(false);\n\t\t\tconst { onBusyChange } = props;\n\t\t\t(0, react.useEffect)(() => {\n\t\t\t\tonBusyChange?.(busy || listBusy);\n\t\t\t}, [\n\t\t\t\tbusy,\n\t\t\t\tlistBusy,\n\t\t\t\tonBusyChange\n\t\t\t]);\n\t\t\tconst [failure, setFailure] = (0, react.useState)(void 0);\n\t\t\tconst [committedOriginal, setCommittedOriginal] = (0, react.useState)(() => schema.getPath(namespace.user, settingsPath));\n\t\t\tconst [expectedRevision, setExpectedRevision] = (0, react.useState)(() => namespace.revision);\n\t\t\tconst root = (0, react.useMemo)(() => schema.rehydrate(namespace.schema), [namespace.schema, schema]);\n\t\t\tconst node = (0, react.useMemo)(() => schema.nodeAtPath(root, settingsPath), [\n\t\t\t\troot,\n\t\t\t\tschema,\n\t\t\t\tsettingsPath\n\t\t\t]);\n\t\t\tconst fallback = schema.getPath(namespace.value, settingsPath);\n\t\t\tconst disabled = props.readOnly || busy;\n\t\t\tconst layout = layoutOf(namespace.ns);\n\t\t\tconst keyRef = refFor(schema, namespace, settingsPath, props.provider);\n\t\t\tconst supportsMultiKey = layout === \"pi-ai\" && props.declared === true && props.credentialOnly !== true && supportsMultiKeySchema(namespace, schema, settingsPath);\n\t\t\tconst multiKey = supportsMultiKey && (draft.multiKey ?? fallback?.multiKey) === true;\n\t\t\tconst keyEntries = draft.keyEntries ?? fallback?.keyEntries ?? {};\n\t\t\tconst entryFailure = multiKey ? multiKeyFailure(props.provider, keyEntries, entryKeyDrafts, entryConfirmations, t) : void 0;\n\t\t\tconst protocols = (0, react.useMemo)(() => layout === \"pi-ai\" ? protocolChoices(namespace, schema) : [], [\n\t\t\t\tlayout,\n\t\t\t\tnamespace,\n\t\t\t\tschema\n\t\t\t]);\n\t\t\tconst stringAt = (source, key) => {\n\t\t\t\tconst value = schema.getPath(source, [key]);\n\t\t\t\treturn typeof value === \"string\" && value.trim().length > 0 ? value : void 0;\n\t\t\t};\n\t\t\tconst setField = (key, next) => {\n\t\t\t\tconst value = next === void 0 || next.trim().length === 0 ? void 0 : next;\n\t\t\t\tsetDraft((current) => value === void 0 ? schema.deletePath(current, [key]) : schema.setPath(current, [key], value));\n\t\t\t};\n\t\t\tconst reasoningLevels = (0, react.useMemo)(() => layout === \"pi-ai\" && props.declared === true ? reasoningLevelChoices(namespace, schema) : [], [\n\t\t\t\tlayout,\n\t\t\t\tprops.declared,\n\t\t\t\tnamespace,\n\t\t\t\tschema\n\t\t\t]);\n\t\t\tconst editsReasoning = reasoningLevels.length > 0;\n\t\t\tconst validateModels = (value) => validateDeepSeekModels(value) ?? (editsReasoning ? validateReasoningEfforts(value) : void 0);\n\t\t\tconst modelFailure = multiKey ? void 0 : validateModels(schema.getPath(draft, [\"models\"]));\n\t\t\tconst keyFailure = multiKey ? void 0 : apiKeyFailure(keyDraft);\n\t\t\tconst keyValue = keyDraft.trim();\n\t\t\tconst shownKeyFailure = (props.credentialRequired === true && keyDraft.length > 0 && keyValue.length === 0 ? \"keyRequired\" : void 0) ?? keyFailure;\n\t\t\tconst probeApi = stringAt(draft, \"api\") ?? stringAt(fallback, \"api\");\n\t\t\tconst probeBaseURL = stringAt(draft, \"baseURL\") ?? stringAt(fallback, \"baseURL\");\n\t\t\tconst probe = {\n\t\t\t\tsettingsNs: namespace.ns,\n\t\t\t\tprovider: props.provider,\n\t\t\t\t...probeBaseURL === void 0 ? {} : { baseURL: probeBaseURL },\n\t\t\t\t...probeApi === void 0 ? {} : { api: probeApi },\n\t\t\t\t...keyValue.length === 0 ? {} : { apiKey: keyValue }\n\t\t\t};\n\t\t\t/**\n\t\t\t* The write for this card, or a failure message. Every edit travels as\n\t\t\t* path ops against the STORED section: the draft comes from the redacted\n\t\t\t* descriptor, so a wholesale replace rebuilt from it could delete fields\n\t\t\t* outside the card. Ops name only the fields this card can see.\n\t\t\t*/\n\t\t\tconst applyOnce = async () => {\n\t\t\t\tconst ns = namespace.ns;\n\t\t\t\tconst normalizedDraft = supportsMultiKey && schema.hasPath(draft, [\"keyEntries\"]) ? schema.setPath(draft, [\"keyEntries\"], normalizedMultiKeyEntries(props.provider, keyEntries)) : draft;\n\t\t\t\tconst next = multiKey ? schema.setPath(normalizedDraft, [\"keyEntries\"], normalizedMultiKeyEntries(props.provider, keyEntries)) : layout === \"pi-ai\" && stringAt(draft, \"apiKeyEnv\") === void 0 && stringAt(fallback, \"apiKeyEnv\") === void 0 && keyValue.length > 0 ? schema.setPath(normalizedDraft, [\"apiKeyEnv\"], keyRef) : normalizedDraft;\n\t\t\t\tif (entryFailure !== void 0) return entryFailure;\n\t\t\t\tif (props.credentialOnly !== true && !multiKey) {\n\t\t\t\t\tconst failure = validateModels(schema.getPath(next, [\"models\"]));\n\t\t\t\t\t/* v8 ignore next 3 -- unreachable from the card: the same failure disables submit */\n\t\t\t\t\tif (failure !== void 0) return `${t(\"model\")} ${String(failure.index + 1)}: ${t(failure.key)}`;\n\t\t\t\t}\n\t\t\t\t/* v8 ignore next -- apply is only reachable from the rendered card, which required a resolved node */\n\t\t\t\tif (props.credentialOnly !== true && node !== void 0 && settingsPath.length === 0) {\n\t\t\t\t\tconst sectionError = schema.validate(node, next);\n\t\t\t\t\tif (sectionError !== void 0) return sectionError;\n\t\t\t\t}\n\t\t\t\tconst materializesNativeProfile = layout === \"pi-ai\" && fallback === void 0 && committedOriginal === void 0 && Object.keys(next).length === 0;\n\t\t\t\tconst ops = props.credentialOnly === true ? [] : materializesNativeProfile ? [{\n\t\t\t\t\top: \"set\",\n\t\t\t\t\tpath: [...settingsPath],\n\t\t\t\t\tvalue: {}\n\t\t\t\t}] : pathOps(settingsPath, committedOriginal, next);\n\t\t\t\tif (ops.length > 0) {\n\t\t\t\t\tconst written = await operations.writeSettings(ns, ops, expectedRevision);\n\t\t\t\t\tif (written.kind !== \"written\") return written.kind === \"conflict\" ? t(\"conflict\") : written.message;\n\t\t\t\t\tsetCommittedOriginal(schema.getPath(written.view.user, settingsPath));\n\t\t\t\t\tsetExpectedRevision(written.view.revision);\n\t\t\t\t\tsetDraft(next);\n\t\t\t\t}\n\t\t\t\tif (multiKey) return storeMultiKeyDrafts(operations, next.keyEntries, entryKeyDrafts, setEntryKeyDrafts);\n\t\t\t\tif (keyValue.length > 0) {\n\t\t\t\t\tconst stored = await operations.storeCredential(keyRef, keyValue);\n\t\t\t\t\tif (stored !== void 0) return stored;\n\t\t\t\t}\n\t\t\t\tsetKeyDraft(\"\");\n\t\t\t};\n\t\t\tconst apply = async () => {\n\t\t\t\tif (saving.current || props.readOnly || listBusy || entryFailure !== void 0) return;\n\t\t\t\tsaving.current = true;\n\t\t\t\tsetBusy(true);\n\t\t\t\tsetFailure(void 0);\n\t\t\t\ttry {\n\t\t\t\t\tconst failure = await applyOnce();\n\t\t\t\t\tif (multiKey) setEntrySaveState({ ok: failure === void 0, entries: structuredClone(failure === void 0 ? normalizedMultiKeyEntries(props.provider, keyEntries) : keyEntries) });\n\t\t\t\t\tif (failure !== void 0) {\n\t\t\t\t\t\tsetFailure(failure);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (!multiKey) props.onClose(true);\n\t\t\t\t} catch {\n\t\t\t\t\tif (multiKey) setEntrySaveState({ ok: false, entries: structuredClone(keyEntries) });\n\t\t\t\t\tsetFailure(t(\"multiKeySaveFailed\"));\n\t\t\t\t} finally {\n\t\t\t\t\tsaving.current = false;\n\t\t\t\t\tsetBusy(false);\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (node === void 0) return (0, react_jsx_runtime.jsxs)(\"p\", {\n\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\tchildren: [\n\t\t\t\t\tprops.provider,\n\t\t\t\t\t\": \",\n\t\t\t\t\tprops.t(\"settingsPathUnresolvable\")\n\t\t\t\t]\n\t\t\t});\n\t\t\t/**\n\t\t\t* The catalog beneath the user layer: what the composition entry pinned, or\n\t\t\t* else the schema default that `resolve` would supply. The effective value\n\t\t\t* cannot answer this — it still carries the stored override until the unset\n\t\t\t* is applied, so reading it would echo that override straight back the\n\t\t\t* moment reset drops it, leaving the rows unchanged until a reload.\n\t\t\t*/\n\t\t\tconst inheritedModels = () => {\n\t\t\t\treturn schema.getPath(namespace.base, [...settingsPath, \"models\"]) ?? schema.nodeAtPath(root, [...settingsPath, \"models\"])?.meta.default;\n\t\t\t};\n\t\t\t/**\n\t\t\t* The curated fields of one known adapter family. The family arrives\n\t\t\t* narrowed so the per-family branches below are total: an unknown namespace\n\t\t\t* renders the hint instead and never reaches this body.\n\t\t\t*/\n\t\t\tconst curatedFields = (family) => {\n\t\t\t\tconst ownsIdentity = family === \"pi-ai\" && props.declared === true;\n\t\t\t\tconst customModels = schema.getPath(draft, [\"models\"]);\n\t\t\t\tconst modelsOverridden = schema.hasPath(draft, [\"models\"]);\n\t\t\t\tconst models = modelDrafts(modelsOverridden ? customModels : inheritedModels());\n\t\t\t\tconst defaultContextWindow = schema.getPath(fallback, [\"defaultContextWindow\"]);\n\t\t\t\tconst defaultMaxTokens = schema.getPath(fallback, [\"maxTokens\"]);\n\t\t\t\tconst defaultInput = schema.getPath(fallback, [\"defaultInput\"]);\n\t\t\t\tconst baseURL = stringAt(fallback, \"baseURL\") ?? props.defaultBaseURL;\n\t\t\t\tconst endpointEnv = props.baseURLEnv ?? [];\n\t\t\t\tconst endpointHint = family === \"deepseek\" ? t(\"deepSeekEndpointHint\") : baseURL === void 0 && endpointEnv.length > 0 ? t(\"baseUrlEnvironment\").replace(\"{env}\", () => endpointEnv.join(\", \")) : void 0;\n\t\t\t\tconst namedRef = stringAt(fallback, \"apiKeyEnv\");\n\t\t\t\tconst nativeAuth = namedRef === void 0 ? props.nativeAuth : void 0;\n\t\t\t\tconst authRefs = namedRef === void 0 ? (nativeAuth?.env ?? []).filter((ref) => !endpointEnv.includes(ref)) : [namedRef];\n\t\t\t\tconst visibleRefs = authRefs.filter((ref) => !ref.toLowerCase().includes(\"oauth\"));\n\t\t\t\tconst keyHint = visibleRefs[0];\n\t\t\t\tconst checkedRefs = authRefs.map((ref) => [ref, props.credentialChecks?.[ref] ?? (ref === namedRef ? props.credential : void 0)]);\n\t\t\t\tconst detected = checkedRefs.find(([, info]) => info?.configured === true);\n\t\t\t\tconst detectedRef = detected?.[0];\n\t\t\t\tconst detectedVisibleRef = detectedRef === void 0 || !visibleRefs.includes(detectedRef) ? void 0 : detectedRef;\n\t\t\t\tconst missingRefs = checkedRefs.length > 0 && checkedRefs.every(([, info]) => info?.configured === false);\n\t\t\t\tconst savedCredential = detected?.[1]?.source === \"file\";\n\t\t\t\tconst credentialHint = keyDraft.length > 0 || savedCredential || keyHint === void 0 || props.credentialRequired === true ? void 0 : t(detectedRef === void 0 ? missingRefs ? \"keyFallbackMissing\" : \"keyFallbackUnchecked\" : detectedVisibleRef === void 0 ? \"keyFallbackDetectedHidden\" : \"keyFallbackDetected\").replace(\"{hint}\", () => detectedVisibleRef ?? keyHint);\n\t\t\t\tconst keyHelp = visibleRefs.length === 0 ? void 0 : t(\"keyHelp\").replace(\"{env}\", () => visibleRefs.join(\" / \"));\n\t\t\t\tconst authHelp = keyHelp === void 0 ? null : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {\n\t\t\t\t\tlabel: keyHelp,\n\t\t\t\t\tside: \"right\",\n\t\t\t\t\tdelayMs: 0,\n\t\t\t\t\tfocusDelayMs: 0,\n\t\t\t\t\tportal: true,\n\t\t\t\t\topenOnClick: true,\n\t\t\t\t\tchildren: (0, react_jsx_runtime.jsx)(\"button\", {\n\t\t\t\t\t\ttype: \"button\",\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"helpButton\"],\n\t\t\t\t\t\t\"aria-label\": t(\"authHelp\"),\n\t\t\t\t\t\tchildren: \"?\"\n\t\t\t\t\t})\n\t\t\t\t});\n\t\t\t\tconst keylessNativeAuth = nativeAuth?.env.length === 0 && nativeAuth.oauth;\n\t\t\t\tconst keyPlaceholder = keyHint === void 0 || props.credentialRequired === true ? t(\"keyPlaceholder\") : t(savedCredential ? \"keyPlaceholderSaved\" : \"keyPlaceholderFallback\").replace(\"{hint}\", () => keyHint);\n\t\t\t\t/** What both family editors take: the rows, whose layer owns them, and the two writes. */\n\t\t\t\tconst catalogProps = {\n\t\t\t\t\tmodels,\n\t\t\t\t\toverridden: modelsOverridden,\n\t\t\t\t\tt,\n\t\t\t\t\tdisabled,\n\t\t\t\t\tonChange: (next) => {\n\t\t\t\t\t\tsetDraft((current) => schema.setPath(current, [\"models\"], next));\n\t\t\t\t\t},\n\t\t\t\t\tonReset: () => {\n\t\t\t\t\t\tsetDraft((current) => schema.deletePath(current, [\"models\"]));\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tconst credentials = (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [supportsMultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyToggle, {\n\t\t\t\t\tt, checked: multiKey, disabled: disabled || listBusy, hasUnsavedKeys: hasMultiKeyDrafts(entryKeyDrafts),\n\t\t\t\t\tonChange: (enabled) => {\n\t\t\t\t\t\tlet updated = schema.setPath(draft, [\"multiKey\"], enabled);\n\t\t\t\t\t\tif (enabled && Object.keys(keyEntries).length === 0) {\n\t\t\t\t\t\t\tconst namedRef = stringAt(draft, \"apiKeyEnv\") ?? stringAt(fallback, \"apiKeyEnv\");\n\t\t\t\t\t\t\tconst [id, entry] = newMultiKeyEntry(props.provider, {\n\t\t\t\t\t\t\t\tname: stringAt(draft, \"displayName\") ?? stringAt(fallback, \"displayName\") ?? props.displayName ?? props.provider,\n\t\t\t\t\t\t\t\tapiKeyEnv: namedRef,\n\t\t\t\t\t\t\t\tmodels: draft.models ?? fallback?.models ?? inheritedModels()\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (keyDraft.length > 0) {\n\t\t\t\t\t\t\t\tsetEntryKeyDrafts({ [id]: keyDraft });\n\t\t\t\t\t\t\t\tif (namedRef === void 0) updated = schema.setPath(updated, [\"apiKeyEnv\"], multiKeyRef(props.provider, id));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tupdated = schema.setPath(updated, [\"keyEntries\"], { [id]: entry });\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsetDraft(updated);\n\t\t\t\t\t}\n\t\t\t\t}) : null, multiKey ? (0, react_jsx_runtime.jsx)(MultiKeyEntriesEditor, {\n\t\t\t\t\troute: props.provider, entries: keyEntries, protocols, saveState: entrySaveState, savedEntries: entrySaveState?.ok ? entrySaveState.entries : void 0,\n\t\t\t\t\tonChange: (entries) => setDraft((current) => schema.setPath(current, [\"keyEntries\"], entries)),\n\t\t\t\t\tkeyDrafts: entryKeyDrafts, onKeyDraftsChange: setEntryKeyDrafts,\n\t\t\t\t\tconfirmations: entryConfirmations, onConfirmationsChange: setEntryConfirmations,\n\t\t\t\t\tpersistedEntries: schema.getPath(committedOriginal, [\"keyEntries\"]) ?? fallback?.keyEntries ?? {},\n\t\t\t\t\tcredentialChecks: props.credentialChecks,\n\t\t\t\t\tprobe: { settingsNs: namespace.ns, provider: props.provider, ...(probeBaseURL === void 0 ? {} : { baseURL: probeBaseURL }), ...(probeApi === void 0 ? {} : { api: probeApi }) },\n\t\t\t\t\treasoningLevels, operations, t, disabled: disabled || listBusy, onBusyChange: setListBusy\n\t\t\t\t}) : null, multiKey || keylessNativeAuth ? null : (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: [t(\"keyInput\"), authHelp]\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ApiKeyInput, {\n\t\t\t\t\t\t\tt,\n\t\t\t\t\t\t\tvalue: keyDraft,\n\t\t\t\t\t\t\tplaceholder: keyPlaceholder,\n\t\t\t\t\t\t\t\"aria-label\": t(\"keyInput\"),\n\t\t\t\t\t\t\t\"aria-invalid\": shownKeyFailure !== void 0,\n\t\t\t\t\t\t\t\"aria-describedby\": credentialHint === void 0 ? void 0 : `${props.provider}-credential-hint`,\n\t\t\t\t\t\t\trequired: props.credentialRequired === true,\n\t\t\t\t\t\t\tautoFocus: props.autoFocusCredential === true,\n\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetKeyDraft(event.target.value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tcredentialHint === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\t\tid: `${props.provider}-credential-hint`,\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[missingRefs ? \"notice\" : detectedRef === void 0 ? \"advancedHint\" : \"savedNotice\"],\n\t\t\t\t\t\t\tchildren: credentialHint\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tshownKeyFailure === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\t\tchildren: t(shownKeyFailure)\n\t\t\t\t\t\t})\n\t\t\t\t\t]\n\t\t\t\t})] });\n\t\t\t\tconst customization = props.credentialOnly === true ? null : (0, react_jsx_runtime.jsxs)(\"details\", {\n\t\t\t\t\tclassName: ModelsSection_module_css_default[\"customized\"],\n\t\t\t\t\topen: supportsMultiKey ? true : void 0,\n\t\t\t\t\t\"data-multi-key-shared-settings\": supportsMultiKey ? true : void 0,\n\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"summary\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"customizedSummary\"],\n\t\t\t\t\t\tchildren: t(supportsMultiKey ? \"multiKeySharedSettings\" : \"customized\")\n\t\t\t\t\t}), (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"customizedBody\"],\n\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\townsIdentity ? (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\t\tchildren: t(\"customDisplayName\")\n\t\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\tvalue: stringAt(draft, \"displayName\") ?? \"\",\n\t\t\t\t\t\t\t\t\tplaceholder: stringAt(schema.getPath(namespace.base, settingsPath), \"displayName\") ?? props.provider,\n\t\t\t\t\t\t\t\t\t\"aria-label\": t(\"customDisplayName\"),\n\t\t\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\tsetField(\"displayName\", event.target.value);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t}) : null,\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\t\t\tchildren: t(\"baseUrl\")\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\t\tvalue: stringAt(draft, \"baseURL\") ?? \"\",\n\t\t\t\t\t\t\t\t\t\tplaceholder: family === \"deepseek\" ? t(\"deepSeekBaseUrl\") : baseURL === void 0 ? t(endpointEnv.length > 0 ? \"baseUrlConfigured\" : \"baseUrlDefault\") : t(\"baseUrlPlaceholder\").replace(\"{url}\", () => baseURL),\n\t\t\t\t\t\t\t\t\t\t\"aria-describedby\": endpointHint === void 0 ? void 0 : `${props.provider}-endpoint-hint`,\n\t\t\t\t\t\t\t\t\t\t\"aria-label\": t(\"baseUrl\"),\n\t\t\t\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\t\tsetField(\"baseURL\", event.target.value === \"\" ? void 0 : event.target.value);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\tendpointHint === void 0 ? null : (0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\t\t\tid: `${props.provider}-endpoint-hint`,\n\t\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\t\t\t\t\tchildren: endpointHint\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\townsIdentity ? (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\t\tchildren: t(\"customApi\")\n\t\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsxs)(\"select\", {\n\t\t\t\t\t\t\t\t\tclassName: `${ModelsSection_module_css_default[\"input\"]} ${ModelsSection_module_css_default[\"selectInput\"]}`,\n\t\t\t\t\t\t\t\t\tvalue: probeApi ?? \"\",\n\t\t\t\t\t\t\t\t\t\"aria-label\": t(\"customApi\"),\n\t\t\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\tsetField(\"api\", event.target.value);\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tchildren: [probeApi === void 0 ? (0, react_jsx_runtime.jsx)(\"option\", {\n\t\t\t\t\t\t\t\t\t\tvalue: \"\",\n\t\t\t\t\t\t\t\t\t\tchildren: t(\"customApiUnset\")\n\t\t\t\t\t\t\t\t\t}) : null, protocols.map((choice) => (0, react_jsx_runtime.jsx)(\"option\", {\n\t\t\t\t\t\t\t\t\t\tvalue: choice,\n\t\t\t\t\t\t\t\t\t\tchildren: protocolLabel(t, choice)\n\t\t\t\t\t\t\t\t\t}, choice))]\n\t\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t}) : null,\n\t\t\t\t\t\t\tmultiKey ? null : family === \"deepseek\" ? (0, react_jsx_runtime.jsx)(DeepSeekModelsEditor, {\n\t\t\t\t\t\t\t\t...catalogProps,\n\t\t\t\t\t\t\t\tdefaultContextWindow: typeof defaultContextWindow === \"number\" ? defaultContextWindow : void 0,\n\t\t\t\t\t\t\t\tdefaultMaxTokens: typeof defaultMaxTokens === \"number\" ? defaultMaxTokens : void 0\n\t\t\t\t\t\t\t}) : (0, react_jsx_runtime.jsx)(ModelListEditor, {\n\t\t\t\t\t\t\t\t...catalogProps,\n\t\t\t\t\t\t\t\tcatalogProvider: props.declared === true ? void 0 : props.provider,\n\t\t\t\t\t\t\t\treasoningLevels,\n\t\t\t\t\t\t\t\tdefaultInput: Array.isArray(defaultInput) ? defaultInput : void 0,\n\t\t\t\t\t\t\t\tprobe,\n\t\t\t\t\t\t\t\tprobeBlocked: keyFailure,\n\t\t\t\t\t\t\t\toperations,\n\t\t\t\t\t\t\t\tonBusyChange: setListBusy\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t]\n\t\t\t\t\t})]\n\t\t\t\t});\n\t\t\t\treturn (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: supportsMultiKey ? [customization, credentials] : [credentials, customization] });\n\t\t\t};\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\tclassName: props.credentialOnly === true ? ModelsSection_module_css_default[\"addBlock\"] : ModelsSection_module_css_default[\"editor\"],\n\t\t\t\tchildren: [\n\t\t\t\t\tprops.hideTitle === true ? null : (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"editorHeader\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"editorTitle\"],\n\t\t\t\t\t\t\tchildren: props.displayName\n\t\t\t\t\t\t}), props.provider !== props.displayName ? (0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"editorRoute\"],\n\t\t\t\t\t\t\tchildren: props.provider\n\t\t\t\t\t\t}) : null]\n\t\t\t\t\t}),\n\t\t\t\t\tlayout === \"unknown\" ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\tchildren: `${t(\"advancedHint\")} (${namespace.ns})`\n\t\t\t\t\t}) : curatedFields(layout),\n\t\t\t\t\t(failure ?? entryFailure) !== void 0 ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: failure ?? entryFailure\n\t\t\t\t\t}) : null,\n\t\t\t\t\tprops.credentialOnly === true || modelFailure === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\tchildren: `${t(\"model\")} ${String(modelFailure.index + 1)}: ${t(modelFailure.key)}`\n\t\t\t\t\t}),\n\t\t\t\t\t(0, react_jsx_runtime.jsx)(EditorFooter, {\n\t\t\t\t\t\tt,\n\t\t\t\t\t\tbusy,\n\t\t\t\t\t\tsubmitDisabled: disabled || listBusy || layout === \"unknown\" || entryFailure !== void 0 || props.credentialOnly !== true && modelFailure !== void 0 || !multiKey && (shownKeyFailure !== void 0 || props.credentialRequired === true && keyValue.length === 0),\n\t\t\t\t\t\tsubmitLabelKey: props.submitLabelKey ?? \"apply\",\n\t\t\t\t\t\tsubmitBusyLabelKey: props.submitBusyLabelKey ?? \"applying\",\n\t\t\t\t\t\t...props.cancelLabelKey === void 0 ? {} : { cancelLabelKey: props.cancelLabelKey },\n\t\t\t\t\t\tonCancel: () => {\n\t\t\t\t\t\t\tprops.onClose(false);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonSubmit: () => {\n\t\t\t\t\t\t\tprops.onSubmitCredential?.();\n\t\t\t\t\t\t\tapply();\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t]\n\t\t\t});\n\t\t}"
|
|
810
|
+
},
|
|
811
|
+
{
|
|
812
|
+
"before": "className: ModelsSection_module_css_default[\"editorActions\"],",
|
|
813
|
+
"after": "className: ModelsSection_module_css_default[\"editorActions\"],\n\t\t\t\t\"data-model-save-actions\": true,\n\t\t\t\tstyle: { position: \"sticky\", bottom: \"calc(var(--dsh-model-save-offset, 0px) + env(safe-area-inset-bottom, 0px))\", zIndex: 2, padding: \"10px 0\", background: \"var(--dsw-alias-bg-module-platform)\", flexWrap: \"wrap\" },"
|
|
814
|
+
},
|
|
815
|
+
{
|
|
816
|
+
"before": "const en = {\n",
|
|
817
|
+
"after": "const en = {\n\t\t\tmultiKeyExpand: \"Expand details\",\n\t\t\tmultiKeyCollapse: \"Collapse details\",\n\t\t\tmultiKeyUnsaved: \"Not saved\",\n\t\t\tmultiKeyProtocol: \"Group API protocol\",\n\t\t\tmultiKeyProtocolInherit: \"Inherit provider ({protocol})\",\n\t\t\tmultiKeyProtocolDefault: \"default protocol\",\n\t\t\tmultiKeyProtocolHelp: \"Only this key group is affected. Choose the protocol supported by your relay, not just the model name.\",\n\t\t\tmultiKeyInvalidProtocol: \"Unsupported key-group protocol.\",\n\t\t\tmultiKeyRemoveGroup: \"Remove this key group\",\n\t\t\tmultiKeyRemoveTitle: \"Remove key group “{name}”?\",\n\t\t\tmultiKeyRemoveHelp: \"Removes the entire key group and its model list, not just one model above. Stored credentials are retained.\",\n\t\t\tmultiKeyRemoveDescription: \"This removes the selected group and all of its model entries from the draft. Other groups and stored credentials are retained. Existing conversations are not switched automatically. Changes take effect after Apply; Cancel editing to discard them.\",\n"
|
|
818
|
+
},
|
|
819
|
+
{
|
|
820
|
+
"before": "const zh = {\n",
|
|
821
|
+
"after": "const zh = {\n\t\t\tmultiKeyExpand: \"展开详情\",\n\t\t\tmultiKeyCollapse: \"收起详情\",\n\t\t\tmultiKeyUnsaved: \"未保存\",\n\t\t\tmultiKeyProtocol: \"分组 API 协议\",\n\t\t\tmultiKeyProtocolInherit: \"跟随供应商({protocol})\",\n\t\t\tmultiKeyProtocolDefault: \"默认协议\",\n\t\t\tmultiKeyProtocolHelp: \"仅影响此密钥分组,请按中转站支持的协议选择,不按模型名称自动切换。\",\n\t\t\tmultiKeyInvalidProtocol: \"不支持此密钥分组协议。\",\n\t\t\tmultiKeyRemoveGroup: \"移除此密钥分组\",\n\t\t\tmultiKeyRemoveTitle: \"移除密钥分组“{name}”?\",\n\t\t\tmultiKeyRemoveHelp: \"移除整个密钥分组及其模型列表,不是仅移除上方一个模型。已保存的密钥凭据会保留。\",\n\t\t\tmultiKeyRemoveDescription: \"此操作从编辑草稿移除该分组及其全部模型条目,其他分组和已保存的密钥凭据不变,不会自动切换现有会话。点击“应用”后才生效;取消编辑可放弃更改。\",\n"
|
|
822
|
+
}
|
|
823
|
+
]
|
|
824
|
+
},
|
|
825
|
+
{
|
|
826
|
+
"baseSha256": "e111ecefea8262e0426f528864b9681d818068042e93d053bcb0b6884b317278",
|
|
827
|
+
"resultSha256": "325371267d764fc3ea65c710a088e519fac0f6c4c56851a1ceca6ca8741c6027",
|
|
828
|
+
"replacements": [
|
|
829
|
+
{
|
|
830
|
+
"before": "\t\t//#region lib/types/client/CustomProviderCard.js",
|
|
831
|
+
"after": "\t\t//#region dsh-model-groups/native/multikey\n\t\t// Entries live under one native provider. Secrets exist only in local drafts\n\t\t// and credentials/set; profile mutations contain credential references only.\n\t\tconst MULTI_KEY_ENTRY_ID = /^[A-Za-z0-9][A-Za-z0-9_-]{0,79}$/;\n\t\tconst MULTI_KEY_REF = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\t\tconst MULTI_KEY_UNSAFE_IDS = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\n\t\tfunction supportsMultiKeySchema(namespace, schema, path) {\n\t\t\tif (!namespace || !schema) return false;\n\t\t\tconst root = schema.rehydrate(namespace.schema);\n\t\t\tconst profile = schema.nodeAtPath(root, path);\n\t\t\treturn profile?.dict?.multiKey !== void 0 && profile?.dict?.keyEntries !== void 0;\n\t\t}\n\t\tfunction multiKeyRef(route, id) {\n\t\t\tconst normalized = route.toUpperCase().replace(/[^A-Z0-9]+/g, \"_\");\n\t\t\tconst stem = /^[A-Z_]/.test(normalized) ? normalized : `DSH_${normalized}`;\n\t\t\treturn `${stem}_MULTKEY_${id.toUpperCase().replace(/[^A-Z0-9]+/g, \"_\")}_API_KEY`;\n\t\t}\n\t\tfunction newMultiKeyEntry(route, source = {}) {\n\t\t\tconst id = `k${crypto.randomUUID()}`;\n\t\t\treturn [id, {\n\t\t\t\tname: source.name ?? \"\",\n\t\t\t\t...(typeof source.apiKeyEnv === \"string\" && source.apiKeyEnv.length > 0 ? { apiKeyEnv: source.apiKeyEnv } : {}),\n\t\t\t\tmodels: modelDrafts(source.models).map((model) => structuredClone(model))\n\t\t\t}];\n\t\t}\n\t\tfunction normalizedMultiKeyEntries(route, entries) {\n\t\t\treturn Object.fromEntries(Object.entries(entries).map(([id, entry]) => [id, {\n\t\t\t\t...entry,\n\t\t\t\tname: typeof entry?.name === \"string\" ? entry.name.trim() : \"\",\n\t\t\t\tapiKeyEnv: typeof entry?.apiKeyEnv === \"string\" && entry.apiKeyEnv.length > 0 ? entry.apiKeyEnv : multiKeyRef(route, id),\n\t\t\t\tmodels: modelDrafts(entry?.models).map((model) => structuredClone(model))\n\t\t\t}]));\n\t\t}\n\t\tfunction multiKeyFailure(route, entries, drafts, confirmations, t) {\n\t\t\tif (!entries || typeof entries !== \"object\" || Array.isArray(entries) || Object.keys(entries).length === 0) return t(\"multiKeyNeedsEntries\");\n\t\t\tconst refs = new Set();\n\t\t\tfor (const [id, entry] of Object.entries(entries)) {\n\t\t\t\tif (!MULTI_KEY_ENTRY_ID.test(id) || MULTI_KEY_UNSAFE_IDS.has(id)) return t(\"multiKeyInvalidId\");\n\t\t\t\tif (!entry || typeof entry.name !== \"string\" || entry.name.trim().length === 0 || entry.name.trim().length > 120) return t(\"multiKeyInvalidName\");\n\t\t\t\tconst ref = entry.apiKeyEnv ?? multiKeyRef(route, id);\n\t\t\t\tif (typeof ref !== \"string\" || !MULTI_KEY_REF.test(ref)) return t(\"multiKeyInvalidRef\");\n\t\t\t\tif (refs.has(ref)) return t(\"multiKeyDuplicateRef\");\n\t\t\t\trefs.add(ref);\n\t\t\t\tconst keyFailure = apiKeyFailure(drafts[id] ?? \"\");\n\t\t\t\tif (keyFailure !== void 0) return `${entry.name}: ${t(keyFailure)}`;\n\t\t\t\tif ((drafts[id] ?? \"\").trim().length > 0 && ref !== multiKeyRef(route, id) && confirmations[id] !== true) return `${entry.name}: ${t(\"multiKeyConfirmRequired\")}`;\n\t\t\t\tif (!Array.isArray(entry.models) || entry.models.length === 0) return `${entry.name}: ${t(\"multiKeyNeedsModels\")}`;\n\t\t\t\tconst modelFailure = validateDeepSeekModels(entry.models) ?? validateReasoningEfforts(entry.models);\n\t\t\t\tif (modelFailure !== void 0) return `${entry.name}: ${t(\"model\")} ${String(modelFailure.index + 1)}: ${t(modelFailure.key)}`;\n\t\t\t}\n\t\t}\n\t\tasync function storeMultiKeyDrafts(operations, entries, drafts, setDrafts) {\n\t\t\tfor (const [id, entry] of Object.entries(entries)) {\n\t\t\t\tconst draft = Object.hasOwn(drafts, id) ? drafts[id] : \"\";\n\t\t\t\tif (draft.trim().length === 0) continue;\n\t\t\t\tconst failure = await operations.storeCredential(entry.apiKeyEnv, draft.trim());\n\t\t\t\tif (failure !== void 0) return failure;\n\t\t\t\t// Clear only successful, unchanged drafts: partial failures retry just\n\t\t\t\t// the unfinished credentials without rewriting the provider profile.\n\t\t\t\tsetDrafts((current) => current[id] === draft ? { ...current, [id]: \"\" } : current);\n\t\t\t}\n\t\t}\n\t\tfunction hasMultiKeyDrafts(drafts) {\n\t\t\treturn Object.values(drafts).some((value) => typeof value === \"string\" && value.length > 0);\n\t\t}\n\t\tfunction MultiKeyToggle({ t, checked, disabled, onChange, hasUnsavedKeys = false }) {\n\t\t\tconst [confirmOff, setConfirmOff] = (0, react.useState)(false);\n\t\t\t(0, react.useEffect)(() => {\n\t\t\t\tif (!checked || disabled) setConfirmOff(false);\n\t\t\t}, [checked, disabled]);\n\t\t\tconst close = () => setConfirmOff(false);\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\"data-multi-key-toggle\": true,\n\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\tchildren: [(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\tclassName: ModelsSection_module_css_default[\"modelReasoningHead\"],\n\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"], children: t(\"multiKey\")\n\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {\n\t\t\t\t\t\tchecked, label: t(\"multiKey\"), disabled,\n\t\t\t\t\t\tonChange: (enabled) => {\n\t\t\t\t\t\t\tif (disabled || enabled === checked) return;\n\t\t\t\t\t\t\tif (!enabled) setConfirmOff(true);\n\t\t\t\t\t\t\telse onChange(true);\n\t\t\t\t\t\t}\n\t\t\t\t\t})]\n\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"], children: t(\"multiKeyHelp\")\n\t\t\t\t}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {\n\t\t\t\t\topen: confirmOff && checked && !disabled, onClose: close,\n\t\t\t\t\ttitle: t(hasUnsavedKeys ? \"multiKeyUnsavedTitle\" : \"multiKeyDisableTitle\"),\n\t\t\t\t\tcloseLabel: t(\"close\"),\n\t\t\t\t\tdescription: t(hasUnsavedKeys ? \"multiKeyUnsavedKeys\" : \"multiKeyDisableDescription\"),\n\t\t\t\t\tclassName: ModelsSection_module_css_default[\"deleteDialog\"],\n\t\t\t\t\tfooter: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [\n\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {\n\t\t\t\t\t\t\tvariant: \"outline\", \"data-modal-autofocus\": true, onClick: close,\n\t\t\t\t\t\t\tchildren: t(hasUnsavedKeys ? \"multiKeyReturnToEdit\" : \"multiKeyKeepEnabled\")\n\t\t\t\t\t\t}), hasUnsavedKeys ? null : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {\n\t\t\t\t\t\t\tvariant: \"outline\", disabled,\n\t\t\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\t\t\tif (disabled || !checked || hasUnsavedKeys) return;\n\t\t\t\t\t\t\t\tclose(); onChange(false);\n\t\t\t\t\t\t\t}, children: t(\"multiKeyDisableConfirm\")\n\t\t\t\t\t\t})\n\t\t\t\t\t] })\n\t\t\t\t})]\n\t\t\t});\n\t\t}\n\t\tfunction MultiKeyEntriesEditor(props) {\n\t\t\tconst { route, entries, keyDrafts, confirmations, onChange, onKeyDraftsChange, onConfirmationsChange, operations, t, disabled } = props;\n\t\t\tconst [busyEntries, setBusyEntries] = (0, react.useState)({});\n\t\t\tconst anyBusy = Object.values(busyEntries).some(Boolean);\n\t\t\tconst { onBusyChange } = props;\n\t\t\t(0, react.useEffect)(() => {\n\t\t\t\tonBusyChange?.(anyBusy);\n\t\t\t}, [anyBusy, onBusyChange]);\n\t\t\t(0, react.useEffect)(() => () => onBusyChange?.(false), [onBusyChange]);\n\t\t\tconst update = (id, patch) => onChange({ ...entries, [id]: { ...entries[id], ...patch } });\n\t\t\tconst remove = (id) => {\n\t\t\t\tconst { [id]: removed, ...remaining } = entries;\n\t\t\t\tonChange(remaining);\n\t\t\t\tonKeyDraftsChange((current) => { const { [id]: removed, ...rest } = current; return rest; });\n\t\t\t\tonConfirmationsChange((current) => { const { [id]: removed, ...rest } = current; return rest; });\n\t\t\t\tsetBusyEntries((current) => { const { [id]: removed, ...rest } = current; return rest; });\n\t\t\t};\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\"data-multi-key-entries\": true,\n\t\t\t\tclassName: ModelsSection_module_css_default[\"modelList\"],\n\t\t\t\tchildren: [Object.entries(entries).map(([id, candidate], index) => {\n\t\t\t\t\tconst entry = candidate && typeof candidate === \"object\" && !Array.isArray(candidate) ? candidate : {};\n\t\t\t\t\tconst ref = entry.apiKeyEnv ?? multiKeyRef(route, id);\n\t\t\t\t\tconst draft = Object.hasOwn(keyDrafts, id) ? keyDrafts[id] : \"\";\n\t\t\t\t\tconst keyFailure = apiKeyFailure(draft);\n\t\t\t\t\tconst persisted = Object.hasOwn(props.persistedEntries ?? {}, id) && props.persistedEntries[id]?.apiKeyEnv === ref;\n\t\t\t\t\tconst info = props.credentialChecks?.[ref];\n\t\t\t\t\tconst status = info?.configured === true ? \"multiKeyConfigured\" : info?.configured === false ? \"multiKeyMissing\" : persisted ? \"multiKeySaved\" : \"multiKeyNew\";\n\t\t\t\t\tconst needsConfirmation = draft.trim().length > 0 && ref !== multiKeyRef(route, id);\n\t\t\t\t\tconst canUseStored = persisted && props.probe.provider !== void 0;\n\t\t\t\t\tconst probe = {\n\t\t\t\t\t\t...props.probe,\n\t\t\t\t\t\t...(canUseStored ? { keyEntryId: id } : {}),\n\t\t\t\t\t\t...(draft.trim().length > 0 ? { apiKey: draft.trim() } : {})\n\t\t\t\t\t};\n\t\t\t\t\tconst heading = typeof entry.name === \"string\" && entry.name.trim().length > 0 ? entry.name.trim() : `${t(\"multiKeyDefaultName\")} ${String(index + 1)}`;\n\t\t\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\"data-key-entry-id\": id, role: \"group\", \"aria-label\": heading,\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowCard\"],\n\t\t\t\t\t\tstyle: { minWidth: 0 },\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\"data-key-entry-heading\": true,\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowHead\"],\n\t\t\t\t\t\t\tstyle: { flexWrap: \"wrap\" },\n\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowName\"],\n\t\t\t\t\t\t\t\tstyle: { minWidth: 0, overflowWrap: \"anywhere\", flex: \"1 1 120px\" }, children: heading\n\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowActions\"],\n\t\t\t\t\t\t\t\tchildren: (0, react_jsx_runtime.jsx)(\"button\", {\n\t\t\t\t\t\t\t\t\ttype: \"button\", className: ModelsSection_module_css_default[\"secondaryButton\"], disabled,\n\t\t\t\t\t\t\t\t\tonClick: () => remove(id), children: t(\"multiKeyRemove\")\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"label\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", { className: ModelsSection_module_css_default[\"fieldLabel\"], children: t(\"multiKeyEntryName\") }),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"], type: \"text\", value: entry.name ?? \"\", maxLength: 120,\n\t\t\t\t\t\t\t\t\t\t\"aria-label\": `${t(\"multiKeyEntryName\")} ${String(index + 1)}`, disabled,\n\t\t\t\t\t\t\t\t\t\tonChange: (event) => update(id, { name: event.target.value })\n\t\t\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", { className: ModelsSection_module_css_default[\"fieldLabel\"], children: t(\"keyInput\") }),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ApiKeyInput, {\n\t\t\t\t\t\t\t\t\t\tt, value: draft, placeholder: t(persisted ? \"keyPlaceholderSaved\" : \"keyPlaceholder\"),\n\t\t\t\t\t\t\t\t\t\t\"aria-label\": `${t(\"keyInput\")} ${String(index + 1)}`, \"aria-invalid\": keyFailure !== void 0,\n\t\t\t\t\t\t\t\t\t\tdisabled: props.keyDisabled ?? disabled,\n\t\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\t\tconst value = event.target.value;\n\t\t\t\t\t\t\t\t\t\t\tonKeyDraftsChange((current) => ({ ...current, [id]: value }));\n\t\t\t\t\t\t\t\t\t\t\tonConfirmationsChange((current) => ({ ...current, [id]: false }));\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], children: t(status) }),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], style: { overflowWrap: \"anywhere\" }, children: t(\"multiKeyRef\").replace(\"{ref}\", () => ref) }),\n\t\t\t\t\t\t\t\t\tkeyFailure === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"error\"], children: t(keyFailure) })]\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tneedsConfirmation ? (0, react_jsx_runtime.jsxs)(\"label\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\tstyle: { display: \"flex\", alignItems: \"flex-start\", gap: 8, overflowWrap: \"anywhere\" },\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\ttype: \"checkbox\", \"data-confirm-entry\": id, \"aria-label\": t(\"multiKeyReplaceConfirm\").replace(\"{ref}\", () => ref),\n\t\t\t\t\t\t\t\t\tchecked: confirmations[id] === true, disabled: props.keyDisabled ?? disabled,\n\t\t\t\t\t\t\t\t\tonChange: (event) => onConfirmationsChange((current) => ({ ...current, [id]: event.target.checked }))\n\t\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"span\", { children: t(\"multiKeyReplaceConfirm\").replace(\"{ref}\", () => ref) })]\n\t\t\t\t\t\t\t}) : null,\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ModelListEditor, {\n\t\t\t\t\t\t\t\tmodels: modelDrafts(entry.models), onChange: (models) => update(id, { models }),\n\t\t\t\t\t\t\t\treasoningLevels: props.reasoningLevels, probe,\n\t\t\t\t\t\t\t\tprobeBlocked: keyFailure ?? props.probeBlocked ?? (!canUseStored && draft.trim().length === 0 ? \"multiKeyProbeNeedsKey\" : void 0),\n\t\t\t\t\t\t\t\toperations, t, disabled,\n\t\t\t\t\t\t\t\tonBusyChange: (value) => setBusyEntries((current) => current[id] === value ? current : { ...current, [id]: value })\n\t\t\t\t\t\t\t})]\n\t\t\t\t\t}, id);\n\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"button\", {\n\t\t\t\t\ttype: \"button\", className: ModelsSection_module_css_default[\"addModelButton\"], disabled,\n\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\tlet id, entry;\n\t\t\t\t\t\tdo { [id, entry] = newMultiKeyEntry(route, { name: `${t(\"multiKeyDefaultName\")} ${String(Object.keys(entries).length + 1)}` }); } while (Object.hasOwn(entries, id) || Object.values(entries).some((other) => other.apiKeyEnv === multiKeyRef(route, id)));\n\t\t\t\t\t\tonChange({ ...entries, [id]: entry });\n\t\t\t\t\t}, children: t(\"multiKeyAdd\")\n\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], children: t(\"multiKeyKeepCredentials\") })]\n\t\t\t});\n\t\t}\n\t\t//#endregion\n\n\t\t//#region lib/types/client/CustomProviderCard.js"
|
|
832
|
+
},
|
|
833
|
+
{
|
|
834
|
+
"before": "\t\t\t\t\t...probe.provider === void 0 ? {} : { provider: probe.provider },",
|
|
835
|
+
"after": "\t\t\t\t\t...probe.provider === void 0 ? {} : { provider: probe.provider },\n\t\t\t\t\t...probe.keyEntryId === void 0 ? {} : { keyEntryId: probe.keyEntryId },"
|
|
836
|
+
},
|
|
837
|
+
{
|
|
838
|
+
"before": "const { taken, protocols, reasoningLevels, operations, t, onBusyChange } = props;",
|
|
839
|
+
"after": "const { taken, protocols, reasoningLevels, operations, t, onBusyChange } = props;\n\t\t\tconst supportsMultiKey = supportsMultiKeySchema(props.namespace, props.schema, [\"providers\", PROBE_ROUTE]);"
|
|
840
|
+
},
|
|
841
|
+
{
|
|
842
|
+
"before": "const [models, setModels] = (0, react.useState)([]);\n\t\t\tconst [busy, setBusy]",
|
|
843
|
+
"after": "const [models, setModels] = (0, react.useState)([]);\n\t\t\tconst [multiKey, setMultiKey] = (0, react.useState)(false);\n\t\t\tconst [keyEntries, setKeyEntries] = (0, react.useState)({});\n\t\t\tconst [entryKeyDrafts, setEntryKeyDrafts] = (0, react.useState)({});\n\t\t\tconst [entryConfirmations, setEntryConfirmations] = (0, react.useState)({});\n\t\t\tconst saving = (0, react.useRef)(false);\n\t\t\tconst [busy, setBusy]"
|
|
844
|
+
},
|
|
845
|
+
{
|
|
846
|
+
"before": "const modelFailure = validateDeepSeekModels(models) ?? validateReasoningEfforts(models);\n\t\t\tconst keyFailure = apiKeyFailure(keyDraft);",
|
|
847
|
+
"after": "const modelFailure = multiKey ? void 0 : validateDeepSeekModels(models) ?? validateReasoningEfforts(models);\n\t\t\tconst entryFailure = multiKey ? multiKeyFailure(route, keyEntries, entryKeyDrafts, entryConfirmations, t) : void 0;\n\t\t\tconst keyFailure = multiKey ? void 0 : apiKeyFailure(keyDraft);"
|
|
848
|
+
},
|
|
849
|
+
{
|
|
850
|
+
"before": "const ready = route.length > 0 && !routeInvalid && !routeTaken && normalizedBaseURL.length > 0 && !baseUrlInvalid && models.length > 0 && modelFailure === void 0 && keyFailure === void 0;",
|
|
851
|
+
"after": "const ready = (committed || route.length > 0 && !routeInvalid && !routeTaken) && normalizedBaseURL.length > 0 && !baseUrlInvalid && (multiKey ? entryFailure === void 0 : models.length > 0 && modelFailure === void 0 && keyFailure === void 0);"
|
|
852
|
+
},
|
|
853
|
+
{
|
|
854
|
+
"before": "const hint = failure !== void 0 || ready || keyFailure !== void 0 || route.length === 0 || routeInvalid || routeTaken || baseUrlInvalid ? void 0 : normalizedBaseURL.length === 0 ? t(\"customNeedsBaseUrl\") : modelFailure !== void 0 ? `${t(\"model\")} ${String(modelFailure.index + 1)}: ${t(modelFailure.key)}` : t(\"customNeedsModels\");",
|
|
855
|
+
"after": "const hint = entryFailure ?? (failure !== void 0 || ready || keyFailure !== void 0 || route.length === 0 || routeInvalid || routeTaken || baseUrlInvalid ? void 0 : normalizedBaseURL.length === 0 ? t(\"customNeedsBaseUrl\") : modelFailure !== void 0 ? `${t(\"model\")} ${String(modelFailure.index + 1)}: ${t(modelFailure.key)}` : t(\"customNeedsModels\"));"
|
|
856
|
+
},
|
|
857
|
+
{
|
|
858
|
+
"before": "const keyRef = deriveKeyRef(route);\n\t\t\t\tconst storesKey = keyValue.length > 0;",
|
|
859
|
+
"after": "const entries = normalizedMultiKeyEntries(route, keyEntries);\n\t\t\t\tconst firstEntry = Object.values(entries)[0];\n\t\t\t\tconst keyRef = multiKey ? firstEntry?.apiKeyEnv : deriveKeyRef(route);\n\t\t\t\tconst storesKey = !multiKey && keyValue.length > 0;\n\t\t\t\tif (multiKey && entryFailure !== void 0) return entryFailure;"
|
|
860
|
+
},
|
|
861
|
+
{
|
|
862
|
+
"before": "...storesKey ? { apiKeyEnv: keyRef } : {},\n\t\t\t\t\t\tapi: protocol,\n\t\t\t\t\t\tbaseURL: normalizedBaseURL,\n\t\t\t\t\t\tmodels: models.map((model) => ({ ...model }))",
|
|
863
|
+
"after": "...storesKey || multiKey ? { apiKeyEnv: keyRef } : {},\n\t\t\t\t\t\tapi: protocol,\n\t\t\t\t\t\tbaseURL: normalizedBaseURL,\n\t\t\t\t\t\tmodels: (multiKey ? firstEntry.models : models).map((model) => ({ ...model })),\n\t\t\t\t\t\t...(multiKey || Object.keys(keyEntries).length > 0 ? { multiKey, keyEntries: entries } : {})"
|
|
864
|
+
},
|
|
865
|
+
{
|
|
866
|
+
"before": "\t\t\t\tif (storesKey) {\n\t\t\t\t\tconst stored = await operations.storeCredential(keyRef, keyValue);\n\t\t\t\t\tif (stored !== void 0) return stored;\n\t\t\t\t}\n\t\t\t};",
|
|
867
|
+
"after": "\t\t\t\tif (multiKey) return storeMultiKeyDrafts(operations, entries, entryKeyDrafts, setEntryKeyDrafts);\n\t\t\t\tif (storesKey) {\n\t\t\t\t\tconst stored = await operations.storeCredential(keyRef, keyValue);\n\t\t\t\t\tif (stored !== void 0) return stored;\n\t\t\t\t\tsetKeyDraft(\"\");\n\t\t\t\t}\n\t\t\t};"
|
|
868
|
+
},
|
|
869
|
+
{
|
|
870
|
+
"before": "const create = async () => {\n\t\t\t\tsetBusy(true);",
|
|
871
|
+
"after": "const create = async () => {\n\t\t\t\tif (saving.current || !ready || props.readOnly || listBusy) return;\n\t\t\t\tsaving.current = true;\n\t\t\t\tsetBusy(true);"
|
|
872
|
+
},
|
|
873
|
+
{
|
|
874
|
+
"before": "props.onClose(true);\n\t\t\t\t} finally {\n\t\t\t\t\tsetBusy(false);\n\t\t\t\t}\n\t\t\t};\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {",
|
|
875
|
+
"after": "props.onClose(true);\n\t\t\t\t} catch {\n\t\t\t\t\tsetFailure(t(\"multiKeySaveFailed\"));\n\t\t\t\t} finally {\n\t\t\t\t\tsaving.current = false;\n\t\t\t\t\tsetBusy(false);\n\t\t\t\t}\n\t\t\t};\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {"
|
|
876
|
+
},
|
|
877
|
+
{
|
|
878
|
+
"before": "\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\tchildren: t(\"keyInput\")",
|
|
879
|
+
"after": "\t\t\t\t\tsupportsMultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyToggle, {\n\t\t\t\t\t\tt, checked: multiKey, disabled: profileDisabled || listBusy, hasUnsavedKeys: hasMultiKeyDrafts(entryKeyDrafts),\n\t\t\t\t\t\tonChange: (enabled) => {\n\t\t\t\t\t\t\tif (enabled && Object.keys(keyEntries).length === 0) {\n\t\t\t\t\t\t\t\tconst [id, entry] = newMultiKeyEntry(route, { name: displayName || route || t(\"multiKeyDefaultName\"), models });\n\t\t\t\t\t\t\t\tsetKeyEntries({ [id]: entry });\n\t\t\t\t\t\t\t\tif (keyDraft.length > 0) setEntryKeyDrafts({ [id]: keyDraft });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsetMultiKey(enabled);\n\t\t\t\t\t\t}\n\t\t\t\t\t}) : null,\n\t\t\t\t\tmultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyEntriesEditor, {\n\t\t\t\t\t\troute, entries: keyEntries, onChange: setKeyEntries,\n\t\t\t\t\t\tkeyDrafts: entryKeyDrafts, onKeyDraftsChange: setEntryKeyDrafts,\n\t\t\t\t\t\tconfirmations: entryConfirmations, onConfirmationsChange: setEntryConfirmations,\n\t\t\t\t\t\tpersistedEntries: committed ? normalizedMultiKeyEntries(route, keyEntries) : {},\n\t\t\t\t\t\tprobe: { settingsNs: NS$1, ...(committed ? { provider: route } : {}), baseURL: normalizedBaseURL, api: protocol },\n\t\t\t\t\t\tprobeBlocked: baseUrlInvalid ? \"customBaseUrlInvalid\" : normalizedBaseURL.length === 0 ? \"customNeedsBaseUrl\" : void 0,\n\t\t\t\t\t\treasoningLevels, operations, t, disabled: profileDisabled || listBusy, keyDisabled: disabled || listBusy, onBusyChange: setListBusy\n\t\t\t\t\t}) : null,\n\t\t\t\t\tmultiKey ? null : (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\tchildren: t(\"keyInput\")"
|
|
880
|
+
},
|
|
881
|
+
{
|
|
882
|
+
"before": "\t\t\t\t\t(0, react_jsx_runtime.jsx)(ModelListEditor, {\n\t\t\t\t\t\tmodels,\n\t\t\t\t\t\tonChange: setModels,",
|
|
883
|
+
"after": "\t\t\t\t\t!multiKey ? (0, react_jsx_runtime.jsx)(ModelListEditor, {\n\t\t\t\t\t\tmodels,\n\t\t\t\t\t\tonChange: setModels,"
|
|
884
|
+
},
|
|
885
|
+
{
|
|
886
|
+
"before": "\t\t\t\t\t\tonBusyChange: setListBusy\n\t\t\t\t\t}),\n\t\t\t\t\tfailure !== void 0",
|
|
887
|
+
"after": "\t\t\t\t\t\tonBusyChange: setListBusy\n\t\t\t\t\t}) : null,\n\t\t\t\t\tfailure !== void 0"
|
|
888
|
+
},
|
|
889
|
+
{
|
|
890
|
+
"before": "submitDisabled: disabled || !ready,",
|
|
891
|
+
"after": "submitDisabled: disabled || listBusy || !ready,"
|
|
892
|
+
},
|
|
893
|
+
{
|
|
894
|
+
"before": "taken: state.rows.map((row) => row.entry.provider),\n\t\t\t\t\t\t\t\t\t\tprotocols,",
|
|
895
|
+
"after": "taken: state.rows.map((row) => row.entry.provider),\n\t\t\t\t\t\t\t\t\t\tnamespace: piAi,\n\t\t\t\t\t\t\t\t\t\tschema,\n\t\t\t\t\t\t\t\t\t\tprotocols,"
|
|
896
|
+
},
|
|
897
|
+
{
|
|
898
|
+
"before": "const [draft, setDraft] = (0, react.useState)(() => draftAt(schema, namespace, settingsPath));",
|
|
899
|
+
"after": "const [draft, setDraft] = (0, react.useState)(() => draftAt(schema, namespace, settingsPath));\n\t\t\tconst [entryKeyDrafts, setEntryKeyDrafts] = (0, react.useState)({});\n\t\t\tconst [entryConfirmations, setEntryConfirmations] = (0, react.useState)({});\n\t\t\tconst saving = (0, react.useRef)(false);"
|
|
900
|
+
},
|
|
901
|
+
{
|
|
902
|
+
"before": "const keyRef = refFor(schema, namespace, settingsPath, props.provider);",
|
|
903
|
+
"after": "const keyRef = refFor(schema, namespace, settingsPath, props.provider);\n\t\t\tconst supportsMultiKey = layout === \"pi-ai\" && props.declared === true && props.credentialOnly !== true && supportsMultiKeySchema(namespace, schema, settingsPath);\n\t\t\tconst multiKey = supportsMultiKey && (draft.multiKey ?? fallback?.multiKey) === true;\n\t\t\tconst keyEntries = draft.keyEntries ?? fallback?.keyEntries ?? {};\n\t\t\tconst entryFailure = multiKey ? multiKeyFailure(props.provider, keyEntries, entryKeyDrafts, entryConfirmations, t) : void 0;"
|
|
904
|
+
},
|
|
905
|
+
{
|
|
906
|
+
"before": "const modelFailure = validateModels(schema.getPath(draft, [\"models\"]));\n\t\t\tconst keyFailure = apiKeyFailure(keyDraft);",
|
|
907
|
+
"after": "const modelFailure = multiKey ? void 0 : validateModels(schema.getPath(draft, [\"models\"]));\n\t\t\tconst keyFailure = multiKey ? void 0 : apiKeyFailure(keyDraft);"
|
|
908
|
+
},
|
|
909
|
+
{
|
|
910
|
+
"before": "const next = layout === \"pi-ai\" && stringAt(draft, \"apiKeyEnv\") === void 0 && stringAt(fallback, \"apiKeyEnv\") === void 0 && keyValue.length > 0 ? schema.setPath(draft, [\"apiKeyEnv\"], keyRef) : draft;",
|
|
911
|
+
"after": "const normalizedDraft = supportsMultiKey && schema.hasPath(draft, [\"keyEntries\"]) ? schema.setPath(draft, [\"keyEntries\"], normalizedMultiKeyEntries(props.provider, keyEntries)) : draft;\n\t\t\t\tconst next = multiKey ? schema.setPath(normalizedDraft, [\"keyEntries\"], normalizedMultiKeyEntries(props.provider, keyEntries)) : layout === \"pi-ai\" && stringAt(draft, \"apiKeyEnv\") === void 0 && stringAt(fallback, \"apiKeyEnv\") === void 0 && keyValue.length > 0 ? schema.setPath(normalizedDraft, [\"apiKeyEnv\"], keyRef) : normalizedDraft;\n\t\t\t\tif (entryFailure !== void 0) return entryFailure;"
|
|
912
|
+
},
|
|
913
|
+
{
|
|
914
|
+
"before": "if (props.credentialOnly !== true) {\n\t\t\t\t\tconst failure = validateModels",
|
|
915
|
+
"after": "if (props.credentialOnly !== true && !multiKey) {\n\t\t\t\t\tconst failure = validateModels"
|
|
916
|
+
},
|
|
917
|
+
{
|
|
918
|
+
"before": "\t\t\t\tif (keyValue.length > 0) {\n\t\t\t\t\tconst stored = await operations.storeCredential(keyRef, keyValue);",
|
|
919
|
+
"after": "\t\t\t\tif (multiKey) return storeMultiKeyDrafts(operations, next.keyEntries, entryKeyDrafts, setEntryKeyDrafts);\n\t\t\t\tif (keyValue.length > 0) {\n\t\t\t\t\tconst stored = await operations.storeCredential(keyRef, keyValue);"
|
|
920
|
+
},
|
|
921
|
+
{
|
|
922
|
+
"before": "const apply = async () => {\n\t\t\t\tsetBusy(true);",
|
|
923
|
+
"after": "const apply = async () => {\n\t\t\t\tif (saving.current || props.readOnly || listBusy || entryFailure !== void 0) return;\n\t\t\t\tsaving.current = true;\n\t\t\t\tsetBusy(true);"
|
|
924
|
+
},
|
|
925
|
+
{
|
|
926
|
+
"before": "props.onClose(true);\n\t\t\t\t} finally {\n\t\t\t\t\tsetBusy(false);\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (node === void 0)",
|
|
927
|
+
"after": "props.onClose(true);\n\t\t\t\t} catch {\n\t\t\t\t\tsetFailure(t(\"multiKeySaveFailed\"));\n\t\t\t\t} finally {\n\t\t\t\t\tsaving.current = false;\n\t\t\t\t\tsetBusy(false);\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (node === void 0)"
|
|
928
|
+
},
|
|
929
|
+
{
|
|
930
|
+
"before": "return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [keylessNativeAuth ? null :",
|
|
931
|
+
"after": "return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [supportsMultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyToggle, {\n\t\t\t\t\tt, checked: multiKey, disabled: disabled || listBusy, hasUnsavedKeys: hasMultiKeyDrafts(entryKeyDrafts),\n\t\t\t\t\tonChange: (enabled) => {\n\t\t\t\t\t\tlet updated = schema.setPath(draft, [\"multiKey\"], enabled);\n\t\t\t\t\t\tif (enabled && Object.keys(keyEntries).length === 0) {\n\t\t\t\t\t\t\tconst namedRef = stringAt(draft, \"apiKeyEnv\") ?? stringAt(fallback, \"apiKeyEnv\");\n\t\t\t\t\t\t\tconst [id, entry] = newMultiKeyEntry(props.provider, {\n\t\t\t\t\t\t\t\tname: stringAt(draft, \"displayName\") ?? stringAt(fallback, \"displayName\") ?? props.displayName ?? props.provider,\n\t\t\t\t\t\t\t\tapiKeyEnv: namedRef,\n\t\t\t\t\t\t\t\tmodels: draft.models ?? fallback?.models ?? inheritedModels()\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (keyDraft.length > 0) {\n\t\t\t\t\t\t\t\tsetEntryKeyDrafts({ [id]: keyDraft });\n\t\t\t\t\t\t\t\tif (namedRef === void 0) updated = schema.setPath(updated, [\"apiKeyEnv\"], multiKeyRef(props.provider, id));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tupdated = schema.setPath(updated, [\"keyEntries\"], { [id]: entry });\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsetDraft(updated);\n\t\t\t\t\t}\n\t\t\t\t}) : null, multiKey ? (0, react_jsx_runtime.jsx)(MultiKeyEntriesEditor, {\n\t\t\t\t\troute: props.provider, entries: keyEntries,\n\t\t\t\t\tonChange: (entries) => setDraft((current) => schema.setPath(current, [\"keyEntries\"], entries)),\n\t\t\t\t\tkeyDrafts: entryKeyDrafts, onKeyDraftsChange: setEntryKeyDrafts,\n\t\t\t\t\tconfirmations: entryConfirmations, onConfirmationsChange: setEntryConfirmations,\n\t\t\t\t\tpersistedEntries: schema.getPath(committedOriginal, [\"keyEntries\"]) ?? fallback?.keyEntries ?? {},\n\t\t\t\t\tcredentialChecks: props.credentialChecks,\n\t\t\t\t\tprobe: { settingsNs: namespace.ns, provider: props.provider, ...(probeBaseURL === void 0 ? {} : { baseURL: probeBaseURL }), ...(probeApi === void 0 ? {} : { api: probeApi }) },\n\t\t\t\t\treasoningLevels, operations, t, disabled: disabled || listBusy, onBusyChange: setListBusy\n\t\t\t\t}) : null, multiKey || keylessNativeAuth ? null :"
|
|
932
|
+
},
|
|
933
|
+
{
|
|
934
|
+
"before": "family === \"deepseek\" ? (0, react_jsx_runtime.jsx)(DeepSeekModelsEditor, {",
|
|
935
|
+
"after": "multiKey ? null : family === \"deepseek\" ? (0, react_jsx_runtime.jsx)(DeepSeekModelsEditor, {"
|
|
936
|
+
},
|
|
937
|
+
{
|
|
938
|
+
"before": "\t\t\t\t\tfailure !== void 0 ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: failure\n\t\t\t\t\t}) : null,\n\t\t\t\t\tprops.credentialOnly",
|
|
939
|
+
"after": "\t\t\t\t\t(failure ?? entryFailure) !== void 0 ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: failure ?? entryFailure\n\t\t\t\t\t}) : null,\n\t\t\t\t\tprops.credentialOnly"
|
|
940
|
+
},
|
|
941
|
+
{
|
|
942
|
+
"before": "submitDisabled: disabled || layout === \"unknown\" || props.credentialOnly !== true && modelFailure !== void 0 || shownKeyFailure !== void 0 || props.credentialRequired === true && keyValue.length === 0,",
|
|
943
|
+
"after": "submitDisabled: disabled || listBusy || layout === \"unknown\" || entryFailure !== void 0 || props.credentialOnly !== true && modelFailure !== void 0 || !multiKey && (shownKeyFailure !== void 0 || props.credentialRequired === true && keyValue.length === 0),"
|
|
944
|
+
},
|
|
945
|
+
{
|
|
946
|
+
"before": "return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [supportsMultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyToggle, {",
|
|
947
|
+
"after": "const credentials = (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [supportsMultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyToggle, {"
|
|
948
|
+
},
|
|
949
|
+
{
|
|
950
|
+
"before": "\t\t\t\t}), props.credentialOnly === true ? null : (0, react_jsx_runtime.jsxs)(\"details\", {\n\t\t\t\t\tclassName: ModelsSection_module_css_default[\"customized\"],",
|
|
951
|
+
"after": "\t\t\t\t})] });\n\t\t\t\tconst customization = props.credentialOnly === true ? null : (0, react_jsx_runtime.jsxs)(\"details\", {\n\t\t\t\t\tclassName: ModelsSection_module_css_default[\"customized\"],\n\t\t\t\t\topen: supportsMultiKey ? true : void 0,\n\t\t\t\t\t\"data-multi-key-shared-settings\": supportsMultiKey ? true : void 0,"
|
|
952
|
+
},
|
|
953
|
+
{
|
|
954
|
+
"before": "children: t(\"customized\")\n\t\t\t\t\t}), (0, react_jsx_runtime.jsxs)(\"div\", {",
|
|
955
|
+
"after": "children: t(supportsMultiKey ? \"multiKeySharedSettings\" : \"customized\")\n\t\t\t\t\t}), (0, react_jsx_runtime.jsxs)(\"div\", {"
|
|
956
|
+
},
|
|
957
|
+
{
|
|
958
|
+
"before": "\t\t\t\t})] });\n\t\t\t};\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\tclassName: props.credentialOnly",
|
|
959
|
+
"after": "\t\t\t\t});\n\t\t\t\treturn (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: supportsMultiKey ? [customization, credentials] : [credentials, customization] });\n\t\t\t};\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\tclassName: props.credentialOnly"
|
|
960
|
+
},
|
|
961
|
+
{
|
|
962
|
+
"before": "\t\tconst en = {",
|
|
963
|
+
"after": "\t\tconst en = {\n\t\t\tmultiKey: \"Multiple key configurations\",\n\t\t\tmultiKeyHelp: \"Configurations share one provider ID, endpoint and protocol; each has its own name, API key and models. Turning this off restores the original single-key configuration without deleting entries or credentials.\",\n\t\t\tmultiKeySharedSettings: \"Shared settings\",\n\t\t\tmultiKeyAdd: \"Add key configuration\",\n\t\t\tmultiKeyRemove: \"Remove\",\n\t\t\tmultiKeyEntryName: \"Configuration name\",\n\t\t\tmultiKeyDefaultName: \"Key configuration\",\n\t\t\tmultiKeyDisableTitle: \"Turn off multiple key configurations?\",\n\t\t\tmultiKeyDisableDescription: \"After applying, this provider will use its original single-key configuration. Saved configurations and credentials will not be deleted. Sessions using a key configuration will need you to re-enable it or select a single-key model; no other key will be chosen automatically.\",\n\t\t\tmultiKeyKeepEnabled: \"Keep enabled\",\n\t\t\tmultiKeyDisableConfirm: \"Turn off in draft\",\n\t\t\tmultiKeyUnsavedTitle: \"Save the API keys before turning this off\",\n\t\t\tmultiKeyUnsavedKeys: \"Some API keys have been typed but not saved. Turning this off and applying would not store those inputs, so the switch will stay on. Return to the configurations and apply to save them, then reopen this card to turn it off. Nothing has been deleted.\",\n\t\t\tmultiKeyReturnToEdit: \"Return to configurations\",\n\t\t\tmultiKeyRef: \"Credential reference: {ref}\",\n\t\t\tmultiKeySaved: \"Saved reference; credential status not checked. Leave the key blank to keep it.\",\n\t\t\tmultiKeyNew: \"Not saved yet. An empty key does not create a credential.\",\n\t\t\tmultiKeyConfigured: \"Credential confirmed configured; leave blank to keep it.\",\n\t\t\tmultiKeyMissing: \"Credential confirmed missing. Enter a key or configure this reference.\",\n\t\t\tmultiKeyKeepCredentials: \"Removing a key configuration does not delete its stored credential.\",\n\t\t\tmultiKeyNeedsEntries: \"Add at least one key configuration.\",\n\t\t\tmultiKeyInvalidId: \"Invalid key-configuration ID; reopen this card or fix the profile.\",\n\t\t\tmultiKeyInvalidName: \"Each key configuration needs a name of 1–120 characters.\",\n\t\t\tmultiKeyInvalidRef: \"Invalid credential reference.\",\n\t\t\tmultiKeyDuplicateRef: \"Two configurations use the same credential reference. Each configuration must have its own reference.\",\n\t\t\tmultiKeyNeedsModels: \"Each key configuration needs at least one model.\",\n\t\t\tmultiKeyReplaceConfirm: \"Replace the key at {ref}. Other configurations sharing this reference will also be affected.\",\n\t\t\tmultiKeyConfirmRequired: \"Confirm the credential replacement before applying.\",\n\t\t\tmultiKeyProbeNeedsKey: \"Enter this configuration’s API key to discover models before saving. The provider’s original key will not be used.\",\n\t\t\tmultiKeySaveFailed: \"Saving did not complete. Keep this card open and retry; successful credential writes will not be repeated.\","
|
|
964
|
+
},
|
|
965
|
+
{
|
|
966
|
+
"before": "\t\tconst zh = {",
|
|
967
|
+
"after": "\t\tconst zh = {\n\t\t\tmultiKey: \"多密钥配置\",\n\t\t\tmultiKeyHelp: \"各配置共享 Provider ID、API 地址与协议,分别管理名称、API 密钥和模型。关闭后恢复原单密钥配置,已保存的配置与密钥不会删除。\",\n\t\t\tmultiKeySharedSettings: \"公共设置\",\n\t\t\tmultiKeyAdd: \"添加密钥配置\",\n\t\t\tmultiKeyRemove: \"移除\",\n\t\t\tmultiKeyEntryName: \"配置名称\",\n\t\t\tmultiKeyDefaultName: \"密钥配置\",\n\t\t\tmultiKeyDisableTitle: \"关闭多密钥配置?\",\n\t\t\tmultiKeyDisableDescription: \"应用后,此供应商将使用原单密钥配置,已保存的密钥配置与凭据不会删除。正在使用密钥配置的会话需要重新开启,或手动选择单密钥模型;不会自动换用其他密钥。\",\n\t\t\tmultiKeyKeepEnabled: \"保持开启\",\n\t\t\tmultiKeyDisableConfirm: \"确认关闭(待应用)\",\n\t\t\tmultiKeyUnsavedTitle: \"请先保存新输入的密钥\",\n\t\t\tmultiKeyUnsavedKeys: \"当前有尚未保存的 API 密钥输入。关闭后直接应用不会保存这些输入,因此开关将保持开启。请返回密钥配置并应用保存,再重新打开此卡片关闭;当前输入与已存储的密钥均未删除。\",\n\t\t\tmultiKeyReturnToEdit: \"返回密钥配置\",\n\t\t\tmultiKeyRef: \"密钥引用:{ref}\",\n\t\t\tmultiKeySaved: \"引用已保存,尚未检查密钥状态;输入留空可保留原密钥。\",\n\t\t\tmultiKeyNew: \"尚未保存;输入留空不会创建密钥。\",\n\t\t\tmultiKeyConfigured: \"已确认密钥已配置;留空可保留。\",\n\t\t\tmultiKeyMissing: \"已确认此引用缺少密钥,请输入或在环境中配置。\",\n\t\t\tmultiKeyKeepCredentials: \"移除密钥配置不会删除已存储的密钥。\",\n\t\t\tmultiKeyNeedsEntries: \"请至少添加一个密钥配置。\",\n\t\t\tmultiKeyInvalidId: \"密钥配置 ID 无效,请重新打开此卡片或修正配置。\",\n\t\t\tmultiKeyInvalidName: \"每个配置名称须为 1–120 个字符。\",\n\t\t\tmultiKeyInvalidRef: \"密钥引用无效。\",\n\t\t\tmultiKeyDuplicateRef: \"多个密钥配置使用了相同的密钥引用;每个配置必须使用独立引用。\",\n\t\t\tmultiKeyNeedsModels: \"每个密钥配置至少需要一个模型。\",\n\t\t\tmultiKeyReplaceConfirm: \"确认替换 {ref} 的密钥;共用此引用的其他配置也会受到影响。\",\n\t\t\tmultiKeyConfirmRequired: \"请先确认替换已引用的密钥,再应用。\",\n\t\t\tmultiKeyProbeNeedsKey: \"保存前请先输入此配置的 API 密钥再获取模型;不会使用供应商原来的密钥。\",\n\t\t\tmultiKeySaveFailed: \"保存尚未完成。请保留此卡片并重试;已成功写入的密钥不会重复写入。\","
|
|
968
|
+
},
|
|
969
|
+
{
|
|
970
|
+
"before": "const MULTI_KEY_ENTRY_ID =",
|
|
971
|
+
"after": "const MULTI_KEY_PROTOCOLS = new Set([\"openai-completions\", \"openai-responses\", \"anthropic-messages\"]);\n\t\tconst MULTI_KEY_ENTRY_ID ="
|
|
972
|
+
},
|
|
973
|
+
{
|
|
974
|
+
"before": "name: source.name ?? \"\",",
|
|
975
|
+
"after": "name: source.name ?? \"\",\n\t\t\t\t...(source.api === void 0 ? {} : { api: source.api }),"
|
|
976
|
+
},
|
|
977
|
+
{
|
|
978
|
+
"before": "return Object.fromEntries(Object.entries(entries).map(([id, entry]) => [id, {\n\t\t\t\t...entry,\n\t\t\t\tname: typeof entry?.name === \"string\" ? entry.name.trim() : \"\",\n\t\t\t\tapiKeyEnv: typeof entry?.apiKeyEnv === \"string\" && entry.apiKeyEnv.length > 0 ? entry.apiKeyEnv : multiKeyRef(route, id),\n\t\t\t\tmodels: modelDrafts(entry?.models).map((model) => structuredClone(model))\n\t\t\t}]));",
|
|
979
|
+
"after": "return Object.fromEntries(Object.entries(entries).map(([id, entry]) => {\n\t\t\t\tconst { api, ...rest } = entry;\n\t\t\t\treturn [id, {\n\t\t\t\t\t...rest,\n\t\t\t\t\t...(api === void 0 || api === \"\" ? {} : { api }),\n\t\t\t\t\tname: typeof entry?.name === \"string\" ? entry.name.trim() : \"\",\n\t\t\t\t\tapiKeyEnv: typeof entry?.apiKeyEnv === \"string\" && entry.apiKeyEnv.length > 0 ? entry.apiKeyEnv : multiKeyRef(route, id),\n\t\t\t\t\tmodels: modelDrafts(entry?.models).map((model) => structuredClone(model))\n\t\t\t\t}];\n\t\t\t}));"
|
|
980
|
+
},
|
|
981
|
+
{
|
|
982
|
+
"before": "return t(\"multiKeyInvalidName\");\n\t\t\t\tconst ref = entry.apiKeyEnv ?? multiKeyRef(route, id);",
|
|
983
|
+
"after": "return t(\"multiKeyInvalidName\");\n\t\t\t\tif (entry.api !== void 0 && !MULTI_KEY_PROTOCOLS.has(entry.api)) return t(\"multiKeyInvalidProtocol\");\n\t\t\t\tconst ref = entry.apiKeyEnv ?? multiKeyRef(route, id);"
|
|
984
|
+
},
|
|
985
|
+
{
|
|
986
|
+
"before": "...(canUseStored ? { keyEntryId: id } : {}),",
|
|
987
|
+
"after": "...(canUseStored ? { keyEntryId: id } : {}),\n\t\t\t\t\t\t...(entry.api === void 0 ? {} : { api: entry.api }),"
|
|
988
|
+
},
|
|
989
|
+
{
|
|
990
|
+
"before": "\t\tfunction MultiKeyEntriesEditor(props) {",
|
|
991
|
+
"after": "\t\tfunction multiKeyEntryDirty(entry, saved, draft) {\n\t\t\treturn saved === void 0 || JSON.stringify(entry) !== JSON.stringify(saved) || (draft ?? \"\").length > 0;\n\t\t}\n\t\tfunction MultiKeyEntriesEditor(props) {"
|
|
992
|
+
},
|
|
993
|
+
{
|
|
994
|
+
"before": "const [busyEntries, setBusyEntries] = (0, react.useState)({});",
|
|
995
|
+
"after": "const [busyEntries, setBusyEntries] = (0, react.useState)({});\n\t\t\tconst [expandedEntries, setExpandedEntries] = (0, react.useState)({});\n\t\t\tconst [removeTarget, setRemoveTarget] = (0, react.useState)(void 0);\n\t\t\tconst detailsPrefix = (0, react.useId)();\n\t\t\tconst previousSave = (0, react.useRef)(props.saveState);\n\t\t\t(0, react.useEffect)(() => {\n\t\t\t\tconst save = props.saveState;\n\t\t\t\tif (save === previousSave.current) return;\n\t\t\t\tpreviousSave.current = save;\n\t\t\t\tif (!save) return;\n\t\t\t\tsetExpandedEntries((current) => {\n\t\t\t\t\tconst next = { ...current };\n\t\t\t\t\tfor (const id of Object.keys(save.entries)) {\n\t\t\t\t\t\t// Only collapse the exact snapshot acknowledged by this save.\n\t\t\t\t\t\tif (!save.ok || !multiKeyEntryDirty(entries[id], save.entries[id], keyDrafts[id])) next[id] = !save.ok;\n\t\t\t\t\t}\n\t\t\t\t\treturn next;\n\t\t\t\t});\n\t\t\t}, [props.saveState, entries, keyDrafts]);\n\t\t\tconst invalidRows = Object.keys(entries).filter((id) => multiKeyFailure(route, { [id]: entries[id] }, keyDrafts, confirmations, t) !== void 0);\n\t\t\tconst invalidEntries = invalidRows.length > 0 ? invalidRows : multiKeyFailure(route, entries, keyDrafts, confirmations, t) !== void 0 ? Object.keys(entries) : [];\n\t\t\tconst invalidSignature = JSON.stringify(invalidEntries);\n\t\t\t(0, react.useEffect)(() => {\n\t\t\t\tif (invalidEntries.length > 0) setExpandedEntries((current) => ({ ...current, ...Object.fromEntries(invalidEntries.map((id) => [id, true])) }));\n\t\t\t}, [invalidSignature]);"
|
|
996
|
+
},
|
|
997
|
+
{
|
|
998
|
+
"before": "const anyBusy = Object.values(busyEntries).some(Boolean);",
|
|
999
|
+
"after": "const anyBusy = Object.values(busyEntries).some(Boolean);\n\t\t\t(0, react.useEffect)(() => {\n\t\t\t\tif (disabled || anyBusy || removeTarget !== void 0 && !Object.hasOwn(entries, removeTarget)) setRemoveTarget(void 0);\n\t\t\t}, [disabled, anyBusy, removeTarget, entries]);\n\t\t\tconst removeName = typeof entries[removeTarget]?.name === \"string\" && entries[removeTarget].name.trim() ? entries[removeTarget].name.trim() : t(\"multiKeyDefaultName\");"
|
|
1000
|
+
},
|
|
1001
|
+
{
|
|
1002
|
+
"before": "const remove = (id) => {",
|
|
1003
|
+
"after": "const remove = (id) => {\n\t\t\t\tif (disabled || anyBusy || !Object.hasOwn(entries, id)) return;"
|
|
1004
|
+
},
|
|
1005
|
+
{
|
|
1006
|
+
"before": "const heading = typeof entry.name === \"string\"",
|
|
1007
|
+
"after": "const dirty = multiKeyEntryDirty(entry, props.savedEntries?.[id] ?? props.persistedEntries?.[id], draft);\n\t\t\t\t\tconst expanded = expandedEntries[id] ?? !Object.hasOwn(props.persistedEntries ?? {}, id);\n\t\t\t\t\tconst detailsId = detailsPrefix + \"-\" + id;\n\t\t\t\t\tconst heading = typeof entry.name === \"string\""
|
|
1008
|
+
},
|
|
1009
|
+
{
|
|
1010
|
+
"before": "\"data-key-entry-id\": id, role: \"group\", \"aria-label\": heading,",
|
|
1011
|
+
"after": "\"data-key-entry-id\": id, \"data-key-entry-expanded\": expanded, \"data-key-entry-dirty\": dirty, role: \"group\", \"aria-label\": heading,"
|
|
1012
|
+
},
|
|
1013
|
+
{
|
|
1014
|
+
"before": "\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\"data-key-entry-heading\": true,\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowHead\"],\n\t\t\t\t\t\t\tstyle: { flexWrap: \"wrap\" },\n\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowName\"],\n\t\t\t\t\t\t\t\tstyle: { minWidth: 0, overflowWrap: \"anywhere\", flex: \"1 1 120px\" }, children: heading\n\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowActions\"],\n\t\t\t\t\t\t\t\tchildren: (0, react_jsx_runtime.jsx)(\"button\", {\n\t\t\t\t\t\t\t\t\ttype: \"button\", className: ModelsSection_module_css_default[\"secondaryButton\"], disabled,\n\t\t\t\t\t\t\t\t\tonClick: () => remove(id), children: t(\"multiKeyRemove\")\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"label\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", { className: ModelsSection_module_css_default[\"fieldLabel\"], children: t(\"multiKeyEntryName\") }),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"], type: \"text\", value: entry.name ?? \"\", maxLength: 120,\n\t\t\t\t\t\t\t\t\t\t\"aria-label\": `${t(\"multiKeyEntryName\")} ${String(index + 1)}`, disabled,\n\t\t\t\t\t\t\t\t\t\tonChange: (event) => update(id, { name: event.target.value })\n\t\t\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", { className: ModelsSection_module_css_default[\"fieldLabel\"], children: t(\"keyInput\") }),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ApiKeyInput, {\n\t\t\t\t\t\t\t\t\t\tt, value: draft, placeholder: t(persisted ? \"keyPlaceholderSaved\" : \"keyPlaceholder\"),\n\t\t\t\t\t\t\t\t\t\t\"aria-label\": `${t(\"keyInput\")} ${String(index + 1)}`, \"aria-invalid\": keyFailure !== void 0,\n\t\t\t\t\t\t\t\t\t\tdisabled: props.keyDisabled ?? disabled,\n\t\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\t\tconst value = event.target.value;\n\t\t\t\t\t\t\t\t\t\t\tonKeyDraftsChange((current) => ({ ...current, [id]: value }));\n\t\t\t\t\t\t\t\t\t\t\tonConfirmationsChange((current) => ({ ...current, [id]: false }));\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], children: t(status) }),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], style: { overflowWrap: \"anywhere\" }, children: t(\"multiKeyRef\").replace(\"{ref}\", () => ref) }),\n\t\t\t\t\t\t\t\t\tkeyFailure === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"error\"], children: t(keyFailure) })]\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tneedsConfirmation ? (0, react_jsx_runtime.jsxs)(\"label\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\tstyle: { display: \"flex\", alignItems: \"flex-start\", gap: 8, overflowWrap: \"anywhere\" },\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\ttype: \"checkbox\", \"data-confirm-entry\": id, \"aria-label\": t(\"multiKeyReplaceConfirm\").replace(\"{ref}\", () => ref),\n\t\t\t\t\t\t\t\t\tchecked: confirmations[id] === true, disabled: props.keyDisabled ?? disabled,\n\t\t\t\t\t\t\t\t\tonChange: (event) => onConfirmationsChange((current) => ({ ...current, [id]: event.target.checked }))\n\t\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"span\", { children: t(\"multiKeyReplaceConfirm\").replace(\"{ref}\", () => ref) })]\n\t\t\t\t\t\t\t}) : null,\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ModelListEditor, {\n\t\t\t\t\t\t\t\tmodels: modelDrafts(entry.models), onChange: (models) => update(id, { models }),\n\t\t\t\t\t\t\t\treasoningLevels: props.reasoningLevels, probe,\n\t\t\t\t\t\t\t\tprobeBlocked: keyFailure ?? props.probeBlocked ?? (!canUseStored && draft.trim().length === 0 ? \"multiKeyProbeNeedsKey\" : void 0),\n\t\t\t\t\t\t\t\toperations, t, disabled,\n\t\t\t\t\t\t\t\tonBusyChange: (value) => setBusyEntries((current) => current[id] === value ? current : { ...current, [id]: value })\n\t\t\t\t\t\t\t})]",
|
|
1015
|
+
"after": "\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\"data-key-entry-heading\": true,\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowHead\"], style: { flexWrap: \"wrap\" },\n\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowName\"],\n\t\t\t\t\t\t\t\tstyle: { minWidth: 0, overflowWrap: \"anywhere\", flex: \"1 1 120px\" }, children: heading\n\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowActions\"],\n\t\t\t\t\t\t\t\tchildren: [dirty ? (0, react_jsx_runtime.jsx)(\"span\", { className: ModelsSection_module_css_default[\"rowTag\"], \"data-key-entry-unsaved\": true, children: t(\"multiKeyUnsaved\") }) : null,\n\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"button\", {\n\t\t\t\t\t\t\t\t\ttype: \"button\", className: ModelsSection_module_css_default[\"secondaryButton\"],\n\t\t\t\t\t\t\t\t\t\"aria-expanded\": expanded, \"aria-controls\": detailsId,\n\t\t\t\t\t\t\t\t\tonClick: () => setExpandedEntries((current) => ({ ...current, [id]: !expanded })),\n\t\t\t\t\t\t\t\t\tchildren: t(expanded ? \"multiKeyCollapse\" : \"multiKeyExpand\")\n\t\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", { className: ModelsSection_module_css_default[\"fieldLabel\"], children: t(\"keyInput\") }),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ApiKeyInput, {\n\t\t\t\t\t\t\t\t\t\tt, value: draft, placeholder: t(persisted ? \"keyPlaceholderSaved\" : \"keyPlaceholder\"),\n\t\t\t\t\t\t\t\t\t\t\"aria-label\": `${t(\"keyInput\")} ${String(index + 1)}`, \"aria-invalid\": keyFailure !== void 0,\n\t\t\t\t\t\t\t\t\t\tdisabled: props.keyDisabled ?? disabled,\n\t\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\t\tconst value = event.target.value;\n\t\t\t\t\t\t\t\t\t\t\tonKeyDraftsChange((current) => ({ ...current, [id]: value }));\n\t\t\t\t\t\t\t\t\t\t\tonConfirmationsChange((current) => ({ ...current, [id]: false }));\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], children: t(status) }),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], style: { overflowWrap: \"anywhere\" }, children: t(\"multiKeyRef\").replace(\"{ref}\", () => ref) }),\n\t\t\t\t\t\t\t\t\tkeyFailure === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"error\"], children: t(keyFailure) })]\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tneedsConfirmation ? (0, react_jsx_runtime.jsxs)(\"label\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\tstyle: { display: \"flex\", alignItems: \"flex-start\", gap: 8, overflowWrap: \"anywhere\" },\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\ttype: \"checkbox\", \"data-confirm-entry\": id, \"aria-label\": t(\"multiKeyReplaceConfirm\").replace(\"{ref}\", () => ref),\n\t\t\t\t\t\t\t\t\tchecked: confirmations[id] === true, disabled: props.keyDisabled ?? disabled,\n\t\t\t\t\t\t\t\t\tonChange: (event) => onConfirmationsChange((current) => ({ ...current, [id]: event.target.checked }))\n\t\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"span\", { children: t(\"multiKeyReplaceConfirm\").replace(\"{ref}\", () => ref) })]\n\t\t\t\t\t\t\t}) : null,\n\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\tid: detailsId, \"data-key-entry-details\": true, hidden: !expanded,\n\t\t\t\t\t\t\tstyle: { display: expanded ? \"flex\" : \"none\", flexDirection: \"column\", gap: 12, minWidth: 0, borderTop: \"0.5px solid var(--dsw-alias-settings-card-stroke)\", paddingTop: 12 },\n\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\t\"data-key-entry-fields\": true, style: { display: \"grid\", gridTemplateColumns: \"repeat(auto-fit, minmax(min(100%, 220px), 1fr))\", gap: 12, minWidth: 0 }, children: [\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"label\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", { className: ModelsSection_module_css_default[\"fieldLabel\"], children: t(\"multiKeyEntryName\") }),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"], type: \"text\", value: entry.name ?? \"\", maxLength: 120,\n\t\t\t\t\t\t\t\t\t\t\"aria-label\": `${t(\"multiKeyEntryName\")} ${String(index + 1)}`, disabled,\n\t\t\t\t\t\t\t\t\t\tonChange: (event) => update(id, { name: event.target.value })\n\t\t\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"label\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", { className: ModelsSection_module_css_default[\"fieldLabel\"], children: t(\"multiKeyProtocol\") }),\n\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"select\", {\n\t\t\t\t\t\t\t\t\t\"data-key-entry-protocol\": id, \"aria-label\": t(\"multiKeyProtocol\") + \" \" + heading,\n\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"] + \" \" + ModelsSection_module_css_default[\"selectInput\"],\n\t\t\t\t\t\t\t\t\tstyle: { maxWidth: \"none\" }, value: entry.api ?? \"\", disabled: disabled || anyBusy,\n\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\tconst value = event.target.value;\n\t\t\t\t\t\t\t\t\t\tif (disabled || anyBusy || value !== \"\" && !MULTI_KEY_PROTOCOLS.has(value)) return;\n\t\t\t\t\t\t\t\t\t\tconst { api, ...inherited } = entries[id];\n\t\t\t\t\t\t\t\t\t\tonChange({ ...entries, [id]: value === \"\" ? inherited : { ...inherited, api: value } });\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"option\", { value: \"\", children: t(\"multiKeyProtocolInherit\").replace(\"{protocol}\", () => props.probe.api ? protocolLabel(t, props.probe.api) : t(\"multiKeyProtocolDefault\")) }),\n\t\t\t\t\t\t\t\t\t...(props.protocols ?? [...MULTI_KEY_PROTOCOLS]).map((choice) => (0, react_jsx_runtime.jsx)(\"option\", { value: choice, children: protocolLabel(t, choice) }, choice))]\n\t\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"span\", { className: ModelsSection_module_css_default[\"advancedHint\"], children: t(\"multiKeyProtocolHelp\") })]\n\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ModelListEditor, {\n\t\t\t\t\t\t\t\tmodels: modelDrafts(entry.models), onChange: (models) => update(id, { models }),\n\t\t\t\t\t\t\t\treasoningLevels: props.reasoningLevels, probe,\n\t\t\t\t\t\t\t\tprobeBlocked: keyFailure ?? props.probeBlocked ?? (!canUseStored && draft.trim().length === 0 ? \"multiKeyProbeNeedsKey\" : void 0),\n\t\t\t\t\t\t\t\toperations, t, disabled,\n\t\t\t\t\t\t\t\tonBusyChange: (value) => setBusyEntries((current) => current[id] === value ? current : { ...current, [id]: value })\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\t\"data-key-entry-danger-zone\": true,\n\t\t\t\t\t\t\t\tstyle: { display: \"flex\", flexDirection: \"column\", gap: 6, borderTop: \"0.5px solid var(--dsw-alias-settings-card-stroke)\", paddingTop: 12 },\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], children: t(\"multiKeyRemoveHelp\") }),\n\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"button\", {\n\t\t\t\t\t\t\t\t\ttype: \"button\", \"data-key-entry-remove\": id,\n\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"dangerButton\"], style: { alignSelf: \"flex-start\" }, disabled: disabled || anyBusy,\n\t\t\t\t\t\t\t\t\tonClick: () => { if (!disabled && !anyBusy) setRemoveTarget(id); }, children: t(\"multiKeyRemoveGroup\")\n\t\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t})]"
|
|
1016
|
+
},
|
|
1017
|
+
{
|
|
1018
|
+
"before": "}), (0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], children: t(\"multiKeyKeepCredentials\") })]",
|
|
1019
|
+
"after": "}), (0, react_jsx_runtime.jsx)(\"p\", { className: ModelsSection_module_css_default[\"advancedHint\"], children: t(\"multiKeyKeepCredentials\") }),\n\t\t\t\t(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {\n\t\t\t\t\topen: removeTarget !== void 0 && Object.hasOwn(entries, removeTarget) && !disabled && !anyBusy,\n\t\t\t\t\t\"data-key-entry-remove-dialog\": true, onClose: () => setRemoveTarget(void 0),\n\t\t\t\t\ttitle: t(\"multiKeyRemoveTitle\").replace(\"{name}\", () => removeName), closeLabel: t(\"close\"),\n\t\t\t\t\tdescription: t(\"multiKeyRemoveDescription\"), className: ModelsSection_module_css_default[\"deleteDialog\"],\n\t\t\t\t\tfooter: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [\n\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, { variant: \"outline\", \"data-modal-autofocus\": true, onClick: () => setRemoveTarget(void 0), children: t(\"cancel\") }),\n\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {\n\t\t\t\t\t\t\tvariant: \"outline\", className: ModelsSection_module_css_default[\"deleteConfirm\"], disabled: disabled || anyBusy,\n\t\t\t\t\t\t\tonClick: () => { if (removeTarget === void 0 || disabled || anyBusy) return; remove(removeTarget); setRemoveTarget(void 0); }, children: t(\"multiKeyRemoveGroup\")\n\t\t\t\t\t\t})]\n\t\t\t\t\t})\n\t\t\t\t})]"
|
|
1020
|
+
},
|
|
1021
|
+
{
|
|
1022
|
+
"before": "function CustomProviderCard(props) {\n\t\t\tconst { taken, protocols, reasoningLevels, operations, t, onBusyChange } = props;\n\t\t\tconst supportsMultiKey = supportsMultiKeySchema(props.namespace, props.schema, [\"providers\", PROBE_ROUTE]);\n\t\t\tconst [openedAt] = (0, react.useState)(() => props.revision);\n\t\t\tconst [route, setRoute] = (0, react.useState)(\"\");\n\t\t\tconst [displayName, setDisplayName] = (0, react.useState)(\"\");\n\t\t\tconst [baseURL, setBaseURL] = (0, react.useState)(\"\");\n\t\t\tconst [protocol, setProtocol] = (0, react.useState)(protocols[0] ?? \"\");\n\t\t\tconst [keyDraft, setKeyDraft] = (0, react.useState)(\"\");\n\t\t\tconst [models, setModels] = (0, react.useState)([]);\n\t\t\tconst [multiKey, setMultiKey] = (0, react.useState)(false);\n\t\t\tconst [keyEntries, setKeyEntries] = (0, react.useState)({});\n\t\t\tconst [entryKeyDrafts, setEntryKeyDrafts] = (0, react.useState)({});\n\t\t\tconst [entryConfirmations, setEntryConfirmations] = (0, react.useState)({});\n\t\t\tconst saving = (0, react.useRef)(false);\n\t\t\tconst [busy, setBusy] = (0, react.useState)(false);\n\t\t\tconst [listBusy, setListBusy] = (0, react.useState)(false);\n\t\t\t(0, react.useEffect)(() => {\n\t\t\t\tonBusyChange?.(busy || listBusy);\n\t\t\t}, [\n\t\t\t\tbusy,\n\t\t\t\tlistBusy,\n\t\t\t\tonBusyChange\n\t\t\t]);\n\t\t\tconst [failure, setFailure] = (0, react.useState)(void 0);\n\t\t\t/**\n\t\t\t* The profile write landed. Only the key write can still be outstanding, so\n\t\t\t* the fields that describe the provider are settled and the retry path is\n\t\t\t* the credential alone.\n\t\t\t*/\n\t\t\tconst [committed, setCommitted] = (0, react.useState)(false);\n\t\t\tconst disabled = props.readOnly || busy;\n\t\t\t/** Everything but the key stops being editable once the provider exists. */\n\t\t\tconst profileDisabled = disabled || committed;\n\t\t\tconst routeInvalid = route.length > 0 && !ROUTE_PATTERN.test(route);\n\t\t\tconst routeTaken = taken.includes(route);\n\t\t\tconst normalizedBaseURL = baseURL.trim();\n\t\t\tconst baseUrlInvalid = baseURL.length > 0 && !isHttpUrl(normalizedBaseURL);\n\t\t\tconst modelFailure = multiKey ? void 0 : validateDeepSeekModels(models) ?? validateReasoningEfforts(models);\n\t\t\tconst entryFailure = multiKey ? multiKeyFailure(route, keyEntries, entryKeyDrafts, entryConfirmations, t) : void 0;\n\t\t\tconst keyFailure = multiKey ? void 0 : apiKeyFailure(keyDraft);\n\t\t\tconst keyValue = keyDraft.trim();\n\t\t\tconst ready = (committed || route.length > 0 && !routeInvalid && !routeTaken) && normalizedBaseURL.length > 0 && !baseUrlInvalid && (multiKey ? entryFailure === void 0 : models.length > 0 && modelFailure === void 0 && keyFailure === void 0);\n\t\t\tconst hint = entryFailure ?? (failure !== void 0 || ready || keyFailure !== void 0 || route.length === 0 || routeInvalid || routeTaken || baseUrlInvalid ? void 0 : normalizedBaseURL.length === 0 ? t(\"customNeedsBaseUrl\") : modelFailure !== void 0 ? `${t(\"model\")} ${String(modelFailure.index + 1)}: ${t(modelFailure.key)}` : t(\"customNeedsModels\"));\n\t\t\t/** Perform the create, returning a failure message or undefined. */\n\t\t\tconst createOnce = async () => {\n\t\t\t\tconst entries = normalizedMultiKeyEntries(route, keyEntries);\n\t\t\t\tconst firstEntry = Object.values(entries)[0];\n\t\t\t\tconst keyRef = multiKey ? firstEntry?.apiKeyEnv : deriveKeyRef(route);\n\t\t\t\tconst storesKey = !multiKey && keyValue.length > 0;\n\t\t\t\tif (multiKey && entryFailure !== void 0) return entryFailure;\n\t\t\t\tif (!committed) {\n\t\t\t\t\tconst profile = {\n\t\t\t\t\t\t...displayName.length === 0 ? {} : { displayName },\n\t\t\t\t\t\t...storesKey || multiKey ? { apiKeyEnv: keyRef } : {},\n\t\t\t\t\t\tapi: protocol,\n\t\t\t\t\t\tbaseURL: normalizedBaseURL,\n\t\t\t\t\t\tmodels: (multiKey ? firstEntry.models : models).map((model) => ({ ...model })),\n\t\t\t\t\t\t...(multiKey || Object.keys(keyEntries).length > 0 ? { multiKey, keyEntries: entries } : {})\n\t\t\t\t\t};\n\t\t\t\t\tconst written = await operations.writeSettings(NS$1, [{\n\t\t\t\t\t\top: \"set\",\n\t\t\t\t\t\tpath: [\"providers\", route],\n\t\t\t\t\t\tvalue: profile\n\t\t\t\t\t}], openedAt);\n\t\t\t\t\tif (written.kind !== \"written\") return written.kind === \"conflict\" ? t(\"conflict\") : written.message;\n\t\t\t\t\tsetCommitted(true);\n\t\t\t\t}\n\t\t\t\tif (multiKey) return storeMultiKeyDrafts(operations, entries, entryKeyDrafts, setEntryKeyDrafts);\n\t\t\t\tif (storesKey) {\n\t\t\t\t\tconst stored = await operations.storeCredential(keyRef, keyValue);\n\t\t\t\t\tif (stored !== void 0) return stored;\n\t\t\t\t\tsetKeyDraft(\"\");\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst create = async () => {\n\t\t\t\tif (saving.current || !ready || props.readOnly || listBusy) return;\n\t\t\t\tsaving.current = true;\n\t\t\t\tsetBusy(true);\n\t\t\t\tsetFailure(void 0);\n\t\t\t\ttry {\n\t\t\t\t\tconst outcome = await createOnce();\n\t\t\t\t\tif (outcome !== void 0) {\n\t\t\t\t\t\tsetFailure(outcome);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tprops.onClose(true);\n\t\t\t\t} catch {\n\t\t\t\t\tsetFailure(t(\"multiKeySaveFailed\"));\n\t\t\t\t} finally {\n\t\t\t\t\tsaving.current = false;\n\t\t\t\t\tsetBusy(false);\n\t\t\t\t}\n\t\t\t};\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\tclassName: ModelsSection_module_css_default[\"editor\"],\n\t\t\t\tchildren: [\n\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: t(\"customRoute\")\n\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\tvalue: route,\n\t\t\t\t\t\t\tplaceholder: \"acme-gateway\",\n\t\t\t\t\t\t\t\"aria-label\": t(\"customRoute\"),\n\t\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetRoute(event.target.value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})]\n\t\t\t\t\t}),\n\t\t\t\t\trouteInvalid || routeTaken ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: t(routeInvalid ? \"customRouteInvalid\" : \"customRouteTaken\")\n\t\t\t\t\t}) : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\tchildren: t(\"customRouteHint\")\n\t\t\t\t\t}),\n\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: t(\"customDisplayName\")\n\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\tvalue: displayName,\n\t\t\t\t\t\t\tplaceholder: route.length === 0 ? t(\"customDisplayName\") : route,\n\t\t\t\t\t\t\t\"aria-label\": t(\"customDisplayName\"),\n\t\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetDisplayName(event.target.value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})]\n\t\t\t\t\t}),\n\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: t(\"baseUrl\")\n\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\tvalue: baseURL,\n\t\t\t\t\t\t\tplaceholder: t(protocol === \"anthropic-messages\" ? \"customAnthropicBaseUrlPlaceholder\" : \"customBaseUrlPlaceholder\"),\n\t\t\t\t\t\t\t\"aria-label\": t(\"baseUrl\"),\n\t\t\t\t\t\t\t\"aria-invalid\": baseUrlInvalid,\n\t\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetBaseURL(event.target.value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})]\n\t\t\t\t\t}),\n\t\t\t\t\tbaseUrlInvalid ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: t(\"customBaseUrlInvalid\")\n\t\t\t\t\t}) : null,\n\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: t(\"customApi\")\n\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"select\", {\n\t\t\t\t\t\t\tclassName: `${ModelsSection_module_css_default[\"input\"]} ${ModelsSection_module_css_default[\"selectInput\"]}`,\n\t\t\t\t\t\t\tvalue: protocol,\n\t\t\t\t\t\t\t\"aria-label\": t(\"customApi\"),\n\t\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetProtocol(event.target.value);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tchildren: protocols.map((choice) => (0, react_jsx_runtime.jsx)(\"option\", {\n\t\t\t\t\t\t\t\tvalue: choice,\n\t\t\t\t\t\t\t\tchildren: protocolLabel(t, choice)\n\t\t\t\t\t\t\t}, choice))\n\t\t\t\t\t\t})]\n\t\t\t\t\t}),\n\t\t\t\t\tsupportsMultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyToggle, {\n\t\t\t\t\t\tt, checked: multiKey, disabled: profileDisabled || listBusy, hasUnsavedKeys: hasMultiKeyDrafts(entryKeyDrafts),\n\t\t\t\t\t\tonChange: (enabled) => {\n\t\t\t\t\t\t\tif (enabled && Object.keys(keyEntries).length === 0) {\n\t\t\t\t\t\t\t\tconst [id, entry] = newMultiKeyEntry(route, { name: displayName || route || t(\"multiKeyDefaultName\"), models });\n\t\t\t\t\t\t\t\tsetKeyEntries({ [id]: entry });\n\t\t\t\t\t\t\t\tif (keyDraft.length > 0) setEntryKeyDrafts({ [id]: keyDraft });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsetMultiKey(enabled);\n\t\t\t\t\t\t}\n\t\t\t\t\t}) : null,\n\t\t\t\t\tmultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyEntriesEditor, {\n\t\t\t\t\t\troute, entries: keyEntries, onChange: setKeyEntries,\n\t\t\t\t\t\tkeyDrafts: entryKeyDrafts, onKeyDraftsChange: setEntryKeyDrafts,\n\t\t\t\t\t\tconfirmations: entryConfirmations, onConfirmationsChange: setEntryConfirmations,\n\t\t\t\t\t\tpersistedEntries: committed ? normalizedMultiKeyEntries(route, keyEntries) : {},\n\t\t\t\t\t\tprobe: { settingsNs: NS$1, ...(committed ? { provider: route } : {}), baseURL: normalizedBaseURL, api: protocol },\n\t\t\t\t\t\tprobeBlocked: baseUrlInvalid ? \"customBaseUrlInvalid\" : normalizedBaseURL.length === 0 ? \"customNeedsBaseUrl\" : void 0,\n\t\t\t\t\t\treasoningLevels, operations, t, disabled: profileDisabled || listBusy, keyDisabled: disabled || listBusy, onBusyChange: setListBusy\n\t\t\t\t\t}) : null,\n\t\t\t\t\tmultiKey ? null : (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\tchildren: t(\"keyInput\")\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ApiKeyInput, {\n\t\t\t\t\t\t\t\tt,\n\t\t\t\t\t\t\t\tvalue: keyDraft,\n\t\t\t\t\t\t\t\tplaceholder: t(\"keyPlaceholder\"),\n\t\t\t\t\t\t\t\t\"aria-label\": t(\"keyInput\"),\n\t\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\tsetKeyDraft(event.target.value);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tkeyFailure === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\t\t\tchildren: t(keyFailure === \"keyBlank\" ? \"keyBlankNew\" : keyFailure)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t]\n\t\t\t\t\t}),\n\t\t\t\t\t!multiKey ? (0, react_jsx_runtime.jsx)(ModelListEditor, {\n\t\t\t\t\t\tmodels,\n\t\t\t\t\t\tonChange: setModels,\n\t\t\t\t\t\treasoningLevels,\n\t\t\t\t\t\tprobe: {\n\t\t\t\t\t\t\tsettingsNs: NS$1,\n\t\t\t\t\t\t\tbaseURL: normalizedBaseURL,\n\t\t\t\t\t\t\tapi: protocol,\n\t\t\t\t\t\t\t...keyValue.length === 0 ? {} : { apiKey: keyValue }\n\t\t\t\t\t\t},\n\t\t\t\t\t\tprobeBlocked: baseUrlInvalid ? \"customBaseUrlInvalid\" : keyFailure === \"keyBlank\" ? \"keyBlankNew\" : keyFailure,\n\t\t\t\t\t\toperations,\n\t\t\t\t\t\tt,\n\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\tonBusyChange: setListBusy\n\t\t\t\t\t}) : null,\n\t\t\t\t\tfailure !== void 0 ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: failure\n\t\t\t\t\t}) : null,\n\t\t\t\t\thint === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\tchildren: hint\n\t\t\t\t\t}),\n\t\t\t\t\t(0, react_jsx_runtime.jsx)(EditorFooter, {\n\t\t\t\t\t\tt,\n\t\t\t\t\t\tbusy,\n\t\t\t\t\t\tsubmitDisabled: disabled || listBusy || !ready,\n\t\t\t\t\t\tsubmitLabelKey: \"create\",\n\t\t\t\t\t\tsubmitBusyLabelKey: \"creating\",\n\t\t\t\t\t\tonCancel: () => {\n\t\t\t\t\t\t\tprops.onClose(committed);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonSubmit: () => {\n\t\t\t\t\t\t\tcreate();\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t]\n\t\t\t});\n\t\t}",
|
|
1023
|
+
"after": "function CustomProviderCard(props) {\n\t\t\tconst { taken, protocols, reasoningLevels, operations, t, onBusyChange } = props;\n\t\t\tconst supportsMultiKey = supportsMultiKeySchema(props.namespace, props.schema, [\"providers\", PROBE_ROUTE]);\n\t\t\tconst [openedAt] = (0, react.useState)(() => props.revision);\n\t\t\tconst [route, setRoute] = (0, react.useState)(\"\");\n\t\t\tconst [displayName, setDisplayName] = (0, react.useState)(\"\");\n\t\t\tconst [baseURL, setBaseURL] = (0, react.useState)(\"\");\n\t\t\tconst [protocol, setProtocol] = (0, react.useState)(protocols[0] ?? \"\");\n\t\t\tconst [keyDraft, setKeyDraft] = (0, react.useState)(\"\");\n\t\t\tconst [models, setModels] = (0, react.useState)([]);\n\t\t\tconst [multiKey, setMultiKey] = (0, react.useState)(false);\n\t\t\tconst [keyEntries, setKeyEntries] = (0, react.useState)({});\n\t\t\tconst [entryKeyDrafts, setEntryKeyDrafts] = (0, react.useState)({});\n\t\t\tconst [entryConfirmations, setEntryConfirmations] = (0, react.useState)({});\n\t\t\tconst [entrySaveState, setEntrySaveState] = (0, react.useState)(void 0);\n\t\t\tconst saving = (0, react.useRef)(false);\n\t\t\tconst [busy, setBusy] = (0, react.useState)(false);\n\t\t\tconst [listBusy, setListBusy] = (0, react.useState)(false);\n\t\t\t(0, react.useEffect)(() => {\n\t\t\t\tonBusyChange?.(busy || listBusy);\n\t\t\t}, [\n\t\t\t\tbusy,\n\t\t\t\tlistBusy,\n\t\t\t\tonBusyChange\n\t\t\t]);\n\t\t\tconst [failure, setFailure] = (0, react.useState)(void 0);\n\t\t\t/**\n\t\t\t* The profile write landed. Only the key write can still be outstanding, so\n\t\t\t* the fields that describe the provider are settled and the retry path is\n\t\t\t* the credential alone.\n\t\t\t*/\n\t\t\tconst [committed, setCommitted] = (0, react.useState)(false);\n\t\t\tconst disabled = props.readOnly || busy;\n\t\t\t/** Everything but the key stops being editable once the provider exists. */\n\t\t\tconst profileDisabled = disabled || committed;\n\t\t\tconst routeInvalid = route.length > 0 && !ROUTE_PATTERN.test(route);\n\t\t\tconst routeTaken = taken.includes(route);\n\t\t\tconst normalizedBaseURL = baseURL.trim();\n\t\t\tconst baseUrlInvalid = baseURL.length > 0 && !isHttpUrl(normalizedBaseURL);\n\t\t\tconst modelFailure = multiKey ? void 0 : validateDeepSeekModels(models) ?? validateReasoningEfforts(models);\n\t\t\tconst entryFailure = multiKey ? multiKeyFailure(route, keyEntries, entryKeyDrafts, entryConfirmations, t) : void 0;\n\t\t\tconst keyFailure = multiKey ? void 0 : apiKeyFailure(keyDraft);\n\t\t\tconst keyValue = keyDraft.trim();\n\t\t\tconst ready = (committed || route.length > 0 && !routeInvalid && !routeTaken) && normalizedBaseURL.length > 0 && !baseUrlInvalid && (multiKey ? entryFailure === void 0 : models.length > 0 && modelFailure === void 0 && keyFailure === void 0);\n\t\t\tconst hint = entryFailure ?? (failure !== void 0 || ready || keyFailure !== void 0 || route.length === 0 || routeInvalid || routeTaken || baseUrlInvalid ? void 0 : normalizedBaseURL.length === 0 ? t(\"customNeedsBaseUrl\") : modelFailure !== void 0 ? `${t(\"model\")} ${String(modelFailure.index + 1)}: ${t(modelFailure.key)}` : t(\"customNeedsModels\"));\n\t\t\t/** Perform the create, returning a failure message or undefined. */\n\t\t\tconst createOnce = async () => {\n\t\t\t\tconst entries = normalizedMultiKeyEntries(route, keyEntries);\n\t\t\t\tconst firstEntry = Object.values(entries)[0];\n\t\t\t\tconst keyRef = multiKey ? firstEntry?.apiKeyEnv : deriveKeyRef(route);\n\t\t\t\tconst storesKey = !multiKey && keyValue.length > 0;\n\t\t\t\tif (multiKey && entryFailure !== void 0) return entryFailure;\n\t\t\t\tif (!committed) {\n\t\t\t\t\tconst profile = {\n\t\t\t\t\t\t...displayName.length === 0 ? {} : { displayName },\n\t\t\t\t\t\t...storesKey || multiKey ? { apiKeyEnv: keyRef } : {},\n\t\t\t\t\t\tapi: protocol,\n\t\t\t\t\t\tbaseURL: normalizedBaseURL,\n\t\t\t\t\t\tmodels: (multiKey ? firstEntry.models : models).map((model) => ({ ...model })),\n\t\t\t\t\t\t...(multiKey || Object.keys(keyEntries).length > 0 ? { multiKey, keyEntries: entries } : {})\n\t\t\t\t\t};\n\t\t\t\t\tconst written = await operations.writeSettings(NS$1, [{\n\t\t\t\t\t\top: \"set\",\n\t\t\t\t\t\tpath: [\"providers\", route],\n\t\t\t\t\t\tvalue: profile\n\t\t\t\t\t}], openedAt);\n\t\t\t\t\tif (written.kind !== \"written\") return written.kind === \"conflict\" ? t(\"conflict\") : written.message;\n\t\t\t\t\tsetCommitted(true);\n\t\t\t\t}\n\t\t\t\tif (multiKey) return storeMultiKeyDrafts(operations, entries, entryKeyDrafts, setEntryKeyDrafts);\n\t\t\t\tif (storesKey) {\n\t\t\t\t\tconst stored = await operations.storeCredential(keyRef, keyValue);\n\t\t\t\t\tif (stored !== void 0) return stored;\n\t\t\t\t\tsetKeyDraft(\"\");\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst create = async () => {\n\t\t\t\tif (saving.current || !ready || props.readOnly || listBusy) return;\n\t\t\t\tsaving.current = true;\n\t\t\t\tsetBusy(true);\n\t\t\t\tsetFailure(void 0);\n\t\t\t\ttry {\n\t\t\t\t\tconst outcome = await createOnce();\n\t\t\t\t\tif (multiKey) setEntrySaveState({ ok: outcome === void 0, entries: structuredClone(outcome === void 0 ? normalizedMultiKeyEntries(route, keyEntries) : keyEntries) });\n\t\t\t\t\tif (outcome !== void 0) {\n\t\t\t\t\t\tsetFailure(outcome);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tprops.onClose(true);\n\t\t\t\t} catch {\n\t\t\t\t\tif (multiKey) setEntrySaveState({ ok: false, entries: structuredClone(keyEntries) });\n\t\t\t\t\tsetFailure(t(\"multiKeySaveFailed\"));\n\t\t\t\t} finally {\n\t\t\t\t\tsaving.current = false;\n\t\t\t\t\tsetBusy(false);\n\t\t\t\t}\n\t\t\t};\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\tclassName: ModelsSection_module_css_default[\"editor\"],\n\t\t\t\tchildren: [\n\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: t(\"customRoute\")\n\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\tvalue: route,\n\t\t\t\t\t\t\tplaceholder: \"acme-gateway\",\n\t\t\t\t\t\t\t\"aria-label\": t(\"customRoute\"),\n\t\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetRoute(event.target.value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})]\n\t\t\t\t\t}),\n\t\t\t\t\trouteInvalid || routeTaken ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: t(routeInvalid ? \"customRouteInvalid\" : \"customRouteTaken\")\n\t\t\t\t\t}) : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\tchildren: t(\"customRouteHint\")\n\t\t\t\t\t}),\n\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: t(\"customDisplayName\")\n\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\tvalue: displayName,\n\t\t\t\t\t\t\tplaceholder: route.length === 0 ? t(\"customDisplayName\") : route,\n\t\t\t\t\t\t\t\"aria-label\": t(\"customDisplayName\"),\n\t\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetDisplayName(event.target.value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})]\n\t\t\t\t\t}),\n\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: t(\"baseUrl\")\n\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\tvalue: baseURL,\n\t\t\t\t\t\t\tplaceholder: t(protocol === \"anthropic-messages\" ? \"customAnthropicBaseUrlPlaceholder\" : \"customBaseUrlPlaceholder\"),\n\t\t\t\t\t\t\t\"aria-label\": t(\"baseUrl\"),\n\t\t\t\t\t\t\t\"aria-invalid\": baseUrlInvalid,\n\t\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetBaseURL(event.target.value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})]\n\t\t\t\t\t}),\n\t\t\t\t\tbaseUrlInvalid ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: t(\"customBaseUrlInvalid\")\n\t\t\t\t\t}) : null,\n\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: t(\"customApi\")\n\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"select\", {\n\t\t\t\t\t\t\tclassName: `${ModelsSection_module_css_default[\"input\"]} ${ModelsSection_module_css_default[\"selectInput\"]}`,\n\t\t\t\t\t\t\tvalue: protocol,\n\t\t\t\t\t\t\t\"aria-label\": t(\"customApi\"),\n\t\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetProtocol(event.target.value);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tchildren: protocols.map((choice) => (0, react_jsx_runtime.jsx)(\"option\", {\n\t\t\t\t\t\t\t\tvalue: choice,\n\t\t\t\t\t\t\t\tchildren: protocolLabel(t, choice)\n\t\t\t\t\t\t\t}, choice))\n\t\t\t\t\t\t})]\n\t\t\t\t\t}),\n\t\t\t\t\tsupportsMultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyToggle, {\n\t\t\t\t\t\tt, checked: multiKey, disabled: profileDisabled || listBusy, hasUnsavedKeys: hasMultiKeyDrafts(entryKeyDrafts),\n\t\t\t\t\t\tonChange: (enabled) => {\n\t\t\t\t\t\t\tif (enabled && Object.keys(keyEntries).length === 0) {\n\t\t\t\t\t\t\t\tconst [id, entry] = newMultiKeyEntry(route, { name: displayName || route || t(\"multiKeyDefaultName\"), models });\n\t\t\t\t\t\t\t\tsetKeyEntries({ [id]: entry });\n\t\t\t\t\t\t\t\tif (keyDraft.length > 0) setEntryKeyDrafts({ [id]: keyDraft });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsetMultiKey(enabled);\n\t\t\t\t\t\t}\n\t\t\t\t\t}) : null,\n\t\t\t\t\tmultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyEntriesEditor, {\n\t\t\t\t\t\troute, entries: keyEntries, protocols, saveState: entrySaveState, savedEntries: entrySaveState?.ok ? entrySaveState.entries : void 0, onChange: setKeyEntries,\n\t\t\t\t\t\tkeyDrafts: entryKeyDrafts, onKeyDraftsChange: setEntryKeyDrafts,\n\t\t\t\t\t\tconfirmations: entryConfirmations, onConfirmationsChange: setEntryConfirmations,\n\t\t\t\t\t\tpersistedEntries: committed ? normalizedMultiKeyEntries(route, keyEntries) : {},\n\t\t\t\t\t\tprobe: { settingsNs: NS$1, ...(committed ? { provider: route } : {}), baseURL: normalizedBaseURL, api: protocol },\n\t\t\t\t\t\tprobeBlocked: baseUrlInvalid ? \"customBaseUrlInvalid\" : normalizedBaseURL.length === 0 ? \"customNeedsBaseUrl\" : void 0,\n\t\t\t\t\t\treasoningLevels, operations, t, disabled: profileDisabled || listBusy, keyDisabled: disabled || listBusy, onBusyChange: setListBusy\n\t\t\t\t\t}) : null,\n\t\t\t\t\tmultiKey ? null : (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\tchildren: t(\"keyInput\")\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ApiKeyInput, {\n\t\t\t\t\t\t\t\tt,\n\t\t\t\t\t\t\t\tvalue: keyDraft,\n\t\t\t\t\t\t\t\tplaceholder: t(\"keyPlaceholder\"),\n\t\t\t\t\t\t\t\t\"aria-label\": t(\"keyInput\"),\n\t\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\tsetKeyDraft(event.target.value);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tkeyFailure === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\t\t\tchildren: t(keyFailure === \"keyBlank\" ? \"keyBlankNew\" : keyFailure)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t]\n\t\t\t\t\t}),\n\t\t\t\t\t!multiKey ? (0, react_jsx_runtime.jsx)(ModelListEditor, {\n\t\t\t\t\t\tmodels,\n\t\t\t\t\t\tonChange: setModels,\n\t\t\t\t\t\treasoningLevels,\n\t\t\t\t\t\tprobe: {\n\t\t\t\t\t\t\tsettingsNs: NS$1,\n\t\t\t\t\t\t\tbaseURL: normalizedBaseURL,\n\t\t\t\t\t\t\tapi: protocol,\n\t\t\t\t\t\t\t...keyValue.length === 0 ? {} : { apiKey: keyValue }\n\t\t\t\t\t\t},\n\t\t\t\t\t\tprobeBlocked: baseUrlInvalid ? \"customBaseUrlInvalid\" : keyFailure === \"keyBlank\" ? \"keyBlankNew\" : keyFailure,\n\t\t\t\t\t\toperations,\n\t\t\t\t\t\tt,\n\t\t\t\t\t\tdisabled: profileDisabled,\n\t\t\t\t\t\tonBusyChange: setListBusy\n\t\t\t\t\t}) : null,\n\t\t\t\t\tfailure !== void 0 ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: failure\n\t\t\t\t\t}) : null,\n\t\t\t\t\thint === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\tchildren: hint\n\t\t\t\t\t}),\n\t\t\t\t\t(0, react_jsx_runtime.jsx)(EditorFooter, {\n\t\t\t\t\t\tt,\n\t\t\t\t\t\tbusy,\n\t\t\t\t\t\tsubmitDisabled: disabled || listBusy || !ready,\n\t\t\t\t\t\tsubmitLabelKey: \"create\",\n\t\t\t\t\t\tsubmitBusyLabelKey: \"creating\",\n\t\t\t\t\t\tonCancel: () => {\n\t\t\t\t\t\t\tprops.onClose(committed);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonSubmit: () => {\n\t\t\t\t\t\t\tcreate();\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t]\n\t\t\t});\n\t\t}"
|
|
1024
|
+
},
|
|
1025
|
+
{
|
|
1026
|
+
"before": "function ProviderEditor(props) {\n\t\t\tconst { namespace, schema, settingsPath, operations, t } = props;\n\t\t\tconst [draft, setDraft] = (0, react.useState)(() => draftAt(schema, namespace, settingsPath));\n\t\t\tconst [entryKeyDrafts, setEntryKeyDrafts] = (0, react.useState)({});\n\t\t\tconst [entryConfirmations, setEntryConfirmations] = (0, react.useState)({});\n\t\t\tconst saving = (0, react.useRef)(false);\n\t\t\tconst [keyDraft, setKeyDraft] = (0, react.useState)(\"\");\n\t\t\tconst [busy, setBusy] = (0, react.useState)(false);\n\t\t\tconst [listBusy, setListBusy] = (0, react.useState)(false);\n\t\t\tconst { onBusyChange } = props;\n\t\t\t(0, react.useEffect)(() => {\n\t\t\t\tonBusyChange?.(busy || listBusy);\n\t\t\t}, [\n\t\t\t\tbusy,\n\t\t\t\tlistBusy,\n\t\t\t\tonBusyChange\n\t\t\t]);\n\t\t\tconst [failure, setFailure] = (0, react.useState)(void 0);\n\t\t\tconst [committedOriginal, setCommittedOriginal] = (0, react.useState)(() => schema.getPath(namespace.user, settingsPath));\n\t\t\tconst [expectedRevision, setExpectedRevision] = (0, react.useState)(() => namespace.revision);\n\t\t\tconst root = (0, react.useMemo)(() => schema.rehydrate(namespace.schema), [namespace.schema, schema]);\n\t\t\tconst node = (0, react.useMemo)(() => schema.nodeAtPath(root, settingsPath), [\n\t\t\t\troot,\n\t\t\t\tschema,\n\t\t\t\tsettingsPath\n\t\t\t]);\n\t\t\tconst fallback = schema.getPath(namespace.value, settingsPath);\n\t\t\tconst disabled = props.readOnly || busy;\n\t\t\tconst layout = layoutOf(namespace.ns);\n\t\t\tconst keyRef = refFor(schema, namespace, settingsPath, props.provider);\n\t\t\tconst supportsMultiKey = layout === \"pi-ai\" && props.declared === true && props.credentialOnly !== true && supportsMultiKeySchema(namespace, schema, settingsPath);\n\t\t\tconst multiKey = supportsMultiKey && (draft.multiKey ?? fallback?.multiKey) === true;\n\t\t\tconst keyEntries = draft.keyEntries ?? fallback?.keyEntries ?? {};\n\t\t\tconst entryFailure = multiKey ? multiKeyFailure(props.provider, keyEntries, entryKeyDrafts, entryConfirmations, t) : void 0;\n\t\t\tconst protocols = (0, react.useMemo)(() => layout === \"pi-ai\" ? protocolChoices(namespace, schema) : [], [\n\t\t\t\tlayout,\n\t\t\t\tnamespace,\n\t\t\t\tschema\n\t\t\t]);\n\t\t\tconst stringAt = (source, key) => {\n\t\t\t\tconst value = schema.getPath(source, [key]);\n\t\t\t\treturn typeof value === \"string\" && value.trim().length > 0 ? value : void 0;\n\t\t\t};\n\t\t\tconst setField = (key, next) => {\n\t\t\t\tconst value = next === void 0 || next.trim().length === 0 ? void 0 : next;\n\t\t\t\tsetDraft((current) => value === void 0 ? schema.deletePath(current, [key]) : schema.setPath(current, [key], value));\n\t\t\t};\n\t\t\tconst reasoningLevels = (0, react.useMemo)(() => layout === \"pi-ai\" && props.declared === true ? reasoningLevelChoices(namespace, schema) : [], [\n\t\t\t\tlayout,\n\t\t\t\tprops.declared,\n\t\t\t\tnamespace,\n\t\t\t\tschema\n\t\t\t]);\n\t\t\tconst editsReasoning = reasoningLevels.length > 0;\n\t\t\tconst validateModels = (value) => validateDeepSeekModels(value) ?? (editsReasoning ? validateReasoningEfforts(value) : void 0);\n\t\t\tconst modelFailure = multiKey ? void 0 : validateModels(schema.getPath(draft, [\"models\"]));\n\t\t\tconst keyFailure = multiKey ? void 0 : apiKeyFailure(keyDraft);\n\t\t\tconst keyValue = keyDraft.trim();\n\t\t\tconst shownKeyFailure = (props.credentialRequired === true && keyDraft.length > 0 && keyValue.length === 0 ? \"keyRequired\" : void 0) ?? keyFailure;\n\t\t\tconst probeApi = stringAt(draft, \"api\") ?? stringAt(fallback, \"api\");\n\t\t\tconst probeBaseURL = stringAt(draft, \"baseURL\") ?? stringAt(fallback, \"baseURL\");\n\t\t\tconst probe = {\n\t\t\t\tsettingsNs: namespace.ns,\n\t\t\t\tprovider: props.provider,\n\t\t\t\t...probeBaseURL === void 0 ? {} : { baseURL: probeBaseURL },\n\t\t\t\t...probeApi === void 0 ? {} : { api: probeApi },\n\t\t\t\t...keyValue.length === 0 ? {} : { apiKey: keyValue }\n\t\t\t};\n\t\t\t/**\n\t\t\t* The write for this card, or a failure message. Every edit travels as\n\t\t\t* path ops against the STORED section: the draft comes from the redacted\n\t\t\t* descriptor, so a wholesale replace rebuilt from it could delete fields\n\t\t\t* outside the card. Ops name only the fields this card can see.\n\t\t\t*/\n\t\t\tconst applyOnce = async () => {\n\t\t\t\tconst ns = namespace.ns;\n\t\t\t\tconst normalizedDraft = supportsMultiKey && schema.hasPath(draft, [\"keyEntries\"]) ? schema.setPath(draft, [\"keyEntries\"], normalizedMultiKeyEntries(props.provider, keyEntries)) : draft;\n\t\t\t\tconst next = multiKey ? schema.setPath(normalizedDraft, [\"keyEntries\"], normalizedMultiKeyEntries(props.provider, keyEntries)) : layout === \"pi-ai\" && stringAt(draft, \"apiKeyEnv\") === void 0 && stringAt(fallback, \"apiKeyEnv\") === void 0 && keyValue.length > 0 ? schema.setPath(normalizedDraft, [\"apiKeyEnv\"], keyRef) : normalizedDraft;\n\t\t\t\tif (entryFailure !== void 0) return entryFailure;\n\t\t\t\tif (props.credentialOnly !== true && !multiKey) {\n\t\t\t\t\tconst failure = validateModels(schema.getPath(next, [\"models\"]));\n\t\t\t\t\t/* v8 ignore next 3 -- unreachable from the card: the same failure disables submit */\n\t\t\t\t\tif (failure !== void 0) return `${t(\"model\")} ${String(failure.index + 1)}: ${t(failure.key)}`;\n\t\t\t\t}\n\t\t\t\t/* v8 ignore next -- apply is only reachable from the rendered card, which required a resolved node */\n\t\t\t\tif (props.credentialOnly !== true && node !== void 0 && settingsPath.length === 0) {\n\t\t\t\t\tconst sectionError = schema.validate(node, next);\n\t\t\t\t\tif (sectionError !== void 0) return sectionError;\n\t\t\t\t}\n\t\t\t\tconst materializesNativeProfile = layout === \"pi-ai\" && fallback === void 0 && committedOriginal === void 0 && Object.keys(next).length === 0;\n\t\t\t\tconst ops = props.credentialOnly === true ? [] : materializesNativeProfile ? [{\n\t\t\t\t\top: \"set\",\n\t\t\t\t\tpath: [...settingsPath],\n\t\t\t\t\tvalue: {}\n\t\t\t\t}] : pathOps(settingsPath, committedOriginal, next);\n\t\t\t\tif (ops.length > 0) {\n\t\t\t\t\tconst written = await operations.writeSettings(ns, ops, expectedRevision);\n\t\t\t\t\tif (written.kind !== \"written\") return written.kind === \"conflict\" ? t(\"conflict\") : written.message;\n\t\t\t\t\tsetCommittedOriginal(schema.getPath(written.view.user, settingsPath));\n\t\t\t\t\tsetExpectedRevision(written.view.revision);\n\t\t\t\t\tsetDraft(next);\n\t\t\t\t}\n\t\t\t\tif (multiKey) return storeMultiKeyDrafts(operations, next.keyEntries, entryKeyDrafts, setEntryKeyDrafts);\n\t\t\t\tif (keyValue.length > 0) {\n\t\t\t\t\tconst stored = await operations.storeCredential(keyRef, keyValue);\n\t\t\t\t\tif (stored !== void 0) return stored;\n\t\t\t\t}\n\t\t\t\tsetKeyDraft(\"\");\n\t\t\t};\n\t\t\tconst apply = async () => {\n\t\t\t\tif (saving.current || props.readOnly || listBusy || entryFailure !== void 0) return;\n\t\t\t\tsaving.current = true;\n\t\t\t\tsetBusy(true);\n\t\t\t\tsetFailure(void 0);\n\t\t\t\ttry {\n\t\t\t\t\tconst failure = await applyOnce();\n\t\t\t\t\tif (failure !== void 0) {\n\t\t\t\t\t\tsetFailure(failure);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tprops.onClose(true);\n\t\t\t\t} catch {\n\t\t\t\t\tsetFailure(t(\"multiKeySaveFailed\"));\n\t\t\t\t} finally {\n\t\t\t\t\tsaving.current = false;\n\t\t\t\t\tsetBusy(false);\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (node === void 0) return (0, react_jsx_runtime.jsxs)(\"p\", {\n\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\tchildren: [\n\t\t\t\t\tprops.provider,\n\t\t\t\t\t\": \",\n\t\t\t\t\tprops.t(\"settingsPathUnresolvable\")\n\t\t\t\t]\n\t\t\t});\n\t\t\t/**\n\t\t\t* The catalog beneath the user layer: what the composition entry pinned, or\n\t\t\t* else the schema default that `resolve` would supply. The effective value\n\t\t\t* cannot answer this — it still carries the stored override until the unset\n\t\t\t* is applied, so reading it would echo that override straight back the\n\t\t\t* moment reset drops it, leaving the rows unchanged until a reload.\n\t\t\t*/\n\t\t\tconst inheritedModels = () => {\n\t\t\t\treturn schema.getPath(namespace.base, [...settingsPath, \"models\"]) ?? schema.nodeAtPath(root, [...settingsPath, \"models\"])?.meta.default;\n\t\t\t};\n\t\t\t/**\n\t\t\t* The curated fields of one known adapter family. The family arrives\n\t\t\t* narrowed so the per-family branches below are total: an unknown namespace\n\t\t\t* renders the hint instead and never reaches this body.\n\t\t\t*/\n\t\t\tconst curatedFields = (family) => {\n\t\t\t\tconst ownsIdentity = family === \"pi-ai\" && props.declared === true;\n\t\t\t\tconst customModels = schema.getPath(draft, [\"models\"]);\n\t\t\t\tconst modelsOverridden = schema.hasPath(draft, [\"models\"]);\n\t\t\t\tconst models = modelDrafts(modelsOverridden ? customModels : inheritedModels());\n\t\t\t\tconst defaultContextWindow = schema.getPath(fallback, [\"defaultContextWindow\"]);\n\t\t\t\tconst defaultMaxTokens = schema.getPath(fallback, [\"maxTokens\"]);\n\t\t\t\tconst defaultInput = schema.getPath(fallback, [\"defaultInput\"]);\n\t\t\t\tconst baseURL = stringAt(fallback, \"baseURL\") ?? props.defaultBaseURL;\n\t\t\t\tconst endpointEnv = props.baseURLEnv ?? [];\n\t\t\t\tconst endpointHint = family === \"deepseek\" ? t(\"deepSeekEndpointHint\") : baseURL === void 0 && endpointEnv.length > 0 ? t(\"baseUrlEnvironment\").replace(\"{env}\", () => endpointEnv.join(\", \")) : void 0;\n\t\t\t\tconst namedRef = stringAt(fallback, \"apiKeyEnv\");\n\t\t\t\tconst nativeAuth = namedRef === void 0 ? props.nativeAuth : void 0;\n\t\t\t\tconst authRefs = namedRef === void 0 ? (nativeAuth?.env ?? []).filter((ref) => !endpointEnv.includes(ref)) : [namedRef];\n\t\t\t\tconst visibleRefs = authRefs.filter((ref) => !ref.toLowerCase().includes(\"oauth\"));\n\t\t\t\tconst keyHint = visibleRefs[0];\n\t\t\t\tconst checkedRefs = authRefs.map((ref) => [ref, props.credentialChecks?.[ref] ?? (ref === namedRef ? props.credential : void 0)]);\n\t\t\t\tconst detected = checkedRefs.find(([, info]) => info?.configured === true);\n\t\t\t\tconst detectedRef = detected?.[0];\n\t\t\t\tconst detectedVisibleRef = detectedRef === void 0 || !visibleRefs.includes(detectedRef) ? void 0 : detectedRef;\n\t\t\t\tconst missingRefs = checkedRefs.length > 0 && checkedRefs.every(([, info]) => info?.configured === false);\n\t\t\t\tconst savedCredential = detected?.[1]?.source === \"file\";\n\t\t\t\tconst credentialHint = keyDraft.length > 0 || savedCredential || keyHint === void 0 || props.credentialRequired === true ? void 0 : t(detectedRef === void 0 ? missingRefs ? \"keyFallbackMissing\" : \"keyFallbackUnchecked\" : detectedVisibleRef === void 0 ? \"keyFallbackDetectedHidden\" : \"keyFallbackDetected\").replace(\"{hint}\", () => detectedVisibleRef ?? keyHint);\n\t\t\t\tconst keyHelp = visibleRefs.length === 0 ? void 0 : t(\"keyHelp\").replace(\"{env}\", () => visibleRefs.join(\" / \"));\n\t\t\t\tconst authHelp = keyHelp === void 0 ? null : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {\n\t\t\t\t\tlabel: keyHelp,\n\t\t\t\t\tside: \"right\",\n\t\t\t\t\tdelayMs: 0,\n\t\t\t\t\tfocusDelayMs: 0,\n\t\t\t\t\tportal: true,\n\t\t\t\t\topenOnClick: true,\n\t\t\t\t\tchildren: (0, react_jsx_runtime.jsx)(\"button\", {\n\t\t\t\t\t\ttype: \"button\",\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"helpButton\"],\n\t\t\t\t\t\t\"aria-label\": t(\"authHelp\"),\n\t\t\t\t\t\tchildren: \"?\"\n\t\t\t\t\t})\n\t\t\t\t});\n\t\t\t\tconst keylessNativeAuth = nativeAuth?.env.length === 0 && nativeAuth.oauth;\n\t\t\t\tconst keyPlaceholder = keyHint === void 0 || props.credentialRequired === true ? t(\"keyPlaceholder\") : t(savedCredential ? \"keyPlaceholderSaved\" : \"keyPlaceholderFallback\").replace(\"{hint}\", () => keyHint);\n\t\t\t\t/** What both family editors take: the rows, whose layer owns them, and the two writes. */\n\t\t\t\tconst catalogProps = {\n\t\t\t\t\tmodels,\n\t\t\t\t\toverridden: modelsOverridden,\n\t\t\t\t\tt,\n\t\t\t\t\tdisabled,\n\t\t\t\t\tonChange: (next) => {\n\t\t\t\t\t\tsetDraft((current) => schema.setPath(current, [\"models\"], next));\n\t\t\t\t\t},\n\t\t\t\t\tonReset: () => {\n\t\t\t\t\t\tsetDraft((current) => schema.deletePath(current, [\"models\"]));\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tconst credentials = (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [supportsMultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyToggle, {\n\t\t\t\t\tt, checked: multiKey, disabled: disabled || listBusy, hasUnsavedKeys: hasMultiKeyDrafts(entryKeyDrafts),\n\t\t\t\t\tonChange: (enabled) => {\n\t\t\t\t\t\tlet updated = schema.setPath(draft, [\"multiKey\"], enabled);\n\t\t\t\t\t\tif (enabled && Object.keys(keyEntries).length === 0) {\n\t\t\t\t\t\t\tconst namedRef = stringAt(draft, \"apiKeyEnv\") ?? stringAt(fallback, \"apiKeyEnv\");\n\t\t\t\t\t\t\tconst [id, entry] = newMultiKeyEntry(props.provider, {\n\t\t\t\t\t\t\t\tname: stringAt(draft, \"displayName\") ?? stringAt(fallback, \"displayName\") ?? props.displayName ?? props.provider,\n\t\t\t\t\t\t\t\tapiKeyEnv: namedRef,\n\t\t\t\t\t\t\t\tmodels: draft.models ?? fallback?.models ?? inheritedModels()\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (keyDraft.length > 0) {\n\t\t\t\t\t\t\t\tsetEntryKeyDrafts({ [id]: keyDraft });\n\t\t\t\t\t\t\t\tif (namedRef === void 0) updated = schema.setPath(updated, [\"apiKeyEnv\"], multiKeyRef(props.provider, id));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tupdated = schema.setPath(updated, [\"keyEntries\"], { [id]: entry });\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsetDraft(updated);\n\t\t\t\t\t}\n\t\t\t\t}) : null, multiKey ? (0, react_jsx_runtime.jsx)(MultiKeyEntriesEditor, {\n\t\t\t\t\troute: props.provider, entries: keyEntries,\n\t\t\t\t\tonChange: (entries) => setDraft((current) => schema.setPath(current, [\"keyEntries\"], entries)),\n\t\t\t\t\tkeyDrafts: entryKeyDrafts, onKeyDraftsChange: setEntryKeyDrafts,\n\t\t\t\t\tconfirmations: entryConfirmations, onConfirmationsChange: setEntryConfirmations,\n\t\t\t\t\tpersistedEntries: schema.getPath(committedOriginal, [\"keyEntries\"]) ?? fallback?.keyEntries ?? {},\n\t\t\t\t\tcredentialChecks: props.credentialChecks,\n\t\t\t\t\tprobe: { settingsNs: namespace.ns, provider: props.provider, ...(probeBaseURL === void 0 ? {} : { baseURL: probeBaseURL }), ...(probeApi === void 0 ? {} : { api: probeApi }) },\n\t\t\t\t\treasoningLevels, operations, t, disabled: disabled || listBusy, onBusyChange: setListBusy\n\t\t\t\t}) : null, multiKey || keylessNativeAuth ? null : (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: [t(\"keyInput\"), authHelp]\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ApiKeyInput, {\n\t\t\t\t\t\t\tt,\n\t\t\t\t\t\t\tvalue: keyDraft,\n\t\t\t\t\t\t\tplaceholder: keyPlaceholder,\n\t\t\t\t\t\t\t\"aria-label\": t(\"keyInput\"),\n\t\t\t\t\t\t\t\"aria-invalid\": shownKeyFailure !== void 0,\n\t\t\t\t\t\t\t\"aria-describedby\": credentialHint === void 0 ? void 0 : `${props.provider}-credential-hint`,\n\t\t\t\t\t\t\trequired: props.credentialRequired === true,\n\t\t\t\t\t\t\tautoFocus: props.autoFocusCredential === true,\n\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetKeyDraft(event.target.value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tcredentialHint === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\t\tid: `${props.provider}-credential-hint`,\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[missingRefs ? \"notice\" : detectedRef === void 0 ? \"advancedHint\" : \"savedNotice\"],\n\t\t\t\t\t\t\tchildren: credentialHint\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tshownKeyFailure === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\t\tchildren: t(shownKeyFailure)\n\t\t\t\t\t\t})\n\t\t\t\t\t]\n\t\t\t\t})] });\n\t\t\t\tconst customization = props.credentialOnly === true ? null : (0, react_jsx_runtime.jsxs)(\"details\", {\n\t\t\t\t\tclassName: ModelsSection_module_css_default[\"customized\"],\n\t\t\t\t\topen: supportsMultiKey ? true : void 0,\n\t\t\t\t\t\"data-multi-key-shared-settings\": supportsMultiKey ? true : void 0,\n\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"summary\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"customizedSummary\"],\n\t\t\t\t\t\tchildren: t(supportsMultiKey ? \"multiKeySharedSettings\" : \"customized\")\n\t\t\t\t\t}), (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"customizedBody\"],\n\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\townsIdentity ? (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\t\tchildren: t(\"customDisplayName\")\n\t\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\tvalue: stringAt(draft, \"displayName\") ?? \"\",\n\t\t\t\t\t\t\t\t\tplaceholder: stringAt(schema.getPath(namespace.base, settingsPath), \"displayName\") ?? props.provider,\n\t\t\t\t\t\t\t\t\t\"aria-label\": t(\"customDisplayName\"),\n\t\t\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\tsetField(\"displayName\", event.target.value);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t}) : null,\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\t\t\tchildren: t(\"baseUrl\")\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\t\tvalue: stringAt(draft, \"baseURL\") ?? \"\",\n\t\t\t\t\t\t\t\t\t\tplaceholder: family === \"deepseek\" ? t(\"deepSeekBaseUrl\") : baseURL === void 0 ? t(endpointEnv.length > 0 ? \"baseUrlConfigured\" : \"baseUrlDefault\") : t(\"baseUrlPlaceholder\").replace(\"{url}\", () => baseURL),\n\t\t\t\t\t\t\t\t\t\t\"aria-describedby\": endpointHint === void 0 ? void 0 : `${props.provider}-endpoint-hint`,\n\t\t\t\t\t\t\t\t\t\t\"aria-label\": t(\"baseUrl\"),\n\t\t\t\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\t\tsetField(\"baseURL\", event.target.value === \"\" ? void 0 : event.target.value);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\tendpointHint === void 0 ? null : (0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\t\t\tid: `${props.provider}-endpoint-hint`,\n\t\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\t\t\t\t\tchildren: endpointHint\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\townsIdentity ? (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\t\tchildren: t(\"customApi\")\n\t\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsxs)(\"select\", {\n\t\t\t\t\t\t\t\t\tclassName: `${ModelsSection_module_css_default[\"input\"]} ${ModelsSection_module_css_default[\"selectInput\"]}`,\n\t\t\t\t\t\t\t\t\tvalue: probeApi ?? \"\",\n\t\t\t\t\t\t\t\t\t\"aria-label\": t(\"customApi\"),\n\t\t\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\tsetField(\"api\", event.target.value);\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tchildren: [probeApi === void 0 ? (0, react_jsx_runtime.jsx)(\"option\", {\n\t\t\t\t\t\t\t\t\t\tvalue: \"\",\n\t\t\t\t\t\t\t\t\t\tchildren: t(\"customApiUnset\")\n\t\t\t\t\t\t\t\t\t}) : null, protocols.map((choice) => (0, react_jsx_runtime.jsx)(\"option\", {\n\t\t\t\t\t\t\t\t\t\tvalue: choice,\n\t\t\t\t\t\t\t\t\t\tchildren: protocolLabel(t, choice)\n\t\t\t\t\t\t\t\t\t}, choice))]\n\t\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t}) : null,\n\t\t\t\t\t\t\tmultiKey ? null : family === \"deepseek\" ? (0, react_jsx_runtime.jsx)(DeepSeekModelsEditor, {\n\t\t\t\t\t\t\t\t...catalogProps,\n\t\t\t\t\t\t\t\tdefaultContextWindow: typeof defaultContextWindow === \"number\" ? defaultContextWindow : void 0,\n\t\t\t\t\t\t\t\tdefaultMaxTokens: typeof defaultMaxTokens === \"number\" ? defaultMaxTokens : void 0\n\t\t\t\t\t\t\t}) : (0, react_jsx_runtime.jsx)(ModelListEditor, {\n\t\t\t\t\t\t\t\t...catalogProps,\n\t\t\t\t\t\t\t\tcatalogProvider: props.declared === true ? void 0 : props.provider,\n\t\t\t\t\t\t\t\treasoningLevels,\n\t\t\t\t\t\t\t\tdefaultInput: Array.isArray(defaultInput) ? defaultInput : void 0,\n\t\t\t\t\t\t\t\tprobe,\n\t\t\t\t\t\t\t\tprobeBlocked: keyFailure,\n\t\t\t\t\t\t\t\toperations,\n\t\t\t\t\t\t\t\tonBusyChange: setListBusy\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t]\n\t\t\t\t\t})]\n\t\t\t\t});\n\t\t\t\treturn (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: supportsMultiKey ? [customization, credentials] : [credentials, customization] });\n\t\t\t};\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\tclassName: props.credentialOnly === true ? ModelsSection_module_css_default[\"addBlock\"] : ModelsSection_module_css_default[\"editor\"],\n\t\t\t\tchildren: [\n\t\t\t\t\tprops.hideTitle === true ? null : (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"editorHeader\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"editorTitle\"],\n\t\t\t\t\t\t\tchildren: props.displayName\n\t\t\t\t\t\t}), props.provider !== props.displayName ? (0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"editorRoute\"],\n\t\t\t\t\t\t\tchildren: props.provider\n\t\t\t\t\t\t}) : null]\n\t\t\t\t\t}),\n\t\t\t\t\tlayout === \"unknown\" ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\tchildren: `${t(\"advancedHint\")} (${namespace.ns})`\n\t\t\t\t\t}) : curatedFields(layout),\n\t\t\t\t\t(failure ?? entryFailure) !== void 0 ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: failure ?? entryFailure\n\t\t\t\t\t}) : null,\n\t\t\t\t\tprops.credentialOnly === true || modelFailure === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\tchildren: `${t(\"model\")} ${String(modelFailure.index + 1)}: ${t(modelFailure.key)}`\n\t\t\t\t\t}),\n\t\t\t\t\t(0, react_jsx_runtime.jsx)(EditorFooter, {\n\t\t\t\t\t\tt,\n\t\t\t\t\t\tbusy,\n\t\t\t\t\t\tsubmitDisabled: disabled || listBusy || layout === \"unknown\" || entryFailure !== void 0 || props.credentialOnly !== true && modelFailure !== void 0 || !multiKey && (shownKeyFailure !== void 0 || props.credentialRequired === true && keyValue.length === 0),\n\t\t\t\t\t\tsubmitLabelKey: props.submitLabelKey ?? \"apply\",\n\t\t\t\t\t\tsubmitBusyLabelKey: props.submitBusyLabelKey ?? \"applying\",\n\t\t\t\t\t\t...props.cancelLabelKey === void 0 ? {} : { cancelLabelKey: props.cancelLabelKey },\n\t\t\t\t\t\tonCancel: () => {\n\t\t\t\t\t\t\tprops.onClose(false);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonSubmit: () => {\n\t\t\t\t\t\t\tprops.onSubmitCredential?.();\n\t\t\t\t\t\t\tapply();\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t]\n\t\t\t});\n\t\t}",
|
|
1027
|
+
"after": "function ProviderEditor(props) {\n\t\t\tconst { namespace, schema, settingsPath, operations, t } = props;\n\t\t\tconst [draft, setDraft] = (0, react.useState)(() => draftAt(schema, namespace, settingsPath));\n\t\t\tconst [entryKeyDrafts, setEntryKeyDrafts] = (0, react.useState)({});\n\t\t\tconst [entryConfirmations, setEntryConfirmations] = (0, react.useState)({});\n\t\t\tconst [entrySaveState, setEntrySaveState] = (0, react.useState)(void 0);\n\t\t\tconst saving = (0, react.useRef)(false);\n\t\t\tconst [keyDraft, setKeyDraft] = (0, react.useState)(\"\");\n\t\t\tconst [busy, setBusy] = (0, react.useState)(false);\n\t\t\tconst [listBusy, setListBusy] = (0, react.useState)(false);\n\t\t\tconst { onBusyChange } = props;\n\t\t\t(0, react.useEffect)(() => {\n\t\t\t\tonBusyChange?.(busy || listBusy);\n\t\t\t}, [\n\t\t\t\tbusy,\n\t\t\t\tlistBusy,\n\t\t\t\tonBusyChange\n\t\t\t]);\n\t\t\tconst [failure, setFailure] = (0, react.useState)(void 0);\n\t\t\tconst [committedOriginal, setCommittedOriginal] = (0, react.useState)(() => schema.getPath(namespace.user, settingsPath));\n\t\t\tconst [expectedRevision, setExpectedRevision] = (0, react.useState)(() => namespace.revision);\n\t\t\tconst root = (0, react.useMemo)(() => schema.rehydrate(namespace.schema), [namespace.schema, schema]);\n\t\t\tconst node = (0, react.useMemo)(() => schema.nodeAtPath(root, settingsPath), [\n\t\t\t\troot,\n\t\t\t\tschema,\n\t\t\t\tsettingsPath\n\t\t\t]);\n\t\t\tconst fallback = schema.getPath(namespace.value, settingsPath);\n\t\t\tconst disabled = props.readOnly || busy;\n\t\t\tconst layout = layoutOf(namespace.ns);\n\t\t\tconst keyRef = refFor(schema, namespace, settingsPath, props.provider);\n\t\t\tconst supportsMultiKey = layout === \"pi-ai\" && props.declared === true && props.credentialOnly !== true && supportsMultiKeySchema(namespace, schema, settingsPath);\n\t\t\tconst multiKey = supportsMultiKey && (draft.multiKey ?? fallback?.multiKey) === true;\n\t\t\tconst keyEntries = draft.keyEntries ?? fallback?.keyEntries ?? {};\n\t\t\tconst entryFailure = multiKey ? multiKeyFailure(props.provider, keyEntries, entryKeyDrafts, entryConfirmations, t) : void 0;\n\t\t\tconst protocols = (0, react.useMemo)(() => layout === \"pi-ai\" ? protocolChoices(namespace, schema) : [], [\n\t\t\t\tlayout,\n\t\t\t\tnamespace,\n\t\t\t\tschema\n\t\t\t]);\n\t\t\tconst stringAt = (source, key) => {\n\t\t\t\tconst value = schema.getPath(source, [key]);\n\t\t\t\treturn typeof value === \"string\" && value.trim().length > 0 ? value : void 0;\n\t\t\t};\n\t\t\tconst setField = (key, next) => {\n\t\t\t\tconst value = next === void 0 || next.trim().length === 0 ? void 0 : next;\n\t\t\t\tsetDraft((current) => value === void 0 ? schema.deletePath(current, [key]) : schema.setPath(current, [key], value));\n\t\t\t};\n\t\t\tconst reasoningLevels = (0, react.useMemo)(() => layout === \"pi-ai\" && props.declared === true ? reasoningLevelChoices(namespace, schema) : [], [\n\t\t\t\tlayout,\n\t\t\t\tprops.declared,\n\t\t\t\tnamespace,\n\t\t\t\tschema\n\t\t\t]);\n\t\t\tconst editsReasoning = reasoningLevels.length > 0;\n\t\t\tconst validateModels = (value) => validateDeepSeekModels(value) ?? (editsReasoning ? validateReasoningEfforts(value) : void 0);\n\t\t\tconst modelFailure = multiKey ? void 0 : validateModels(schema.getPath(draft, [\"models\"]));\n\t\t\tconst keyFailure = multiKey ? void 0 : apiKeyFailure(keyDraft);\n\t\t\tconst keyValue = keyDraft.trim();\n\t\t\tconst shownKeyFailure = (props.credentialRequired === true && keyDraft.length > 0 && keyValue.length === 0 ? \"keyRequired\" : void 0) ?? keyFailure;\n\t\t\tconst probeApi = stringAt(draft, \"api\") ?? stringAt(fallback, \"api\");\n\t\t\tconst probeBaseURL = stringAt(draft, \"baseURL\") ?? stringAt(fallback, \"baseURL\");\n\t\t\tconst probe = {\n\t\t\t\tsettingsNs: namespace.ns,\n\t\t\t\tprovider: props.provider,\n\t\t\t\t...probeBaseURL === void 0 ? {} : { baseURL: probeBaseURL },\n\t\t\t\t...probeApi === void 0 ? {} : { api: probeApi },\n\t\t\t\t...keyValue.length === 0 ? {} : { apiKey: keyValue }\n\t\t\t};\n\t\t\t/**\n\t\t\t* The write for this card, or a failure message. Every edit travels as\n\t\t\t* path ops against the STORED section: the draft comes from the redacted\n\t\t\t* descriptor, so a wholesale replace rebuilt from it could delete fields\n\t\t\t* outside the card. Ops name only the fields this card can see.\n\t\t\t*/\n\t\t\tconst applyOnce = async () => {\n\t\t\t\tconst ns = namespace.ns;\n\t\t\t\tconst normalizedDraft = supportsMultiKey && schema.hasPath(draft, [\"keyEntries\"]) ? schema.setPath(draft, [\"keyEntries\"], normalizedMultiKeyEntries(props.provider, keyEntries)) : draft;\n\t\t\t\tconst next = multiKey ? schema.setPath(normalizedDraft, [\"keyEntries\"], normalizedMultiKeyEntries(props.provider, keyEntries)) : layout === \"pi-ai\" && stringAt(draft, \"apiKeyEnv\") === void 0 && stringAt(fallback, \"apiKeyEnv\") === void 0 && keyValue.length > 0 ? schema.setPath(normalizedDraft, [\"apiKeyEnv\"], keyRef) : normalizedDraft;\n\t\t\t\tif (entryFailure !== void 0) return entryFailure;\n\t\t\t\tif (props.credentialOnly !== true && !multiKey) {\n\t\t\t\t\tconst failure = validateModels(schema.getPath(next, [\"models\"]));\n\t\t\t\t\t/* v8 ignore next 3 -- unreachable from the card: the same failure disables submit */\n\t\t\t\t\tif (failure !== void 0) return `${t(\"model\")} ${String(failure.index + 1)}: ${t(failure.key)}`;\n\t\t\t\t}\n\t\t\t\t/* v8 ignore next -- apply is only reachable from the rendered card, which required a resolved node */\n\t\t\t\tif (props.credentialOnly !== true && node !== void 0 && settingsPath.length === 0) {\n\t\t\t\t\tconst sectionError = schema.validate(node, next);\n\t\t\t\t\tif (sectionError !== void 0) return sectionError;\n\t\t\t\t}\n\t\t\t\tconst materializesNativeProfile = layout === \"pi-ai\" && fallback === void 0 && committedOriginal === void 0 && Object.keys(next).length === 0;\n\t\t\t\tconst ops = props.credentialOnly === true ? [] : materializesNativeProfile ? [{\n\t\t\t\t\top: \"set\",\n\t\t\t\t\tpath: [...settingsPath],\n\t\t\t\t\tvalue: {}\n\t\t\t\t}] : pathOps(settingsPath, committedOriginal, next);\n\t\t\t\tif (ops.length > 0) {\n\t\t\t\t\tconst written = await operations.writeSettings(ns, ops, expectedRevision);\n\t\t\t\t\tif (written.kind !== \"written\") return written.kind === \"conflict\" ? t(\"conflict\") : written.message;\n\t\t\t\t\tsetCommittedOriginal(schema.getPath(written.view.user, settingsPath));\n\t\t\t\t\tsetExpectedRevision(written.view.revision);\n\t\t\t\t\tsetDraft(next);\n\t\t\t\t}\n\t\t\t\tif (multiKey) return storeMultiKeyDrafts(operations, next.keyEntries, entryKeyDrafts, setEntryKeyDrafts);\n\t\t\t\tif (keyValue.length > 0) {\n\t\t\t\t\tconst stored = await operations.storeCredential(keyRef, keyValue);\n\t\t\t\t\tif (stored !== void 0) return stored;\n\t\t\t\t}\n\t\t\t\tsetKeyDraft(\"\");\n\t\t\t};\n\t\t\tconst apply = async () => {\n\t\t\t\tif (saving.current || props.readOnly || listBusy || entryFailure !== void 0) return;\n\t\t\t\tsaving.current = true;\n\t\t\t\tsetBusy(true);\n\t\t\t\tsetFailure(void 0);\n\t\t\t\ttry {\n\t\t\t\t\tconst failure = await applyOnce();\n\t\t\t\t\tif (multiKey) setEntrySaveState({ ok: failure === void 0, entries: structuredClone(failure === void 0 ? normalizedMultiKeyEntries(props.provider, keyEntries) : keyEntries) });\n\t\t\t\t\tif (failure !== void 0) {\n\t\t\t\t\t\tsetFailure(failure);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (!multiKey) props.onClose(true);\n\t\t\t\t} catch {\n\t\t\t\t\tif (multiKey) setEntrySaveState({ ok: false, entries: structuredClone(keyEntries) });\n\t\t\t\t\tsetFailure(t(\"multiKeySaveFailed\"));\n\t\t\t\t} finally {\n\t\t\t\t\tsaving.current = false;\n\t\t\t\t\tsetBusy(false);\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (node === void 0) return (0, react_jsx_runtime.jsxs)(\"p\", {\n\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\tchildren: [\n\t\t\t\t\tprops.provider,\n\t\t\t\t\t\": \",\n\t\t\t\t\tprops.t(\"settingsPathUnresolvable\")\n\t\t\t\t]\n\t\t\t});\n\t\t\t/**\n\t\t\t* The catalog beneath the user layer: what the composition entry pinned, or\n\t\t\t* else the schema default that `resolve` would supply. The effective value\n\t\t\t* cannot answer this — it still carries the stored override until the unset\n\t\t\t* is applied, so reading it would echo that override straight back the\n\t\t\t* moment reset drops it, leaving the rows unchanged until a reload.\n\t\t\t*/\n\t\t\tconst inheritedModels = () => {\n\t\t\t\treturn schema.getPath(namespace.base, [...settingsPath, \"models\"]) ?? schema.nodeAtPath(root, [...settingsPath, \"models\"])?.meta.default;\n\t\t\t};\n\t\t\t/**\n\t\t\t* The curated fields of one known adapter family. The family arrives\n\t\t\t* narrowed so the per-family branches below are total: an unknown namespace\n\t\t\t* renders the hint instead and never reaches this body.\n\t\t\t*/\n\t\t\tconst curatedFields = (family) => {\n\t\t\t\tconst ownsIdentity = family === \"pi-ai\" && props.declared === true;\n\t\t\t\tconst customModels = schema.getPath(draft, [\"models\"]);\n\t\t\t\tconst modelsOverridden = schema.hasPath(draft, [\"models\"]);\n\t\t\t\tconst models = modelDrafts(modelsOverridden ? customModels : inheritedModels());\n\t\t\t\tconst defaultContextWindow = schema.getPath(fallback, [\"defaultContextWindow\"]);\n\t\t\t\tconst defaultMaxTokens = schema.getPath(fallback, [\"maxTokens\"]);\n\t\t\t\tconst defaultInput = schema.getPath(fallback, [\"defaultInput\"]);\n\t\t\t\tconst baseURL = stringAt(fallback, \"baseURL\") ?? props.defaultBaseURL;\n\t\t\t\tconst endpointEnv = props.baseURLEnv ?? [];\n\t\t\t\tconst endpointHint = family === \"deepseek\" ? t(\"deepSeekEndpointHint\") : baseURL === void 0 && endpointEnv.length > 0 ? t(\"baseUrlEnvironment\").replace(\"{env}\", () => endpointEnv.join(\", \")) : void 0;\n\t\t\t\tconst namedRef = stringAt(fallback, \"apiKeyEnv\");\n\t\t\t\tconst nativeAuth = namedRef === void 0 ? props.nativeAuth : void 0;\n\t\t\t\tconst authRefs = namedRef === void 0 ? (nativeAuth?.env ?? []).filter((ref) => !endpointEnv.includes(ref)) : [namedRef];\n\t\t\t\tconst visibleRefs = authRefs.filter((ref) => !ref.toLowerCase().includes(\"oauth\"));\n\t\t\t\tconst keyHint = visibleRefs[0];\n\t\t\t\tconst checkedRefs = authRefs.map((ref) => [ref, props.credentialChecks?.[ref] ?? (ref === namedRef ? props.credential : void 0)]);\n\t\t\t\tconst detected = checkedRefs.find(([, info]) => info?.configured === true);\n\t\t\t\tconst detectedRef = detected?.[0];\n\t\t\t\tconst detectedVisibleRef = detectedRef === void 0 || !visibleRefs.includes(detectedRef) ? void 0 : detectedRef;\n\t\t\t\tconst missingRefs = checkedRefs.length > 0 && checkedRefs.every(([, info]) => info?.configured === false);\n\t\t\t\tconst savedCredential = detected?.[1]?.source === \"file\";\n\t\t\t\tconst credentialHint = keyDraft.length > 0 || savedCredential || keyHint === void 0 || props.credentialRequired === true ? void 0 : t(detectedRef === void 0 ? missingRefs ? \"keyFallbackMissing\" : \"keyFallbackUnchecked\" : detectedVisibleRef === void 0 ? \"keyFallbackDetectedHidden\" : \"keyFallbackDetected\").replace(\"{hint}\", () => detectedVisibleRef ?? keyHint);\n\t\t\t\tconst keyHelp = visibleRefs.length === 0 ? void 0 : t(\"keyHelp\").replace(\"{env}\", () => visibleRefs.join(\" / \"));\n\t\t\t\tconst authHelp = keyHelp === void 0 ? null : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {\n\t\t\t\t\tlabel: keyHelp,\n\t\t\t\t\tside: \"right\",\n\t\t\t\t\tdelayMs: 0,\n\t\t\t\t\tfocusDelayMs: 0,\n\t\t\t\t\tportal: true,\n\t\t\t\t\topenOnClick: true,\n\t\t\t\t\tchildren: (0, react_jsx_runtime.jsx)(\"button\", {\n\t\t\t\t\t\ttype: \"button\",\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"helpButton\"],\n\t\t\t\t\t\t\"aria-label\": t(\"authHelp\"),\n\t\t\t\t\t\tchildren: \"?\"\n\t\t\t\t\t})\n\t\t\t\t});\n\t\t\t\tconst keylessNativeAuth = nativeAuth?.env.length === 0 && nativeAuth.oauth;\n\t\t\t\tconst keyPlaceholder = keyHint === void 0 || props.credentialRequired === true ? t(\"keyPlaceholder\") : t(savedCredential ? \"keyPlaceholderSaved\" : \"keyPlaceholderFallback\").replace(\"{hint}\", () => keyHint);\n\t\t\t\t/** What both family editors take: the rows, whose layer owns them, and the two writes. */\n\t\t\t\tconst catalogProps = {\n\t\t\t\t\tmodels,\n\t\t\t\t\toverridden: modelsOverridden,\n\t\t\t\t\tt,\n\t\t\t\t\tdisabled,\n\t\t\t\t\tonChange: (next) => {\n\t\t\t\t\t\tsetDraft((current) => schema.setPath(current, [\"models\"], next));\n\t\t\t\t\t},\n\t\t\t\t\tonReset: () => {\n\t\t\t\t\t\tsetDraft((current) => schema.deletePath(current, [\"models\"]));\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tconst credentials = (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [supportsMultiKey ? (0, react_jsx_runtime.jsx)(MultiKeyToggle, {\n\t\t\t\t\tt, checked: multiKey, disabled: disabled || listBusy, hasUnsavedKeys: hasMultiKeyDrafts(entryKeyDrafts),\n\t\t\t\t\tonChange: (enabled) => {\n\t\t\t\t\t\tlet updated = schema.setPath(draft, [\"multiKey\"], enabled);\n\t\t\t\t\t\tif (enabled && Object.keys(keyEntries).length === 0) {\n\t\t\t\t\t\t\tconst namedRef = stringAt(draft, \"apiKeyEnv\") ?? stringAt(fallback, \"apiKeyEnv\");\n\t\t\t\t\t\t\tconst [id, entry] = newMultiKeyEntry(props.provider, {\n\t\t\t\t\t\t\t\tname: stringAt(draft, \"displayName\") ?? stringAt(fallback, \"displayName\") ?? props.displayName ?? props.provider,\n\t\t\t\t\t\t\t\tapiKeyEnv: namedRef,\n\t\t\t\t\t\t\t\tmodels: draft.models ?? fallback?.models ?? inheritedModels()\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (keyDraft.length > 0) {\n\t\t\t\t\t\t\t\tsetEntryKeyDrafts({ [id]: keyDraft });\n\t\t\t\t\t\t\t\tif (namedRef === void 0) updated = schema.setPath(updated, [\"apiKeyEnv\"], multiKeyRef(props.provider, id));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tupdated = schema.setPath(updated, [\"keyEntries\"], { [id]: entry });\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsetDraft(updated);\n\t\t\t\t\t}\n\t\t\t\t}) : null, multiKey ? (0, react_jsx_runtime.jsx)(MultiKeyEntriesEditor, {\n\t\t\t\t\troute: props.provider, entries: keyEntries, protocols, saveState: entrySaveState, savedEntries: entrySaveState?.ok ? entrySaveState.entries : void 0,\n\t\t\t\t\tonChange: (entries) => setDraft((current) => schema.setPath(current, [\"keyEntries\"], entries)),\n\t\t\t\t\tkeyDrafts: entryKeyDrafts, onKeyDraftsChange: setEntryKeyDrafts,\n\t\t\t\t\tconfirmations: entryConfirmations, onConfirmationsChange: setEntryConfirmations,\n\t\t\t\t\tpersistedEntries: schema.getPath(committedOriginal, [\"keyEntries\"]) ?? fallback?.keyEntries ?? {},\n\t\t\t\t\tcredentialChecks: props.credentialChecks,\n\t\t\t\t\tprobe: { settingsNs: namespace.ns, provider: props.provider, ...(probeBaseURL === void 0 ? {} : { baseURL: probeBaseURL }), ...(probeApi === void 0 ? {} : { api: probeApi }) },\n\t\t\t\t\treasoningLevels, operations, t, disabled: disabled || listBusy, onBusyChange: setListBusy\n\t\t\t\t}) : null, multiKey || keylessNativeAuth ? null : (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\tchildren: [t(\"keyInput\"), authHelp]\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(ApiKeyInput, {\n\t\t\t\t\t\t\tt,\n\t\t\t\t\t\t\tvalue: keyDraft,\n\t\t\t\t\t\t\tplaceholder: keyPlaceholder,\n\t\t\t\t\t\t\t\"aria-label\": t(\"keyInput\"),\n\t\t\t\t\t\t\t\"aria-invalid\": shownKeyFailure !== void 0,\n\t\t\t\t\t\t\t\"aria-describedby\": credentialHint === void 0 ? void 0 : `${props.provider}-credential-hint`,\n\t\t\t\t\t\t\trequired: props.credentialRequired === true,\n\t\t\t\t\t\t\tautoFocus: props.autoFocusCredential === true,\n\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\tsetKeyDraft(event.target.value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tcredentialHint === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\t\tid: `${props.provider}-credential-hint`,\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[missingRefs ? \"notice\" : detectedRef === void 0 ? \"advancedHint\" : \"savedNotice\"],\n\t\t\t\t\t\t\tchildren: credentialHint\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tshownKeyFailure === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\t\tchildren: t(shownKeyFailure)\n\t\t\t\t\t\t})\n\t\t\t\t\t]\n\t\t\t\t})] });\n\t\t\t\tconst customization = props.credentialOnly === true ? null : (0, react_jsx_runtime.jsxs)(\"details\", {\n\t\t\t\t\tclassName: ModelsSection_module_css_default[\"customized\"],\n\t\t\t\t\topen: supportsMultiKey ? true : void 0,\n\t\t\t\t\t\"data-multi-key-shared-settings\": supportsMultiKey ? true : void 0,\n\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"summary\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"customizedSummary\"],\n\t\t\t\t\t\tchildren: t(supportsMultiKey ? \"multiKeySharedSettings\" : \"customized\")\n\t\t\t\t\t}), (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"customizedBody\"],\n\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\townsIdentity ? (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\t\tchildren: t(\"customDisplayName\")\n\t\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\tvalue: stringAt(draft, \"displayName\") ?? \"\",\n\t\t\t\t\t\t\t\t\tplaceholder: stringAt(schema.getPath(namespace.base, settingsPath), \"displayName\") ?? props.provider,\n\t\t\t\t\t\t\t\t\t\"aria-label\": t(\"customDisplayName\"),\n\t\t\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\tsetField(\"displayName\", event.target.value);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t}) : null,\n\t\t\t\t\t\t\t(0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\t\t\tchildren: t(\"baseUrl\")\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t(0, react_jsx_runtime.jsx)(\"input\", {\n\t\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"input\"],\n\t\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\t\tvalue: stringAt(draft, \"baseURL\") ?? \"\",\n\t\t\t\t\t\t\t\t\t\tplaceholder: family === \"deepseek\" ? t(\"deepSeekBaseUrl\") : baseURL === void 0 ? t(endpointEnv.length > 0 ? \"baseUrlConfigured\" : \"baseUrlDefault\") : t(\"baseUrlPlaceholder\").replace(\"{url}\", () => baseURL),\n\t\t\t\t\t\t\t\t\t\t\"aria-describedby\": endpointHint === void 0 ? void 0 : `${props.provider}-endpoint-hint`,\n\t\t\t\t\t\t\t\t\t\t\"aria-label\": t(\"baseUrl\"),\n\t\t\t\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\t\tsetField(\"baseURL\", event.target.value === \"\" ? void 0 : event.target.value);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\tendpointHint === void 0 ? null : (0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\t\t\tid: `${props.provider}-endpoint-hint`,\n\t\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\t\t\t\t\tchildren: endpointHint\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\townsIdentity ? (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"field\"],\n\t\t\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"fieldLabel\"],\n\t\t\t\t\t\t\t\t\tchildren: t(\"customApi\")\n\t\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsxs)(\"select\", {\n\t\t\t\t\t\t\t\t\tclassName: `${ModelsSection_module_css_default[\"input\"]} ${ModelsSection_module_css_default[\"selectInput\"]}`,\n\t\t\t\t\t\t\t\t\tvalue: probeApi ?? \"\",\n\t\t\t\t\t\t\t\t\t\"aria-label\": t(\"customApi\"),\n\t\t\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t\t\t\tonChange: (event) => {\n\t\t\t\t\t\t\t\t\t\tsetField(\"api\", event.target.value);\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tchildren: [probeApi === void 0 ? (0, react_jsx_runtime.jsx)(\"option\", {\n\t\t\t\t\t\t\t\t\t\tvalue: \"\",\n\t\t\t\t\t\t\t\t\t\tchildren: t(\"customApiUnset\")\n\t\t\t\t\t\t\t\t\t}) : null, protocols.map((choice) => (0, react_jsx_runtime.jsx)(\"option\", {\n\t\t\t\t\t\t\t\t\t\tvalue: choice,\n\t\t\t\t\t\t\t\t\t\tchildren: protocolLabel(t, choice)\n\t\t\t\t\t\t\t\t\t}, choice))]\n\t\t\t\t\t\t\t\t})]\n\t\t\t\t\t\t\t}) : null,\n\t\t\t\t\t\t\tmultiKey ? null : family === \"deepseek\" ? (0, react_jsx_runtime.jsx)(DeepSeekModelsEditor, {\n\t\t\t\t\t\t\t\t...catalogProps,\n\t\t\t\t\t\t\t\tdefaultContextWindow: typeof defaultContextWindow === \"number\" ? defaultContextWindow : void 0,\n\t\t\t\t\t\t\t\tdefaultMaxTokens: typeof defaultMaxTokens === \"number\" ? defaultMaxTokens : void 0\n\t\t\t\t\t\t\t}) : (0, react_jsx_runtime.jsx)(ModelListEditor, {\n\t\t\t\t\t\t\t\t...catalogProps,\n\t\t\t\t\t\t\t\tcatalogProvider: props.declared === true ? void 0 : props.provider,\n\t\t\t\t\t\t\t\treasoningLevels,\n\t\t\t\t\t\t\t\tdefaultInput: Array.isArray(defaultInput) ? defaultInput : void 0,\n\t\t\t\t\t\t\t\tprobe,\n\t\t\t\t\t\t\t\tprobeBlocked: keyFailure,\n\t\t\t\t\t\t\t\toperations,\n\t\t\t\t\t\t\t\tonBusyChange: setListBusy\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t]\n\t\t\t\t\t})]\n\t\t\t\t});\n\t\t\t\treturn (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: supportsMultiKey ? [customization, credentials] : [credentials, customization] });\n\t\t\t};\n\t\t\treturn (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\tclassName: props.credentialOnly === true ? ModelsSection_module_css_default[\"addBlock\"] : ModelsSection_module_css_default[\"editor\"],\n\t\t\t\tchildren: [\n\t\t\t\t\tprops.hideTitle === true ? null : (0, react_jsx_runtime.jsxs)(\"div\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"editorHeader\"],\n\t\t\t\t\t\tchildren: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"editorTitle\"],\n\t\t\t\t\t\t\tchildren: props.displayName\n\t\t\t\t\t\t}), props.provider !== props.displayName ? (0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"editorRoute\"],\n\t\t\t\t\t\t\tchildren: props.provider\n\t\t\t\t\t\t}) : null]\n\t\t\t\t\t}),\n\t\t\t\t\tlayout === \"unknown\" ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\tchildren: `${t(\"advancedHint\")} (${namespace.ns})`\n\t\t\t\t\t}) : curatedFields(layout),\n\t\t\t\t\t(failure ?? entryFailure) !== void 0 ? (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"error\"],\n\t\t\t\t\t\tchildren: failure ?? entryFailure\n\t\t\t\t\t}) : null,\n\t\t\t\t\tprops.credentialOnly === true || modelFailure === void 0 ? null : (0, react_jsx_runtime.jsx)(\"p\", {\n\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"advancedHint\"],\n\t\t\t\t\t\tchildren: `${t(\"model\")} ${String(modelFailure.index + 1)}: ${t(modelFailure.key)}`\n\t\t\t\t\t}),\n\t\t\t\t\t(0, react_jsx_runtime.jsx)(EditorFooter, {\n\t\t\t\t\t\tt,\n\t\t\t\t\t\tbusy,\n\t\t\t\t\t\tsubmitDisabled: disabled || listBusy || layout === \"unknown\" || entryFailure !== void 0 || props.credentialOnly !== true && modelFailure !== void 0 || !multiKey && (shownKeyFailure !== void 0 || props.credentialRequired === true && keyValue.length === 0),\n\t\t\t\t\t\tsubmitLabelKey: props.submitLabelKey ?? \"apply\",\n\t\t\t\t\t\tsubmitBusyLabelKey: props.submitBusyLabelKey ?? \"applying\",\n\t\t\t\t\t\t...props.cancelLabelKey === void 0 ? {} : { cancelLabelKey: props.cancelLabelKey },\n\t\t\t\t\t\tonCancel: () => {\n\t\t\t\t\t\t\tprops.onClose(false);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonSubmit: () => {\n\t\t\t\t\t\t\tprops.onSubmitCredential?.();\n\t\t\t\t\t\t\tapply();\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t]\n\t\t\t});\n\t\t}"
|
|
1028
|
+
},
|
|
1029
|
+
{
|
|
1030
|
+
"before": "className: ModelsSection_module_css_default[\"editorActions\"],",
|
|
1031
|
+
"after": "className: ModelsSection_module_css_default[\"editorActions\"],\n\t\t\t\t\"data-model-save-actions\": true,\n\t\t\t\tstyle: { position: \"sticky\", bottom: \"calc(var(--dsh-model-save-offset, 0px) + env(safe-area-inset-bottom, 0px))\", zIndex: 2, padding: \"10px 0\", background: \"var(--dsw-alias-bg-module-platform)\", flexWrap: \"wrap\" },"
|
|
1032
|
+
},
|
|
1033
|
+
{
|
|
1034
|
+
"before": "const en = {\n",
|
|
1035
|
+
"after": "const en = {\n\t\t\tmultiKeyExpand: \"Expand details\",\n\t\t\tmultiKeyCollapse: \"Collapse details\",\n\t\t\tmultiKeyUnsaved: \"Not saved\",\n\t\t\tmultiKeyProtocol: \"Group API protocol\",\n\t\t\tmultiKeyProtocolInherit: \"Inherit provider ({protocol})\",\n\t\t\tmultiKeyProtocolDefault: \"default protocol\",\n\t\t\tmultiKeyProtocolHelp: \"Only this key group is affected. Choose the protocol supported by your relay, not just the model name.\",\n\t\t\tmultiKeyInvalidProtocol: \"Unsupported key-group protocol.\",\n\t\t\tmultiKeyRemoveGroup: \"Remove this key group\",\n\t\t\tmultiKeyRemoveTitle: \"Remove key group “{name}”?\",\n\t\t\tmultiKeyRemoveHelp: \"Removes the entire key group and its model list, not just one model above. Stored credentials are retained.\",\n\t\t\tmultiKeyRemoveDescription: \"This removes the selected group and all of its model entries from the draft. Other groups and stored credentials are retained. Existing conversations are not switched automatically. Changes take effect after Apply; Cancel editing to discard them.\",\n"
|
|
1036
|
+
},
|
|
1037
|
+
{
|
|
1038
|
+
"before": "const zh = {\n",
|
|
1039
|
+
"after": "const zh = {\n\t\t\tmultiKeyExpand: \"展开详情\",\n\t\t\tmultiKeyCollapse: \"收起详情\",\n\t\t\tmultiKeyUnsaved: \"未保存\",\n\t\t\tmultiKeyProtocol: \"分组 API 协议\",\n\t\t\tmultiKeyProtocolInherit: \"跟随供应商({protocol})\",\n\t\t\tmultiKeyProtocolDefault: \"默认协议\",\n\t\t\tmultiKeyProtocolHelp: \"仅影响此密钥分组,请按中转站支持的协议选择,不按模型名称自动切换。\",\n\t\t\tmultiKeyInvalidProtocol: \"不支持此密钥分组协议。\",\n\t\t\tmultiKeyRemoveGroup: \"移除此密钥分组\",\n\t\t\tmultiKeyRemoveTitle: \"移除密钥分组“{name}”?\",\n\t\t\tmultiKeyRemoveHelp: \"移除整个密钥分组及其模型列表,不是仅移除上方一个模型。已保存的密钥凭据会保留。\",\n\t\t\tmultiKeyRemoveDescription: \"此操作从编辑草稿移除该分组及其全部模型条目,其他分组和已保存的密钥凭据不变,不会自动切换现有会话。点击“应用”后才生效;取消编辑可放弃更改。\",\n"
|
|
1040
|
+
},
|
|
1041
|
+
{
|
|
1042
|
+
"before": "const MULTI_KEY_ENTRY_ID =",
|
|
1043
|
+
"after": "function createSettingsReorder({ handle, row, selector, commit, delay = 400 }) {\n const doc = handle.ownerDocument;\n const win = doc.defaultView;\n const list = row.parentElement;\n const rows = () => [...list.querySelectorAll(selector)].filter(item => item.parentElement === list);\n const original = rows();\n let active = false, stopped = false, timer, frame, target, half;\n let x, y, startX, startY, pointerId;\n const oldOutline = row.style.outline;\n const oldOpacity = row.style.opacity;\n let targetShadow;\n function clearTarget() {\n if (target) target.style.boxShadow = targetShadow;\n target = undefined;\n }\n function locate() {\n clearTarget();\n const bounds = list.getBoundingClientRect();\n if (x < bounds.left - 40 || x > bounds.right + 40) return;\n const candidates = rows().filter(item => item !== row && item.getBoundingClientRect().height > 0);\n target = candidates.find(item => y < item.getBoundingClientRect().bottom) ?? candidates.at(-1);\n if (!target) return;\n const rect = target.getBoundingClientRect();\n half = y < rect.top + rect.height / 2 ? 'before' : 'after';\n targetShadow = target.style.boxShadow;\n target.style.boxShadow = `inset 0 ${half === 'before' ? 3 : -3}px 0 var(--dsw-alias-label-primary, #679cff)`;\n }\n const scrollParent = () => {\n for (let node = list; node && node !== doc.documentElement; node = node.parentElement) {\n if (node.scrollHeight > node.clientHeight && /auto|scroll/.test(win.getComputedStyle(node).overflowY)) return node;\n }\n return doc.scrollingElement;\n };\n function tick() {\n if (!active || stopped) return;\n const scroll = scrollParent();\n if (scroll) {\n const viewport = scroll === doc.scrollingElement;\n const rect = viewport ? { top: 0, bottom: win.innerHeight } : scroll.getBoundingClientRect();\n const top = Math.max(0, rect.top), bottom = Math.min(win.innerHeight, rect.bottom);\n const speed = y < top + 56 ? -Math.min(14, (top + 56 - y) / 3) : y > bottom - 56 ? Math.min(14, (y - bottom + 56) / 3) : 0;\n if (speed) { scroll.scrollTop += speed; locate(); }\n }\n frame = win.requestAnimationFrame(tick);\n }\n function cancel() { finish(false); }\n function move(event) {\n if (event.pointerId !== pointerId) { cancel(); return; }\n x = event.clientX; y = event.clientY;\n if (!active) {\n // A swipe before activation is never interpreted as a reorder.\n if (Math.hypot(x - startX, y - startY) > 10) cancel();\n return;\n }\n event.preventDefault();\n locate();\n }\n function up(event) {\n if (event.pointerId !== pointerId) return;\n if (Number.isFinite(event.clientX)) x = event.clientX;\n if (Number.isFinite(event.clientY)) y = event.clientY;\n if (active) locate();\n finish(true);\n }\n function escape(event) { if (event.key === 'Escape') { event.preventDefault(); cancel(); } }\n function context(event) { event.preventDefault(); }\n function finish(save) {\n if (stopped) return;\n stopped = true;\n win.clearTimeout(timer); win.cancelAnimationFrame(frame);\n doc.removeEventListener('pointermove', move, true);\n doc.removeEventListener('pointerup', up, true);\n doc.removeEventListener('pointercancel', cancel, true);\n doc.removeEventListener('pointerdown', secondPointer, true);\n doc.removeEventListener('keydown', escape, true);\n doc.removeEventListener('contextmenu', context, true);\n win.removeEventListener('blur', cancel);\n doc.removeEventListener('visibilitychange', cancel);\n const destination = target;\n clearTarget(); row.style.outline = oldOutline; row.style.opacity = oldOpacity;\n if (handle.hasPointerCapture?.(pointerId)) handle.releasePointerCapture(pointerId);\n const current = rows();\n // Do not apply an offset to a list changed by another control while held.\n if (!save || !active || !destination || current.length !== original.length || current.some((item, index) => item !== original[index])) return;\n const from = current.indexOf(row), at = current.indexOf(destination);\n const insertion = at + (half === 'after' ? 1 : 0);\n const to = insertion > from ? insertion - 1 : insertion;\n if (from >= 0 && to >= 0 && to !== from) commit(to - from);\n }\n function secondPointer(event) { if (event.pointerId !== pointerId) cancel(); }\n return {\n start(event) {\n if (event.button !== 0 || event.isPrimary === false) return;\n pointerId = event.pointerId; x = startX = event.clientX; y = startY = event.clientY;\n handle.setPointerCapture?.(pointerId);\n doc.addEventListener('pointermove', move, { capture: true, passive: false });\n doc.addEventListener('pointerup', up, true);\n doc.addEventListener('pointercancel', cancel, true);\n doc.addEventListener('pointerdown', secondPointer, true);\n doc.addEventListener('keydown', escape, true);\n doc.addEventListener('contextmenu', context, true);\n win.addEventListener('blur', cancel);\n doc.addEventListener('visibilitychange', cancel);\n timer = win.setTimeout(() => {\n if (stopped || !row.isConnected) { cancel(); return; }\n active = true;\n row.style.outline = '2px solid var(--dsw-alias-label-primary, #679cff)';\n row.style.opacity = '0.65';\n locate(); tick();\n }, delay);\n }, cancel\n };\n}\n\t\tfunction useSettingsReorder(config) {\n const latest = (0, react.useRef)(config);\n latest.current = config;\n const gesture = (0, react.useRef)();\n (0, react.useEffect)(() => {\n if (config.disabled) gesture.current?.cancel();\n return () => gesture.current?.cancel();\n }, [config.disabled]);\n return id => ({\n draggable: false,\n style: { minWidth: 44, minHeight: 44, touchAction: 'none', userSelect: 'none', WebkitTouchCallout: 'none', cursor: 'grab', flexShrink: 0 },\n onContextMenu: event => event.preventDefault(),\n onClick: event => { event.preventDefault(); event.stopPropagation(); },\n onPointerDown: event => {\n if (latest.current.disabled || event.button !== 0 || event.isPrimary === false) return;\n gesture.current?.cancel();\n const handle = event.currentTarget;\n const row = handle.closest(latest.current.selector);\n if (!row) return;\n gesture.current = createSettingsReorder({ handle, row, selector: latest.current.selector, commit: offset => {\n if (!latest.current.disabled) latest.current.move(id, offset);\n } });\n gesture.current.start(event);\n },\n onLostPointerCapture: () => gesture.current?.cancel(),\n onKeyDown: event => {\n if (latest.current.disabled || (event.key !== 'ArrowUp' && event.key !== 'ArrowDown')) return;\n event.preventDefault(); event.stopPropagation();\n latest.current.move(id, event.key === 'ArrowUp' ? -1 : 1);\n }\n });\n}\n\t\tconst MULTI_KEY_ENTRY_ID ="
|
|
1044
|
+
},
|
|
1045
|
+
{
|
|
1046
|
+
"before": "const anyBusy = Object.values(busyEntries).some(Boolean);",
|
|
1047
|
+
"after": "const anyBusy = Object.values(busyEntries).some(Boolean);\n\t\t\tconst savedEntryOrder = Object.keys(props.savedEntries ?? props.persistedEntries ?? {});\n\t\t\tconst reorder = useSettingsReorder({ disabled: disabled || anyBusy, selector: \"[data-key-entry-id]\", move: (id, offset) => {\n\t\t\t\tconst ordered = Object.entries(entries), from = ordered.findIndex(([key]) => key === id), to = from + offset;\n\t\t\t\tif (from < 0 || to < 0 || to >= ordered.length) return;\n\t\t\t\tconst [moved] = ordered.splice(from, 1); ordered.splice(to, 0, moved);\n\t\t\t\tonChange(Object.fromEntries(ordered));\n\t\t\t} });"
|
|
1048
|
+
},
|
|
1049
|
+
{
|
|
1050
|
+
"before": "const dirty = multiKeyEntryDirty(entry, props.savedEntries?.[id] ?? props.persistedEntries?.[id], draft);",
|
|
1051
|
+
"after": "const dirty = savedEntryOrder.indexOf(id) !== index || multiKeyEntryDirty(entry, props.savedEntries?.[id] ?? props.persistedEntries?.[id], draft);"
|
|
1052
|
+
},
|
|
1053
|
+
{
|
|
1054
|
+
"before": "children: [(0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowName\"],",
|
|
1055
|
+
"after": "children: [(0, react_jsx_runtime.jsx)(\"button\", {\n\t\t\t\t\t\t\t\ttype: \"button\", className: ModelsSection_module_css_default[\"iconButton\"],\n\t\t\t\t\t\t\t\t\"data-key-entry-handle\": id, \"aria-label\": t(\"multiKeyReorder\") + \" \" + heading,\n\t\t\t\t\t\t\t\t\"aria-keyshortcuts\": \"ArrowUp ArrowDown\", \"aria-description\": t(\"multiKeyReorderHelp\"), title: t(\"multiKeyReorderHelp\"),\n\t\t\t\t\t\t\t\tdisabled: disabled || anyBusy, ...reorder(id),\n\t\t\t\t\t\t\t\tchildren: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconDragHandleOutlineRegular, { size: 14 })\n\t\t\t\t\t\t\t}), (0, react_jsx_runtime.jsx)(\"span\", {\n\t\t\t\t\t\t\t\tclassName: ModelsSection_module_css_default[\"rowName\"],"
|
|
1056
|
+
},
|
|
1057
|
+
{
|
|
1058
|
+
"before": "const preview = (0, _deepseek_ai_dsh_client_ui_primitives.useRowDragPreview)(ModelsSection_module_css_default[\"modelDragPreview\"]);",
|
|
1059
|
+
"after": "const reorder = useSettingsReorder({ disabled, selector: \"[data-row-key]\", move: (_key, offset) => props.order.onMove(offset) });"
|
|
1060
|
+
},
|
|
1061
|
+
{
|
|
1062
|
+
"before": "\n\t\t\t\tonDragOver: (event) => {\n\t\t\t\t\tif (!props.order.canDrop) return;\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.dataTransfer.dropEffect = \"move\";\n\t\t\t\t\tprops.order.onOver(rowHalf(event));\n\t\t\t\t},\n\t\t\t\tonDragLeave: (event) => {\n\t\t\t\t\tif (event.relatedTarget instanceof Node && event.currentTarget.contains(event.relatedTarget)) return;\n\t\t\t\t\tprops.order.onLeave();\n\t\t\t\t},\n\t\t\t\tonDrop: (event) => {\n\t\t\t\t\tif (!props.order.canDrop) return;\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tprops.order.onDrop(rowHalf(event));\n\t\t\t\t},",
|
|
1063
|
+
"after": "\n\t\t\t\t// Reordering is handled by the pointer handle below."
|
|
1064
|
+
},
|
|
1065
|
+
{
|
|
1066
|
+
"before": "\n\t\t\t\t\t\t\t\tdraggable: !disabled,\n\t\t\t\t\t\t\t\tonDragStart: (event) => {\n\t\t\t\t\t\t\t\t\tevent.dataTransfer.effectAllowed = \"move\";\n\t\t\t\t\t\t\t\t\tevent.dataTransfer.setData(\"application/x-dsh-model-order\", String(position));\n\t\t\t\t\t\t\t\t\tprops.order.onStart();\n\t\t\t\t\t\t\t\t\tpreview.start(event, event.currentTarget.closest(\"[data-row-key]\"));\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tonDragEnd: () => {\n\t\t\t\t\t\t\t\t\tif (preview.clear()) props.order.onEnd();\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tonKeyDown: (event) => {\n\t\t\t\t\t\t\t\t\tif (event.key !== \"ArrowUp\" && event.key !== \"ArrowDown\") return;\n\t\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\tprops.order.onMove(event.key === \"ArrowUp\" ? -1 : 1);\n\t\t\t\t\t\t\t\t},",
|
|
1067
|
+
"after": "\n\t\t\t\t\t\t\t\t...reorder(props.rowKey),"
|
|
1068
|
+
},
|
|
1069
|
+
{
|
|
1070
|
+
"before": "label: t(\"reorderModelHelp\"),",
|
|
1071
|
+
"after": "label: t(\"modelReorderTouchHelp\"),"
|
|
1072
|
+
},
|
|
1073
|
+
{
|
|
1074
|
+
"before": "\"aria-description\": t(\"reorderModelHelp\"),",
|
|
1075
|
+
"after": "\"aria-description\": t(\"modelReorderTouchHelp\"),"
|
|
1076
|
+
},
|
|
1077
|
+
{
|
|
1078
|
+
"before": "const en = {\n",
|
|
1079
|
+
"after": "const en = {\n\t\t\tmultiKeyReorder: \"Reorder key group\",\n\t\t\tmultiKeyReorderHelp: \"Hold the handle to reorder; or use Arrow Up/Down. Save with the other edits.\",\n\t\t\tmodelReorderTouchHelp: \"Hold the handle to reorder; or use Arrow Up/Down. Save with the other edits.\",\n"
|
|
1080
|
+
},
|
|
1081
|
+
{
|
|
1082
|
+
"before": "const zh = {\n",
|
|
1083
|
+
"after": "const zh = {\n\t\t\tmultiKeyReorder: \"调整密钥分组顺序\",\n\t\t\tmultiKeyReorderHelp: \"长按手柄拖动,或用上下方向键调整;与其他改动一起保存。\",\n\t\t\tmodelReorderTouchHelp: \"长按手柄拖动,或用上下方向键调整;与其他改动一起保存。\",\n"
|
|
1084
|
+
}
|
|
1085
|
+
]
|
|
554
1086
|
}
|
|
555
1087
|
]
|
|
556
1088
|
}
|