window.__ModuleLoader__.load({ id: '@local/thinking-level-selector', factory(require) { const React = require('react'); const h = React.createElement; const NS = 'thinkingLevel'; const en = { label: 'Thinking level', none: 'Thinking', default: 'Default', loading: 'Loading…', }; const zh = { label: '思考强度', none: '思考', default: '默认', loading: '加载中…', }; // DSH derives names from the level key ("xhigh" -> "Xhigh"); show friendlier ones. const LEVEL_NAMES = { xhigh: 'Extra' }; const levelName = (e) => LEVEL_NAMES[e.id] ?? e.name; // Same shape of data the model seat renders from. function currentReasoning(state) { const cur = state.current; if (!cur) return undefined; for (const g of state.groups) { if (g.id !== cur.provider) continue; const m = g.models.find((x) => x.id === cur.model); if (m) return m.reasoning; } return undefined; } function ThinkingLevel({ locked, available, directory, load, select, t }) { const state = React.useSyncExternalStore( (fn) => directory.subscribe(fn), () => directory.getSnapshot(), ); const [open, setOpen] = React.useState(false); const rootRef = React.useRef(null); React.useEffect(() => { if (available) load(); }, [available]); React.useEffect(() => { if (!open) return undefined; const onDown = (e) => { if (rootRef.current && !rootRef.current.contains(e.target)) setOpen(false); }; const onKey = (e) => { if (e.key === 'Escape') setOpen(false); }; document.addEventListener('mousedown', onDown); document.addEventListener('keydown', onKey); return () => { document.removeEventListener('mousedown', onDown); document.removeEventListener('keydown', onKey); }; }, [open]); const reasoning = currentReasoning(state); if (!available || !reasoning || reasoning.efforts.length === 0) return null; const cur = state.current; const effective = cur.reasoningEffort ?? reasoning.defaultEffort; const active = reasoning.efforts.find((e) => e.id === effective); const label = active ? levelName(active) : t('default'); const disabled = locked || state.status === 'selecting'; const pick = (effort) => { setOpen(false); if (effort === effective) return; select({ provider: cur.provider, model: cur.model, ...(effort === undefined ? {} : { reasoningEffort: effort }), }); }; const itemStyle = (selected) => ({ display: 'flex', alignItems: 'center', gap: 8, width: '100%', padding: '6px 10px', border: 0, borderRadius: 6, cursor: 'pointer', textAlign: 'left', font: 'inherit', fontSize: 13, whiteSpace: 'nowrap', background: selected ? 'var(--dsw-alias-interactive-bg-hover)' : 'transparent', color: 'var(--dsw-alias-label-primary, inherit)', }); return h('div', { ref: rootRef, style: { position: 'relative', display: 'inline-flex' } }, h('button', { type: 'button', disabled, title: t('label'), 'aria-label': t('label'), 'aria-haspopup': 'listbox', 'aria-expanded': open, onClick: () => setOpen((v) => !v), style: { display: 'inline-flex', alignItems: 'center', gap: 4, padding: '2px 8px', border: 0, borderRadius: 6, background: 'transparent', font: 'inherit', fontSize: 13, cursor: disabled ? 'default' : 'pointer', color: 'var(--dsw-alias-label-secondary, inherit)', opacity: disabled ? 0.5 : 1, whiteSpace: 'nowrap', }, }, label, h('span', { 'aria-hidden': true, style: { fontSize: 10 } }, '▾')), open && h('div', { role: 'listbox', style: { position: 'absolute', bottom: 'calc(100% + 6px)', left: 0, zIndex: 50, minWidth: 140, padding: 4, borderRadius: 8, background: 'var(--dsw-specific-input-major, #fff)', boxShadow: 'var(--dsw-elevation-soft, 0 4px 16px rgba(0,0,0,.18))', border: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,.3))', }, }, reasoning.defaultEffort === undefined && h('button', { type: 'button', role: 'option', 'aria-selected': effective === undefined, onClick: () => pick(undefined), style: itemStyle(effective === undefined), }, t('default')), reasoning.efforts.map((e) => h('button', { key: e.id, type: 'button', role: 'option', title: e.description, 'aria-selected': e.id === effective, onClick: () => pick(e.id), style: itemStyle(e.id === effective), }, levelName(e), e.id === reasoning.defaultEffort ? h('span', { style: { opacity: 0.55, fontSize: 11 } }, '· ' + t('default')) : null)), ), ); } return { inject: ['slots', 'locale', 'sessions', 'remote', 'remote.session', 'modelDirectories'], apply(ctx) { ctx.effect(() => ctx.locale.register(NS, { en, zh }), 'thinking-level: dictionaries'); ctx.slots.inject('conversation.input.activity', () => ctx.slots.register({ name: 'conversation.input.activity', locale: NS, inject: (sessionId) => { const directory = ctx.modelDirectories.directoryFor(sessionId); const available = ctx.sessions.subagentAddress(sessionId) === undefined; return { available, directory: directory.store, load: () => { if (available) directory.load().catch(() => {}); }, select: (sel) => available ? directory.select(sel) : Promise.resolve(undefined), }; }, }, ThinkingLevel)); }, }; }, });