fix: apply deployment default preset to new sessions (stale deleted model)

This commit is contained in:
Aisland
2026-08-21 22:30:55 +08:00
parent 5905cc44ef
commit 874ee5f7be
4 changed files with 51 additions and 1 deletions
+24
View File
@@ -307,6 +307,27 @@ const registryStore: { ids: string[]; listeners: Set<() => void> } = { ids: [],
/** 自定义窗口 → 宿主会话桥(apply 时注入;不可用时 CustomPane 降级提示) */
let sessionBridge: { sessions: any; conversation: any; list: any; workspaces: any } | null = null
/** 宿主 API 客户端(apply 时从 connection 服务取;agentPresets 用于修复新会话继承已删预设的 bug) */
let presetApi: { agentPresets?: any } | null = null
/** 新会话显式应用「部署默认预设」:宿主新会话座位同款逻辑(api.agentPresets.select,仅对 blank 会话生效)。
* 修复:用户删掉默认模型后,新建会话继承到失效预设,prompt 报 model-unavailable 导致窗口建不出来。 */
async function ensureSessionPreset(sessionId: string): Promise<void> {
const api = presetApi?.agentPresets
if (!api || typeof api.list !== 'function' || typeof api.select !== 'function') return
try {
const listRes = await api.list({})
const presets = listRes?.result?.ok ? listRes?.result?.value?.presets : null
if (!Array.isArray(presets) || presets.length === 0) return
const fallback = presets.find((p: any) => p?.isDefault)?.id ?? presets[0]?.id
if (!fallback) return
const selRes = await api.select({ sessionId, agentPreset: fallback })
if (selRes?.result?.ok) {
try { sessionBridge?.sessions?.noteAgentPreset?.(sessionId, fallback) } catch {}
}
} catch { /* 修复失败不阻断主流程,错误仍按原路径提示 */ }
}
/** 控制室(工作台自己)项目:固定 id、固定排项目列表第一位、不可删除 */
const CONSOLE_ID = 'wt-console'
const CONSOLE_ICON = '🖥️'
@@ -640,6 +661,7 @@ export async function createCustomSession(projectId: string, projectName: string
if (workspaceId) createOpts = { workspaceId }
else if (folder) createOpts = { cwd: folder }
const sessionId = await b.sessions.create(createOpts)
await ensureSessionPreset(sessionId) // 新会话应用部署默认预设(修复继承已删模型 → model-unavailable)
markPluginSessionOpen(sessionId) // 插件发起的切换:不触发「切会话关项目」联动
try { await b.sessions.open?.(sessionId) } catch {}
await promptIntoSession(sessionId, text)
@@ -1432,6 +1454,7 @@ function buildCustomLayoutPrompt(req: string): string {
if (workspaceId) createOpts = { workspaceId }
else if (folder) createOpts = { cwd: folder }
const sessionId = await b.sessions.create(createOpts)
await ensureSessionPreset(sessionId) // 同样修复:管理对话新建后首次发消息不再继承已删模型
markPluginSessionOpen(sessionId)
persistProjects((prev) => ({ ...prev, bindings: { ...prev.bindings, [CONSOLE_ID]: sessionId } }))
setConsoleBind(null)
@@ -2680,6 +2703,7 @@ export const inject = ['slots', 'locale', 'sessions', 'conversation', 'workspace
export function apply(ctx: any) {
// 自定义窗口 → 宿主会话桥:保存 sessions/conversation/list 服务引用(模块级)
sessionBridge = { sessions: ctx.sessions ?? null, conversation: ctx.conversation ?? null, list: ctx.sessions?.list ?? null, workspaces: ctx.workspaces ?? null }
try { presetApi = ctx.get?.('connection')?.api ?? null } catch { presetApi = null }
try { (window as any).__dshOpenSession = (id: string) => ctx.sessions?.open?.(id); (window as any).__dshSessions = ctx.sessions; (window as any).__dshPromptIntoSession = (id: string, text: string) => promptIntoSession(id, text); (window as any).__dshWorkspaces = ctx.workspaces; (window as any).__dshBuildWindowTaskText = buildWindowTaskText; (window as any).__dshSyncSessionScope = () => syncSessionScope(sessionBridge?.list) } catch {}
@@ -1430,3 +1430,17 @@
100% .01),处处非零、软肩过渡,不再有整齐边线;浅色主题对应 .1/.3/.55/.3/.1。
- 验证:构建通过;functional-diag 全 20 STEP ERROR_COUNT: 0。
- 备注:纯客户端改动,F5 即生效。
## 补记(第十七轮:修复新会话继承已删模型导致窗口建不出来)
- 事故:用户删掉 OpenAI GPT 默认模型后,自定义窗口「新建」流程创建会话继承到失效预设,
prompt 报 session.prompt: model-unavailable: no adapter serves provider "openai",
窗口无法建立。
- 侦察(只读):宿主 ui-agent-preset 插件的新会话座位用 api.agentPresets.list/select
(select 仅对 blank 会话生效);创建出的新会话是 blank → 可直接应用部署默认预设。
- 实现:apply 里从 ctx.get('connection').api 捕获 presetApi;新增 ensureSessionPreset
(list 取 presets → 默认 isDefault ?? 首个 → select 应用到新会话 → noteAgentPreset 同步
列表镜像;失败静默不阻断);createCustomSession 与 bindConsoleNew 两处 create 后调用。
- 验证(probe-batch16 阶段3 扩展):新建会话 agentPreset='standard'(部署默认预设已应用)✓;
functional-diag 全 20 STEP ERROR_COUNT: 0。
- 备注:纯客户端改动,F5 即生效;未启用 agentPresets 的宿主自动跳过(无行为变化)。
+7
View File
@@ -329,6 +329,13 @@ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
var saved2 = JSON.parse(localStorage.getItem('dsh.worktable.projects.v1'));
out.newBindingSet = !!saved2.bindings['wt-console'];
out.newBindingDiffers = saved2.bindings['wt-console'] !== undefined;
// 预设修复验证:新建会话应被应用「部署默认预设」(agentPreset 非空)
var newSid = saved2.bindings['wt-console'];
try {
var snap3 = window.__dshSessions && window.__dshSessions.list ? window.__dshSessions.list.getSnapshot() : null;
var nrow = snap3 && snap3.byId ? snap3.byId[newSid] : null;
out.newSessionAgentPreset = nrow && nrow.agentPreset ? nrow.agentPreset : (nrow ? '(none)' : '(missing)');
} catch (e) { out.newSessionAgentPreset = 'err:' + String(e); }
// 主题:三选一开关 + data-wt-theme 落定 + 持久化
var con = vis('.dsh-wt_console');
out.themeAttr0 = con ? con.getAttribute('data-wt-theme') : null;
+6 -1
View File
@@ -31,6 +31,11 @@ node --check lib/index.js
- **预设追加规则**:新布局预设只允许追加到 `PRESET_DEFS` 末尾(选择器里的「+自定义」磁贴
永远是最后一个);字段 leftCount/topCount/contentCount/chatFull/topHeightDefault/topHeightRatio,
聊天窗恒在右侧;缩略图在 presetThumb() 加分支。
- **新会话预设修复**:新建会话(createCustomSession / bindConsoleNew)创建后调用
ensureSessionPreset——用宿主 api.agentPresets.list/select 显式应用「部署默认预设」
(isDefault ?? 首个;select 仅对 blank 会话生效),修复用户删掉默认模型后新会话继承
失效预设、prompt 报 model-unavailable 建不出窗口的问题;失败静默、无 agentPresets
API 的宿主自动跳过。
- **对话绑定**:projects.v1.bindings = { 项目id → 会话id };打开项目时引擎自动
sessions.open(绑定会话)(openSplit / DOM 桥两处入口);未绑定/解绑 = 不切换。
- **项目×对话联动**:打开项目记录「打开前会话」(projectAttachRef.sessionId);项目打开期间切到
@@ -108,7 +113,7 @@ node --check lib/index.js
2×边长 1.4,实测 236px:名字 20/状态 22/预览 8.5 四行截断);标题下横向分隔线;无子代理
徽章、无 💬 跳转按钮;网格最后一位恒为「创建卡片」(虚线+)→ openAddPanel;入口卡无描边。
- 背景:--wt-bg 深色 #0a0d13 + 30px 浅色井字格线(--wt-grid .045/.07,两条
linear-gradient),工作台/蓝图质感;玻璃贴片半透明底(暗 .18/浅 .28)+ backdrop blur 4px。
linear-gradient),工作台/蓝图质感;玻璃贴片半透明底(暗 .24/浅 .34,无磨砂模糊)。
- 顶部标题克制:控制室页只保留侧栏入口卡一个「控制室」——分栏标题栏对 wt-console
不渲染 title(保留 ⇄/✕)、PaneBody singleConsole 不渲染标签栏、ConsolePane 头只留
主题开关(右对齐)。