dsh-model-reasoning-defaults 0.0.1 → 0.0.2

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/README.md CHANGED
@@ -217,7 +217,7 @@ llm-deepseek:
217
217
 
218
218
  本插件包含 Web 客户端扩展(`src/client/index.ts`):
219
219
  - 注册到 DSH 设置页槽位 `settings.section`(「推理等级默认」面板):增删路由行、从已知等级集合下拉选择,保存写入本插件的 `model-reasoning-defaults` 设置命名空间。
220
- - 数据经宿主统一 settings Remote(`remote.settings.describe` / `update`)实时读取渲染;保存携带 `expectedRevision` 修订号,并发编辑时由宿主裁决而非静默覆盖。
220
+ - 数据经宿主统一 settings Remote(`remote.settings.describe` / `replace`)实时读取渲染;保存携带 `expectedRevision` 修订号,并发编辑时由宿主裁决而非静默覆盖。保存走 `replace`(整段替换)而非 `update`(merge patch):merge 语义下省略键不表达删除,删除的路由会被存储层原样保留。
221
221
  - 路由键输入带建议弹层(来自 `llm-pi-ai` / `llm-deepseek` 已配置的 Provider/Model),面板内展示匹配语义与生效优先级说明。
222
222
 
223
223
  ---
package/lib/client.js CHANGED
@@ -276,7 +276,7 @@ window.__ModuleLoader__.load({
276
276
  setSaving(true);
277
277
  setFeedback(void 0);
278
278
  try {
279
- const response = await api.update(SETTINGS_NS, { defaults: collapsed }, revisionRef.revision);
279
+ const response = await api.replace(SETTINGS_NS, { defaults: collapsed }, revisionRef.revision);
280
280
  if (!response.ok) {
281
281
  setFeedback({
282
282
  kind: "error",
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["useState","createElement","Menu","Input","Button","IconChevronDownOutline14","IconTrashOutline16","IconPlusOutline16"],"sources":["../src/client/index.ts"],"sourcesContent":["/**\n * dsh-model-reasoning-defaults 的客户端半体。\n *\n * - 设置页 section:编辑本插件设置命名空间中的扁平路由表,经宿主统一的\n * settings API 写入。Host 每次请求实时读取该层,保存即生效。\n *\n * 控件一律使用官方 @deepseek-ai/dsh-client-ui-primitives(平台基线模块,\n * 宿主模块表直接应答),与设置壳视觉一致。\n */\nimport { createElement, useEffect, useState } from 'react'\nimport type { ChangeEvent, CSSProperties, ReactNode } from 'react'\nimport {\n Button,\n IconChevronDownOutline14,\n IconPlusOutline16,\n IconTrashOutline16,\n Input,\n Menu,\n} from '@deepseek-ai/dsh-client-ui-primitives'\n// Type-only:拉入 SlotMap 声明面,使下方 declare module 增强可解析。\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\n\n/** 设置页 section 槽位类型由 ui-settings 壳声明;本插件不依赖该包,本地补齐面。 */\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface SlotMap {\n 'settings.section': { kind: 'list'; scope: 'root'; owner: { close: () => void } }\n }\n}\n\n/** 宿主 SlotRegistry 的窄面:本插件只用 inject/register 两个入口。 */\ninterface SlotRegistry {\n inject(name: string, callback: () => () => void): () => void\n register(options: unknown, component: unknown): () => void\n}\n\n/** 本插件的设置命名空间,与 Host 侧 UI_DEFAULTS_NAMESPACE 一致。 */\nconst SETTINGS_NS = 'model-reasoning-defaults'\n\n/** 已知推理等级集合(与 Host 侧 KNOWN_REASONING_EFFORTS 保持一致)。 */\nconst KNOWN_EFFORTS = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'] as const\n\ntype ClientContext = {\n slots: SlotRegistry\n remote: {\n settings: RemoteSettings\n }\n}\n\n/** 声明客户端所需的槽位与 settings Remote 命名空间。 */\nexport const inject = ['slots', 'remote', 'remote.settings'] as const\n\n/** settings Remote 的读写方法面(宿主 API Gateway 经 Typert Remote 生成)。 */\ninterface RemoteSettings {\n describe(): Promise<RemoteResult<SettingsDescribeValue>>\n update(\n ns: string,\n patch: Record<string, unknown>,\n expectedRevision: number | undefined,\n ): Promise<RemoteResult<SettingsNamespaceView>>\n}\n\n/** Typert Remote 统一应答形状。 */\ntype RemoteResult<T> =\n | { ok: true; value: T }\n | { ok: false; error: { code: string; message: string; details: object } }\n\n/** describe 应答:每个已注册命名空间与写入能力标记。 */\ninterface SettingsDescribeValue {\n /** 设置文档是否可写。 */\n writable: boolean\n /** 是否有宿主侧的设置文档。 */\n hasDocument: boolean\n /** 已注册命名空间视图列表。 */\n namespaces: SettingsNamespaceView[]\n}\n\n/** 单个命名空间的描述视图。 */\ninterface SettingsNamespaceView {\n /** 命名空间键。 */\n ns: string\n /** 脱敏后的解析值。 */\n value: unknown\n /** 该视图读取时的修订号,写回时作为 expectedRevision。 */\n revision: number\n}\n\n/** apply 时捕获的设置 Remote;组件经模块级引用读取(单注册插件,热重载时随 apply 刷新)。 */\nlet currentApi: RemoteSettings | undefined\n\n/** 一条可编辑的路由行。 */\ninterface RouteRow {\n key: string\n effort: string\n}\n\n/** describe 应答中单个命名空间的视图子集。 */\ninterface NamespaceView {\n ns: string\n value: unknown\n revision: number\n}\n\n/**\n * 从 describe 应答中提取本插件命名空间的路由表与修订号。\n *\n * @param namespaces - describe 应答携带的命名空间视图列表。\n * @returns 路由字典副本与修订号;命名空间尚未注册时为 undefined。\n */\nfunction findOwnNamespace(namespaces: NamespaceView[]): { defaults: Record<string, string>; revision: number } | undefined {\n const own = namespaces.find(entry => entry.ns === SETTINGS_NS)\n if (own === undefined) return undefined\n const section = own.value as { defaults?: Record<string, string> } | null\n return {\n defaults: section !== null && typeof section === 'object'\n && section.defaults !== undefined && typeof section.defaults === 'object'\n ? { ...section.defaults }\n : {},\n revision: own.revision,\n }\n}\n\n/**\n * 从 describe 应答中收集已知 provider 与 provider:model 路由键,作为输入建议。\n *\n * @param namespaces - describe 应答携带的命名空间视图列表。\n * @returns 排序后的建议键列表。\n */\nfunction collectSuggestions(namespaces: NamespaceView[]): string[] {\n const suggestions = new Set<string>()\n const addProvider = (id: string, models: readonly string[]): void => {\n const providerId = id.trim()\n if (providerId.length === 0) return\n suggestions.add(providerId)\n for (const model of models) {\n const modelId = model.trim()\n if (modelId.length > 0) suggestions.add(providerId + ':' + modelId)\n }\n }\n\n const piAi = namespaces.find(entry => entry.ns === 'llm-pi-ai')?.value as {\n providers?: Record<string, { models?: Array<{ id?: unknown }> }>\n } | null\n if (piAi?.providers && typeof piAi.providers === 'object') {\n for (const [providerId, profile] of Object.entries(piAi.providers)) {\n const models = Array.isArray(profile?.models)\n ? profile.models.map(m => (typeof m?.id === 'string' ? m.id : '')).filter(id => id.length > 0)\n : []\n addProvider(providerId, models)\n }\n }\n\n if (namespaces.some(entry => entry.ns === 'llm-deepseek')) addProvider('deepseek-official', [])\n\n return [...suggestions].sort()\n}\n\n/** 建议弹层最多展示的条数;更多条目没有滚动价值,缩小查询即可。 */\nconst SUGGESTION_LIMIT = 12\n\n/**\n * 按当前输入过滤建议键:子串匹配(路由键常以 provider 前缀开头,前缀过滤\n * 会漏掉 model 段命中),排除与输入完全相同的项,空输入展示前若干条。\n *\n * @param value - 输入框当前值。\n * @param all - 全量建议键。\n * @returns 供弹层展示的建议键列表。\n */\nfunction suggestionMatches(value: string, all: string[]): string[] {\n const exact = value.trim()\n const query = exact.toLowerCase()\n const pool = query.length === 0\n ? all\n : all.filter(candidate => candidate !== exact && candidate.toLowerCase().includes(query))\n return pool.slice(0, SUGGESTION_LIMIT)\n}\n\n// 颜色一律使用 --dsw-alias-* 语义 token(随明暗主题翻转);布局遵循设置壳\n// 约定:.options 已提供 24px 内边距,section 只负责纵向节奏与最大宽度。\nconst sectionStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 12,\n maxWidth: 720,\n color: 'var(--dsw-alias-label-primary)',\n}\n\nconst titleStyle: CSSProperties = {\n margin: 0,\n fontSize: 16,\n fontWeight: 600,\n lineHeight: 1.4,\n}\n\nconst rowStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n}\n\nconst keyFieldStyle: CSSProperties = {\n flex: 1,\n minWidth: 0,\n}\n\nconst mutedStyle: CSSProperties = {\n margin: 0,\n fontSize: 13,\n lineHeight: 1.6,\n color: 'var(--dsw-alias-label-tertiary)',\n}\n\nconst hintStyle: CSSProperties = {\n margin: 0,\n fontSize: 12,\n lineHeight: 1.6,\n color: 'var(--dsw-alias-label-tertiary)',\n}\n\nconst errorStyle: CSSProperties = {\n margin: 0,\n fontSize: 12,\n lineHeight: 1.6,\n color: 'var(--dsw-alias-state-error-primary)',\n}\n\nconst okStyle: CSSProperties = {\n margin: 0,\n fontSize: 12,\n lineHeight: 1.6,\n color: 'var(--dsw-alias-state-success-primary)',\n}\n\n/**\n * 把官方 Input 的默认几何(h32 / r8 / 字号 14)对齐到行内 sm 胶囊控件\n * (Button.sm:h28 / r14 / 字号 12),使路由键输入框与右侧下拉、删除按钮同高同形。\n * 建议弹层的包裹 span 由 Menu 注入为 inline 布局,这里展开成块级并撑满列宽,\n * 让弹层与输入框左缘对齐。通过 data-plugin-css 标记幂等注入,遵循宿主插件样式约定。\n */\nconst COMPACT_INPUT_CSS = [\n '.dsh-mrd-input-sm {',\n // 宿主无全局 border-box reset:content-box 下 width:100% 只是内容宽,\n // 叠加 padding/border 后总宽超出父容器 22px,溢出盖住右侧按钮。\n ' box-sizing: border-box;',\n ' width: 100%;',\n ' height: 28px;',\n ' border-radius: 14px;',\n ' padding: 0 10px;',\n '}',\n '.dsh-mrd-input-sm > input {',\n ' font-size: 12px;',\n ' line-height: 18px;',\n '}',\n '.dsh-mrd-suggest {',\n ' display: block;',\n ' width: 100%;',\n '}',\n].join('\\n')\n\nconst COMPACT_INPUT_STYLE_TAG = 'dsh-model-reasoning-defaults/input-sm'\n\n// 样式注入必须脱离 React 渲染树(模块级副作用):若以组件节点渲染,每次\n// 渲染的 DOM 幂等检查会让 React 把该节点当作\"不再渲染\"而卸载/重挂,\n// 菜单展开等重渲染期间样式短暂丢失,`.dsh-mrd-suggest` 回退为 Menu 默认的\n// inline-flex,输入框宽度塌缩(跟随宿主 tsdown.client.ts 的注入约定)。\nif (\n typeof document !== 'undefined'\n && document.querySelector('style[data-plugin-css=\"' + COMPACT_INPUT_STYLE_TAG + '\"]') === null\n) {\n const tag = document.createElement('style')\n tag.dataset.plugin = 'dsh-model-reasoning-defaults'\n tag.dataset.pluginCss = COMPACT_INPUT_STYLE_TAG\n tag.textContent = COMPACT_INPUT_CSS\n document.head.appendChild(tag)\n}\n\n/**\n * 把路由字典展开成按键排序的可编辑行。\n *\n * @param defaults - 路由字典。\n * @returns 稳定排序的行列表。\n */\nfunction rowsOf(defaults: Record<string, string>): RouteRow[] {\n return Object.entries(defaults)\n .map(([key, effort]) => ({ key, effort }))\n .sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0))\n}\n\n/**\n * 校验待保存的行集合并折叠回路由字典。\n *\n * @param rows - 当前编辑的行。\n * @returns 校验通过时返回字典;失败时返回错误消息。\n */\nfunction collapseRows(rows: RouteRow[]): Record<string, string> | { error: string } {\n const result: Record<string, string> = {}\n for (const row of rows) {\n const key = row.key.trim()\n // 空键行是编辑过程中的残渣:直接丢弃而不是拦住保存。\n if (key.length === 0) continue\n if (key in result) return { error: '存在重复路由键:' + key }\n result[key] = row.effort\n }\n return result\n}\n\n/**\n * 设置页「推理等级默认」编辑面板。\n *\n * 数据流:挂载时 describe 读一次(拿路由表、修订号、只读标记与建议键);\n * 保存时带 expectedRevision 做 update,陈旧编辑会被宿主拒绝而不是静默覆盖。\n * 外部改动(另一标签页、手工编辑 yaml)在本组件重新挂载时可见——设置壳每次\n * 打开都重新挂载 section,无需订阅失效事件。\n *\n * @param props - 无属主属性(close 由壳持有,本面板不离开设置页)。\n * @returns 面板节点树。\n */\nfunction ReasoningDefaultsSection(_props: { close: () => void }): ReactNode {\n const [rows, setRows] = useState<RouteRow[]>([])\n const [phase, setPhase] = useState<'loading' | 'ready' | 'unavailable'>('loading')\n const [writable, setWritable] = useState(true)\n const [saving, setSaving] = useState(false)\n const [feedback, setFeedback] = useState<{ kind: 'ok' | 'error'; text: string } | undefined>(undefined)\n const [suggestions, setSuggestions] = useState<string[]>([])\n const [openMenuIndex, setOpenMenuIndex] = useState<number | null>(null)\n const [suggestIndex, setSuggestIndex] = useState<number | null>(null)\n const revisionRef = useState<{ revision: number }>(() => ({ revision: 0 }))[0]\n\n useEffect(() => {\n let cancelled = false\n const load = async (): Promise<void> => {\n const api = currentApi\n if (api === undefined) {\n if (!cancelled) setPhase('unavailable')\n return\n }\n try {\n const response = await api.describe()\n if (cancelled) return\n if (!response.ok) {\n setPhase('unavailable')\n setFeedback({ kind: 'error', text: response.error.message })\n return\n }\n const own = findOwnNamespace(response.value.namespaces)\n if (own === undefined) {\n setPhase('unavailable')\n setFeedback({ kind: 'error', text: 'Host 未注册 ' + SETTINGS_NS + ' 命名空间,请确认插件已启用并刷新页面' })\n return\n }\n setRows(rowsOf(own.defaults))\n revisionRef.revision = own.revision\n setWritable(response.value.writable)\n setSuggestions(collectSuggestions(response.value.namespaces))\n setPhase('ready')\n } catch (error) {\n if (!cancelled) {\n setPhase('unavailable')\n setFeedback({ kind: 'error', text: error instanceof Error ? error.message : String(error) })\n }\n }\n }\n void load()\n return () => { cancelled = true }\n }, [revisionRef])\n\n const save = async (): Promise<void> => {\n const api = currentApi\n if (api === undefined || saving) return\n const collapsed = collapseRows(rows)\n if ('error' in collapsed) {\n setFeedback({ kind: 'error', text: collapsed.error })\n return\n }\n setSaving(true)\n setFeedback(undefined)\n try {\n const response = await api.update(SETTINGS_NS, { defaults: collapsed }, revisionRef.revision)\n if (!response.ok) {\n setFeedback({ kind: 'error', text: response.error.message })\n return\n }\n // 写回应答里带新修订号;再 describe 一次让行视图与存储严格一致(含 trim)。\n const reread = await api.describe()\n if (reread.ok) {\n const own = findOwnNamespace(reread.value.namespaces)\n if (own !== undefined) {\n setRows(rowsOf(own.defaults))\n revisionRef.revision = own.revision\n }\n }\n setFeedback({ kind: 'ok', text: '已保存,对新请求即时生效' })\n } catch (error) {\n setFeedback({ kind: 'error', text: error instanceof Error ? error.message : String(error) })\n } finally {\n setSaving(false)\n }\n }\n\n if (phase === 'loading') {\n return createElement('div', { style: sectionStyle }, createElement('p', { style: mutedStyle }, '加载推理等级配置…'))\n }\n\n if (phase === 'unavailable') {\n return createElement(\n 'div',\n { style: sectionStyle },\n createElement('p', { style: errorStyle }, '无法读取推理等级配置。'),\n feedback === undefined\n ? null\n : createElement('p', { style: feedback.kind === 'error' ? errorStyle : okStyle }, feedback.text),\n )\n }\n\n const children: ReactNode[] = [\n createElement('div', { key: 'title', style: titleStyle }, '推理等级默认'),\n createElement(\n 'p',\n { key: 'intro', style: mutedStyle },\n '请求未显式指定 reasoningEffort 时按此路由表补齐。匹配顺序:provider:model → provider:* → provider/* → provider → *:model → *。',\n ),\n ]\n\n if (!writable) {\n children.push(createElement('p', { key: 'readonly', style: mutedStyle }, '当前设置文档为只读,修改需在 Host 侧完成。'))\n }\n\n for (let index = 0; index < rows.length; index += 1) {\n const row = rows[index]\n const menuOpen = openMenuIndex === index\n const keySuggestions = suggestionMatches(row.key, suggestions)\n children.push(createElement(\n 'div',\n { key: 'row-' + index, style: rowStyle },\n createElement('div', { key: 'key', style: keyFieldStyle },\n // 建议弹层与等级下拉一样走 portal:设置壳的 .panel 裁剪 overflow,\n // 原地弹层会被裁掉或顶出面板(原生 datalist 更是完全不受控)。\n createElement(Menu, {\n key: 'key-suggest',\n className: 'dsh-mrd-suggest',\n open: suggestIndex === index && keySuggestions.length > 0,\n portal: true,\n dense: true,\n items: keySuggestions.map(candidate => ({ id: candidate, label: candidate })),\n onSelect: (candidate: string) => {\n const next = [...rows]\n next[index] = { ...row, key: candidate }\n setRows(next)\n setSuggestIndex(null)\n },\n onClose: () => { setSuggestIndex(null) },\n anchor: createElement(Input, {\n className: 'dsh-mrd-input-sm',\n value: row.key,\n placeholder: 'provider:model / provider:* / *',\n 'aria-label': '路由键',\n style: { width: '100%' },\n onFocus: () => { setSuggestIndex(index) },\n onChange: (event: ChangeEvent<HTMLInputElement>) => {\n const next = [...rows]\n next[index] = { ...row, key: event.target.value }\n setRows(next)\n setSuggestIndex(index)\n },\n }),\n }),\n ),\n createElement(Menu, {\n key: 'effort',\n open: menuOpen,\n onClose: () => { setOpenMenuIndex(null) },\n portal: true,\n dense: true,\n items: KNOWN_EFFORTS.map(level => ({ id: level, label: level })),\n selectedId: row.effort,\n onSelect: (id: string) => {\n const next = [...rows]\n next[index] = { ...row, effort: id }\n setRows(next)\n setOpenMenuIndex(null)\n },\n anchor: createElement(Button, {\n variant: 'outline',\n size: 'sm',\n 'aria-haspopup': 'menu',\n 'aria-expanded': menuOpen,\n onClick: () => { setOpenMenuIndex(menuOpen ? null : index) },\n }, row.effort, createElement(IconChevronDownOutline14)),\n }),\n createElement(Button, {\n key: 'remove',\n variant: 'ghost',\n size: 'sm',\n icon: createElement(IconTrashOutline16),\n 'aria-label': '删除路由 ' + row.key,\n title: '删除该路由',\n onClick: () => {\n setRows(rows.filter((_, i) => i !== index))\n setOpenMenuIndex(null)\n setSuggestIndex(null)\n },\n }, '删除'),\n ))\n }\n\n children.push(createElement(\n 'div',\n { key: 'actions', style: rowStyle },\n createElement(Button, {\n variant: 'outline',\n size: 'sm',\n icon: createElement(IconPlusOutline16),\n onClick: () => setRows([...rows, { key: '', effort: 'medium' }]),\n }, '添加路由'),\n createElement(Button, {\n variant: 'primary',\n size: 'sm',\n disabled: saving || !writable || rows.length === 0,\n onClick: () => { void save() },\n }, saving ? '保存中…' : '保存'),\n ))\n\n children.push(createElement(\n 'p',\n { key: 'hint', style: hintStyle },\n '已知等级:' + KNOWN_EFFORTS.join(' / ')\n + '。生效优先级:patch 层插件配置 > 此处 > Host 各 Provider 已声明的思考等级。'\n + '路由键支持 * 通配,聚焦输入框可查看已配置 Provider/Model 的建议。',\n ))\n\n if (feedback !== undefined) {\n children.push(createElement(\n 'p',\n { key: 'feedback', style: { ...(feedback.kind === 'error' ? errorStyle : okStyle) } },\n feedback.text,\n ))\n }\n\n return createElement('div', { style: sectionStyle }, children)\n}\n\n/**\n * 注册设置页编辑 section。\n *\n * slots.inject 已绑定当前 fiber 的生命周期,不需要再套一层 effect,\n * 注册和注销由同一个 slot owner 管理,不会留下嵌套 disposer。\n *\n * @param ctx - 提供槽位与连接服务的客户端上下文。\n */\nexport function apply(ctx: ClientContext): void {\n // 宿主 API Gateway 装配了 settings Remote 命名空间后,ctx.remote.settings 才可用;\n // inject 声明保证了装配顺序,此处直接引用。\n currentApi = ctx.remote.settings\n\n ctx.slots.inject(\n 'settings.section',\n () => ctx.slots.register({\n name: 'settings.section',\n id: SETTINGS_NS,\n order: 15,\n label: () => '推理等级默认',\n }, ReasoningDefaultsSection),\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["useState","createElement","Menu","Input","Button","IconChevronDownOutline14","IconTrashOutline16","IconPlusOutline16"],"sources":["../src/client/index.ts"],"sourcesContent":["/**\n * dsh-model-reasoning-defaults 的客户端半体。\n *\n * - 设置页 section:编辑本插件设置命名空间中的扁平路由表,经宿主统一的\n * settings API 写入。Host 每次请求实时读取该层,保存即生效。\n *\n * 控件一律使用官方 @deepseek-ai/dsh-client-ui-primitives(平台基线模块,\n * 宿主模块表直接应答),与设置壳视觉一致。\n */\nimport { createElement, useEffect, useState } from 'react'\nimport type { ChangeEvent, CSSProperties, ReactNode } from 'react'\nimport {\n Button,\n IconChevronDownOutline14,\n IconPlusOutline16,\n IconTrashOutline16,\n Input,\n Menu,\n} from '@deepseek-ai/dsh-client-ui-primitives'\n// Type-only:拉入 SlotMap 声明面,使下方 declare module 增强可解析。\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\n\n/** 设置页 section 槽位类型由 ui-settings 壳声明;本插件不依赖该包,本地补齐面。 */\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface SlotMap {\n 'settings.section': { kind: 'list'; scope: 'root'; owner: { close: () => void } }\n }\n}\n\n/** 宿主 SlotRegistry 的窄面:本插件只用 inject/register 两个入口。 */\ninterface SlotRegistry {\n inject(name: string, callback: () => () => void): () => void\n register(options: unknown, component: unknown): () => void\n}\n\n/** 本插件的设置命名空间,与 Host 侧 UI_DEFAULTS_NAMESPACE 一致。 */\nconst SETTINGS_NS = 'model-reasoning-defaults'\n\n/** 已知推理等级集合(与 Host 侧 KNOWN_REASONING_EFFORTS 保持一致)。 */\nconst KNOWN_EFFORTS = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'] as const\n\ntype ClientContext = {\n slots: SlotRegistry\n remote: {\n settings: RemoteSettings\n }\n}\n\n/** 声明客户端所需的槽位与 settings Remote 命名空间。 */\nexport const inject = ['slots', 'remote', 'remote.settings'] as const\n\n/** settings Remote 的读写方法面(宿主 API Gateway 经 Typert Remote 生成)。 */\ninterface RemoteSettings {\n describe(): Promise<RemoteResult<SettingsDescribeValue>>\n replace(\n ns: string,\n section: Record<string, unknown>,\n expectedRevision: number | undefined,\n ): Promise<RemoteResult<SettingsNamespaceView>>\n}\n\n/** Typert Remote 统一应答形状。 */\ntype RemoteResult<T> =\n | { ok: true; value: T }\n | { ok: false; error: { code: string; message: string; details: object } }\n\n/** describe 应答:每个已注册命名空间与写入能力标记。 */\ninterface SettingsDescribeValue {\n /** 设置文档是否可写。 */\n writable: boolean\n /** 是否有宿主侧的设置文档。 */\n hasDocument: boolean\n /** 已注册命名空间视图列表。 */\n namespaces: SettingsNamespaceView[]\n}\n\n/** 单个命名空间的描述视图。 */\ninterface SettingsNamespaceView {\n /** 命名空间键。 */\n ns: string\n /** 脱敏后的解析值。 */\n value: unknown\n /** 该视图读取时的修订号,写回时作为 expectedRevision。 */\n revision: number\n}\n\n/** apply 时捕获的设置 Remote;组件经模块级引用读取(单注册插件,热重载时随 apply 刷新)。 */\nlet currentApi: RemoteSettings | undefined\n\n/** 一条可编辑的路由行。 */\ninterface RouteRow {\n key: string\n effort: string\n}\n\n/** describe 应答中单个命名空间的视图子集。 */\ninterface NamespaceView {\n ns: string\n value: unknown\n revision: number\n}\n\n/**\n * 从 describe 应答中提取本插件命名空间的路由表与修订号。\n *\n * @param namespaces - describe 应答携带的命名空间视图列表。\n * @returns 路由字典副本与修订号;命名空间尚未注册时为 undefined。\n */\nfunction findOwnNamespace(namespaces: NamespaceView[]): { defaults: Record<string, string>; revision: number } | undefined {\n const own = namespaces.find(entry => entry.ns === SETTINGS_NS)\n if (own === undefined) return undefined\n const section = own.value as { defaults?: Record<string, string> } | null\n return {\n defaults: section !== null && typeof section === 'object'\n && section.defaults !== undefined && typeof section.defaults === 'object'\n ? { ...section.defaults }\n : {},\n revision: own.revision,\n }\n}\n\n/**\n * 从 describe 应答中收集已知 provider 与 provider:model 路由键,作为输入建议。\n *\n * @param namespaces - describe 应答携带的命名空间视图列表。\n * @returns 排序后的建议键列表。\n */\nfunction collectSuggestions(namespaces: NamespaceView[]): string[] {\n const suggestions = new Set<string>()\n const addProvider = (id: string, models: readonly string[]): void => {\n const providerId = id.trim()\n if (providerId.length === 0) return\n suggestions.add(providerId)\n for (const model of models) {\n const modelId = model.trim()\n if (modelId.length > 0) suggestions.add(providerId + ':' + modelId)\n }\n }\n\n const piAi = namespaces.find(entry => entry.ns === 'llm-pi-ai')?.value as {\n providers?: Record<string, { models?: Array<{ id?: unknown }> }>\n } | null\n if (piAi?.providers && typeof piAi.providers === 'object') {\n for (const [providerId, profile] of Object.entries(piAi.providers)) {\n const models = Array.isArray(profile?.models)\n ? profile.models.map(m => (typeof m?.id === 'string' ? m.id : '')).filter(id => id.length > 0)\n : []\n addProvider(providerId, models)\n }\n }\n\n if (namespaces.some(entry => entry.ns === 'llm-deepseek')) addProvider('deepseek-official', [])\n\n return [...suggestions].sort()\n}\n\n/** 建议弹层最多展示的条数;更多条目没有滚动价值,缩小查询即可。 */\nconst SUGGESTION_LIMIT = 12\n\n/**\n * 按当前输入过滤建议键:子串匹配(路由键常以 provider 前缀开头,前缀过滤\n * 会漏掉 model 段命中),排除与输入完全相同的项,空输入展示前若干条。\n *\n * @param value - 输入框当前值。\n * @param all - 全量建议键。\n * @returns 供弹层展示的建议键列表。\n */\nfunction suggestionMatches(value: string, all: string[]): string[] {\n const exact = value.trim()\n const query = exact.toLowerCase()\n const pool = query.length === 0\n ? all\n : all.filter(candidate => candidate !== exact && candidate.toLowerCase().includes(query))\n return pool.slice(0, SUGGESTION_LIMIT)\n}\n\n// 颜色一律使用 --dsw-alias-* 语义 token(随明暗主题翻转);布局遵循设置壳\n// 约定:.options 已提供 24px 内边距,section 只负责纵向节奏与最大宽度。\nconst sectionStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 12,\n maxWidth: 720,\n color: 'var(--dsw-alias-label-primary)',\n}\n\nconst titleStyle: CSSProperties = {\n margin: 0,\n fontSize: 16,\n fontWeight: 600,\n lineHeight: 1.4,\n}\n\nconst rowStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n}\n\nconst keyFieldStyle: CSSProperties = {\n flex: 1,\n minWidth: 0,\n}\n\nconst mutedStyle: CSSProperties = {\n margin: 0,\n fontSize: 13,\n lineHeight: 1.6,\n color: 'var(--dsw-alias-label-tertiary)',\n}\n\nconst hintStyle: CSSProperties = {\n margin: 0,\n fontSize: 12,\n lineHeight: 1.6,\n color: 'var(--dsw-alias-label-tertiary)',\n}\n\nconst errorStyle: CSSProperties = {\n margin: 0,\n fontSize: 12,\n lineHeight: 1.6,\n color: 'var(--dsw-alias-state-error-primary)',\n}\n\nconst okStyle: CSSProperties = {\n margin: 0,\n fontSize: 12,\n lineHeight: 1.6,\n color: 'var(--dsw-alias-state-success-primary)',\n}\n\n/**\n * 把官方 Input 的默认几何(h32 / r8 / 字号 14)对齐到行内 sm 胶囊控件\n * (Button.sm:h28 / r14 / 字号 12),使路由键输入框与右侧下拉、删除按钮同高同形。\n * 建议弹层的包裹 span 由 Menu 注入为 inline 布局,这里展开成块级并撑满列宽,\n * 让弹层与输入框左缘对齐。通过 data-plugin-css 标记幂等注入,遵循宿主插件样式约定。\n */\nconst COMPACT_INPUT_CSS = [\n '.dsh-mrd-input-sm {',\n // 宿主无全局 border-box reset:content-box 下 width:100% 只是内容宽,\n // 叠加 padding/border 后总宽超出父容器 22px,溢出盖住右侧按钮。\n ' box-sizing: border-box;',\n ' width: 100%;',\n ' height: 28px;',\n ' border-radius: 14px;',\n ' padding: 0 10px;',\n '}',\n '.dsh-mrd-input-sm > input {',\n ' font-size: 12px;',\n ' line-height: 18px;',\n '}',\n '.dsh-mrd-suggest {',\n ' display: block;',\n ' width: 100%;',\n '}',\n].join('\\n')\n\nconst COMPACT_INPUT_STYLE_TAG = 'dsh-model-reasoning-defaults/input-sm'\n\n// 样式注入必须脱离 React 渲染树(模块级副作用):若以组件节点渲染,每次\n// 渲染的 DOM 幂等检查会让 React 把该节点当作\"不再渲染\"而卸载/重挂,\n// 菜单展开等重渲染期间样式短暂丢失,`.dsh-mrd-suggest` 回退为 Menu 默认的\n// inline-flex,输入框宽度塌缩(跟随宿主 tsdown.client.ts 的注入约定)。\nif (\n typeof document !== 'undefined'\n && document.querySelector('style[data-plugin-css=\"' + COMPACT_INPUT_STYLE_TAG + '\"]') === null\n) {\n const tag = document.createElement('style')\n tag.dataset.plugin = 'dsh-model-reasoning-defaults'\n tag.dataset.pluginCss = COMPACT_INPUT_STYLE_TAG\n tag.textContent = COMPACT_INPUT_CSS\n document.head.appendChild(tag)\n}\n\n/**\n * 把路由字典展开成按键排序的可编辑行。\n *\n * @param defaults - 路由字典。\n * @returns 稳定排序的行列表。\n */\nfunction rowsOf(defaults: Record<string, string>): RouteRow[] {\n return Object.entries(defaults)\n .map(([key, effort]) => ({ key, effort }))\n .sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0))\n}\n\n/**\n * 校验待保存的行集合并折叠回路由字典。\n *\n * @param rows - 当前编辑的行。\n * @returns 校验通过时返回字典;失败时返回错误消息。\n */\nfunction collapseRows(rows: RouteRow[]): Record<string, string> | { error: string } {\n const result: Record<string, string> = {}\n for (const row of rows) {\n const key = row.key.trim()\n // 空键行是编辑过程中的残渣:直接丢弃而不是拦住保存。\n if (key.length === 0) continue\n if (key in result) return { error: '存在重复路由键:' + key }\n result[key] = row.effort\n }\n return result\n}\n\n/**\n * 设置页「推理等级默认」编辑面板。\n *\n * 数据流:挂载时 describe 读一次(拿路由表、修订号、只读标记与建议键);\n * 保存时带 expectedRevision 做 update,陈旧编辑会被宿主拒绝而不是静默覆盖。\n * 外部改动(另一标签页、手工编辑 yaml)在本组件重新挂载时可见——设置壳每次\n * 打开都重新挂载 section,无需订阅失效事件。\n *\n * @param props - 无属主属性(close 由壳持有,本面板不离开设置页)。\n * @returns 面板节点树。\n */\nfunction ReasoningDefaultsSection(_props: { close: () => void }): ReactNode {\n const [rows, setRows] = useState<RouteRow[]>([])\n const [phase, setPhase] = useState<'loading' | 'ready' | 'unavailable'>('loading')\n const [writable, setWritable] = useState(true)\n const [saving, setSaving] = useState(false)\n const [feedback, setFeedback] = useState<{ kind: 'ok' | 'error'; text: string } | undefined>(undefined)\n const [suggestions, setSuggestions] = useState<string[]>([])\n const [openMenuIndex, setOpenMenuIndex] = useState<number | null>(null)\n const [suggestIndex, setSuggestIndex] = useState<number | null>(null)\n const revisionRef = useState<{ revision: number }>(() => ({ revision: 0 }))[0]\n\n useEffect(() => {\n let cancelled = false\n const load = async (): Promise<void> => {\n const api = currentApi\n if (api === undefined) {\n if (!cancelled) setPhase('unavailable')\n return\n }\n try {\n const response = await api.describe()\n if (cancelled) return\n if (!response.ok) {\n setPhase('unavailable')\n setFeedback({ kind: 'error', text: response.error.message })\n return\n }\n const own = findOwnNamespace(response.value.namespaces)\n if (own === undefined) {\n setPhase('unavailable')\n setFeedback({ kind: 'error', text: 'Host 未注册 ' + SETTINGS_NS + ' 命名空间,请确认插件已启用并刷新页面' })\n return\n }\n setRows(rowsOf(own.defaults))\n revisionRef.revision = own.revision\n setWritable(response.value.writable)\n setSuggestions(collectSuggestions(response.value.namespaces))\n setPhase('ready')\n } catch (error) {\n if (!cancelled) {\n setPhase('unavailable')\n setFeedback({ kind: 'error', text: error instanceof Error ? error.message : String(error) })\n }\n }\n }\n void load()\n return () => { cancelled = true }\n }, [revisionRef])\n\n const save = async (): Promise<void> => {\n const api = currentApi\n if (api === undefined || saving) return\n const collapsed = collapseRows(rows)\n if ('error' in collapsed) {\n setFeedback({ kind: 'error', text: collapsed.error })\n return\n }\n setSaving(true)\n setFeedback(undefined)\n try {\n // 必须走 replace 而非 update:update 是 merge patch,普通对象递归合并、\n // 省略键不表达删除,删掉的路由会在存储层原样保留并在回读时\"复活\";\n // replace 整段替换 user section,删除才能落盘。修订号语义两种写法一致。\n const response = await api.replace(SETTINGS_NS, { defaults: collapsed }, revisionRef.revision)\n if (!response.ok) {\n setFeedback({ kind: 'error', text: response.error.message })\n return\n }\n // 写回应答里带新修订号;再 describe 一次让行视图与存储严格一致(含 trim)。\n const reread = await api.describe()\n if (reread.ok) {\n const own = findOwnNamespace(reread.value.namespaces)\n if (own !== undefined) {\n setRows(rowsOf(own.defaults))\n revisionRef.revision = own.revision\n }\n }\n setFeedback({ kind: 'ok', text: '已保存,对新请求即时生效' })\n } catch (error) {\n setFeedback({ kind: 'error', text: error instanceof Error ? error.message : String(error) })\n } finally {\n setSaving(false)\n }\n }\n\n if (phase === 'loading') {\n return createElement('div', { style: sectionStyle }, createElement('p', { style: mutedStyle }, '加载推理等级配置…'))\n }\n\n if (phase === 'unavailable') {\n return createElement(\n 'div',\n { style: sectionStyle },\n createElement('p', { style: errorStyle }, '无法读取推理等级配置。'),\n feedback === undefined\n ? null\n : createElement('p', { style: feedback.kind === 'error' ? errorStyle : okStyle }, feedback.text),\n )\n }\n\n const children: ReactNode[] = [\n createElement('div', { key: 'title', style: titleStyle }, '推理等级默认'),\n createElement(\n 'p',\n { key: 'intro', style: mutedStyle },\n '请求未显式指定 reasoningEffort 时按此路由表补齐。匹配顺序:provider:model → provider:* → provider/* → provider → *:model → *。',\n ),\n ]\n\n if (!writable) {\n children.push(createElement('p', { key: 'readonly', style: mutedStyle }, '当前设置文档为只读,修改需在 Host 侧完成。'))\n }\n\n for (let index = 0; index < rows.length; index += 1) {\n const row = rows[index]\n const menuOpen = openMenuIndex === index\n const keySuggestions = suggestionMatches(row.key, suggestions)\n children.push(createElement(\n 'div',\n { key: 'row-' + index, style: rowStyle },\n createElement('div', { key: 'key', style: keyFieldStyle },\n // 建议弹层与等级下拉一样走 portal:设置壳的 .panel 裁剪 overflow,\n // 原地弹层会被裁掉或顶出面板(原生 datalist 更是完全不受控)。\n createElement(Menu, {\n key: 'key-suggest',\n className: 'dsh-mrd-suggest',\n open: suggestIndex === index && keySuggestions.length > 0,\n portal: true,\n dense: true,\n items: keySuggestions.map(candidate => ({ id: candidate, label: candidate })),\n onSelect: (candidate: string) => {\n const next = [...rows]\n next[index] = { ...row, key: candidate }\n setRows(next)\n setSuggestIndex(null)\n },\n onClose: () => { setSuggestIndex(null) },\n anchor: createElement(Input, {\n className: 'dsh-mrd-input-sm',\n value: row.key,\n placeholder: 'provider:model / provider:* / *',\n 'aria-label': '路由键',\n style: { width: '100%' },\n onFocus: () => { setSuggestIndex(index) },\n onChange: (event: ChangeEvent<HTMLInputElement>) => {\n const next = [...rows]\n next[index] = { ...row, key: event.target.value }\n setRows(next)\n setSuggestIndex(index)\n },\n }),\n }),\n ),\n createElement(Menu, {\n key: 'effort',\n open: menuOpen,\n onClose: () => { setOpenMenuIndex(null) },\n portal: true,\n dense: true,\n items: KNOWN_EFFORTS.map(level => ({ id: level, label: level })),\n selectedId: row.effort,\n onSelect: (id: string) => {\n const next = [...rows]\n next[index] = { ...row, effort: id }\n setRows(next)\n setOpenMenuIndex(null)\n },\n anchor: createElement(Button, {\n variant: 'outline',\n size: 'sm',\n 'aria-haspopup': 'menu',\n 'aria-expanded': menuOpen,\n onClick: () => { setOpenMenuIndex(menuOpen ? null : index) },\n }, row.effort, createElement(IconChevronDownOutline14)),\n }),\n createElement(Button, {\n key: 'remove',\n variant: 'ghost',\n size: 'sm',\n icon: createElement(IconTrashOutline16),\n 'aria-label': '删除路由 ' + row.key,\n title: '删除该路由',\n onClick: () => {\n setRows(rows.filter((_, i) => i !== index))\n setOpenMenuIndex(null)\n setSuggestIndex(null)\n },\n }, '删除'),\n ))\n }\n\n children.push(createElement(\n 'div',\n { key: 'actions', style: rowStyle },\n createElement(Button, {\n variant: 'outline',\n size: 'sm',\n icon: createElement(IconPlusOutline16),\n onClick: () => setRows([...rows, { key: '', effort: 'medium' }]),\n }, '添加路由'),\n createElement(Button, {\n variant: 'primary',\n size: 'sm',\n disabled: saving || !writable || rows.length === 0,\n onClick: () => { void save() },\n }, saving ? '保存中…' : '保存'),\n ))\n\n children.push(createElement(\n 'p',\n { key: 'hint', style: hintStyle },\n '已知等级:' + KNOWN_EFFORTS.join(' / ')\n + '。生效优先级:patch 层插件配置 > 此处 > Host 各 Provider 已声明的思考等级。'\n + '路由键支持 * 通配,聚焦输入框可查看已配置 Provider/Model 的建议。',\n ))\n\n if (feedback !== undefined) {\n children.push(createElement(\n 'p',\n { key: 'feedback', style: { ...(feedback.kind === 'error' ? errorStyle : okStyle) } },\n feedback.text,\n ))\n }\n\n return createElement('div', { style: sectionStyle }, children)\n}\n\n/**\n * 注册设置页编辑 section。\n *\n * slots.inject 已绑定当前 fiber 的生命周期,不需要再套一层 effect,\n * 注册和注销由同一个 slot owner 管理,不会留下嵌套 disposer。\n *\n * @param ctx - 提供槽位与连接服务的客户端上下文。\n */\nexport function apply(ctx: ClientContext): void {\n // 宿主 API Gateway 装配了 settings Remote 命名空间后,ctx.remote.settings 才可用;\n // inject 声明保证了装配顺序,此处直接引用。\n currentApi = ctx.remote.settings\n\n ctx.slots.inject(\n 'settings.section',\n () => ctx.slots.register({\n name: 'settings.section',\n id: SETTINGS_NS,\n order: 15,\n label: () => '推理等级默认',\n }, ReasoningDefaultsSection),\n )\n}\n"],"mappings":"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"}
@@ -26,7 +26,7 @@ export declare const inject: readonly ["slots", "remote", "remote.settings"];
26
26
  /** settings Remote 的读写方法面(宿主 API Gateway 经 Typert Remote 生成)。 */
27
27
  interface RemoteSettings {
28
28
  describe(): Promise<RemoteResult<SettingsDescribeValue>>;
29
- update(ns: string, patch: Record<string, unknown>, expectedRevision: number | undefined): Promise<RemoteResult<SettingsNamespaceView>>;
29
+ replace(ns: string, section: Record<string, unknown>, expectedRevision: number | undefined): Promise<RemoteResult<SettingsNamespaceView>>;
30
30
  }
31
31
  /** Typert Remote 统一应答形状。 */
32
32
  type RemoteResult<T> = {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAsBA,wDAAwD;AACxD,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,OAAO;QACf,kBAAkB,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE;gBAAE,KAAK,EAAE,MAAM,IAAI,CAAA;aAAE,CAAA;SAAE,CAAA;KAClF;CACF;AAED,sDAAsD;AACtD,UAAU,YAAY;IACpB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;IAC5D,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,IAAI,CAAA;CAC3D;AAQD,KAAK,aAAa,GAAG;IACnB,KAAK,EAAE,YAAY,CAAA;IACnB,MAAM,EAAE;QACN,QAAQ,EAAE,cAAc,CAAA;KACzB,CAAA;CACF,CAAA;AAED,wCAAwC;AACxC,eAAO,MAAM,MAAM,iDAAkD,CAAA;AAErE,iEAAiE;AACjE,UAAU,cAAc;IACtB,QAAQ,IAAI,OAAO,CAAC,YAAY,CAAC,qBAAqB,CAAC,CAAC,CAAA;IACxD,MAAM,CACJ,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,gBAAgB,EAAE,MAAM,GAAG,SAAS,GACnC,OAAO,CAAC,YAAY,CAAC,qBAAqB,CAAC,CAAC,CAAA;CAChD;AAED,4BAA4B;AAC5B,KAAK,YAAY,CAAC,CAAC,IACf;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GACtB;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAA;AAE5E,oCAAoC;AACpC,UAAU,qBAAqB;IAC7B,gBAAgB;IAChB,QAAQ,EAAE,OAAO,CAAA;IACjB,mBAAmB;IACnB,WAAW,EAAE,OAAO,CAAA;IACpB,mBAAmB;IACnB,UAAU,EAAE,qBAAqB,EAAE,CAAA;CACpC;AAED,mBAAmB;AACnB,UAAU,qBAAqB;IAC7B,aAAa;IACb,EAAE,EAAE,MAAM,CAAA;IACV,eAAe;IACf,KAAK,EAAE,OAAO,CAAA;IACd,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAA;CACjB;AAwcD;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAc9C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAsBA,wDAAwD;AACxD,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,OAAO;QACf,kBAAkB,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE;gBAAE,KAAK,EAAE,MAAM,IAAI,CAAA;aAAE,CAAA;SAAE,CAAA;KAClF;CACF;AAED,sDAAsD;AACtD,UAAU,YAAY;IACpB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;IAC5D,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,IAAI,CAAA;CAC3D;AAQD,KAAK,aAAa,GAAG;IACnB,KAAK,EAAE,YAAY,CAAA;IACnB,MAAM,EAAE;QACN,QAAQ,EAAE,cAAc,CAAA;KACzB,CAAA;CACF,CAAA;AAED,wCAAwC;AACxC,eAAO,MAAM,MAAM,iDAAkD,CAAA;AAErE,iEAAiE;AACjE,UAAU,cAAc;IACtB,QAAQ,IAAI,OAAO,CAAC,YAAY,CAAC,qBAAqB,CAAC,CAAC,CAAA;IACxD,OAAO,CACL,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,gBAAgB,EAAE,MAAM,GAAG,SAAS,GACnC,OAAO,CAAC,YAAY,CAAC,qBAAqB,CAAC,CAAC,CAAA;CAChD;AAED,4BAA4B;AAC5B,KAAK,YAAY,CAAC,CAAC,IACf;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GACtB;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAA;AAE5E,oCAAoC;AACpC,UAAU,qBAAqB;IAC7B,gBAAgB;IAChB,QAAQ,EAAE,OAAO,CAAA;IACjB,mBAAmB;IACnB,WAAW,EAAE,OAAO,CAAA;IACpB,mBAAmB;IACnB,UAAU,EAAE,qBAAqB,EAAE,CAAA;CACpC;AAED,mBAAmB;AACnB,UAAU,qBAAqB;IAC7B,aAAa;IACb,EAAE,EAAE,MAAM,CAAA;IACV,eAAe;IACf,KAAK,EAAE,OAAO,CAAA;IACd,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAA;CACjB;AA2cD;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAc9C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-model-reasoning-defaults",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "DSH (DeepSeek Harness) 插件:为每个 LLM 模型配置默认推理等级(reasoningEffort),并在请求进入底层调用链前按路由规则自动补齐",
5
5
  "keywords": [
6
6
  "dsh",