Improve session defaults and onboarding UI

This commit is contained in:
Shantur Rathore
2025-11-07 21:22:46 +00:00
parent 7193103646
commit 5483932196
10 changed files with 254 additions and 119 deletions

View File

@@ -1,10 +1,21 @@
import { createSignal, onMount } from "solid-js"
import { storage, type ConfigData } from "../lib/storage"
export interface ModelPreference {
providerId: string
modelId: string
}
export interface AgentModelSelections {
[instanceId: string]: Record<string, ModelPreference>
}
export interface Preferences {
showThinkingBlocks: boolean
lastUsedBinary?: string
environmentVariables?: Record<string, string>
modelRecents?: ModelPreference[]
agentModelSelections?: AgentModelSelections
}
export interface OpenCodeBinary {
@@ -19,9 +30,12 @@ export interface RecentFolder {
}
const MAX_RECENT_FOLDERS = 10
const MAX_RECENT_MODELS = 5
const defaultPreferences: Preferences = {
showThinkingBlocks: false,
modelRecents: [],
agentModelSelections: {},
}
const [preferences, setPreferences] = createSignal<Preferences>(defaultPreferences)
@@ -127,6 +141,37 @@ function removeEnvironmentVariable(key: string): void {
updateEnvironmentVariables(rest)
}
function addRecentModelPreference(model: ModelPreference): void {
if (!model.providerId || !model.modelId) return
const recents = preferences().modelRecents ?? []
const filtered = recents.filter((item) => item.providerId !== model.providerId || item.modelId !== model.modelId)
const updated = [model, ...filtered].slice(0, MAX_RECENT_MODELS)
updatePreferences({ modelRecents: updated })
}
function setAgentModelPreference(instanceId: string, agent: string, model: ModelPreference): void {
if (!instanceId || !agent || !model.providerId || !model.modelId) return
const selections = preferences().agentModelSelections ?? {}
const instanceSelections = selections[instanceId] ?? {}
const existing = instanceSelections[agent]
if (existing && existing.providerId === model.providerId && existing.modelId === model.modelId) {
return
}
updatePreferences({
agentModelSelections: {
...selections,
[instanceId]: {
...instanceSelections,
[agent]: model,
},
},
})
}
function getAgentModelPreference(instanceId: string, agent: string): ModelPreference | undefined {
return preferences().agentModelSelections?.[instanceId]?.[agent]
}
// Load config on mount and listen for changes from other instances
onMount(() => {
loadConfig()
@@ -154,4 +199,7 @@ export {
updateEnvironmentVariables,
addEnvironmentVariable,
removeEnvironmentVariable,
addRecentModelPreference,
setAgentModelPreference,
getAgentModelPreference,
}

View File

@@ -6,7 +6,7 @@ import { instances } from "./instances"
import { sseManager } from "../lib/sse-manager"
import { decodeHtmlEntities } from "../lib/markdown"
import { preferences } from "./preferences"
import { preferences, addRecentModelPreference, getAgentModelPreference, setAgentModelPreference } from "./preferences"
interface SessionInfo {
tokens: number
@@ -330,6 +330,28 @@ async function fetchSessions(instanceId: string): Promise<void> {
}
}
function isModelValid(
instanceId: string,
model?: { providerId: string; modelId: string } | null,
): model is { providerId: string; modelId: string } {
if (!model?.providerId || !model.modelId) return false
const instanceProviders = providers().get(instanceId) || []
const provider = instanceProviders.find((p) => p.id === model.providerId)
if (!provider) return false
return provider.models.some((item) => item.id === model.modelId)
}
function getRecentModelPreferenceForInstance(
instanceId: string,
): { providerId: string; modelId: string } | undefined {
const recents = preferences().modelRecents ?? []
for (const item of recents) {
if (isModelValid(instanceId, item)) {
return item
}
}
}
async function getDefaultModel(
instanceId: string,
agentName?: string,
@@ -337,9 +359,16 @@ async function getDefaultModel(
const instanceProviders = providers().get(instanceId) || []
const instanceAgents = agents().get(instanceId) || []
if (agentName) {
const stored = getAgentModelPreference(instanceId, agentName)
if (isModelValid(instanceId, stored)) {
return stored
}
}
if (agentName) {
const agent = instanceAgents.find((a) => a.name === agentName)
if (agent?.model?.providerId && agent.model.modelId) {
if (agent && agent.model && isModelValid(instanceId, agent.model)) {
return {
providerId: agent.model.providerId,
modelId: agent.model.modelId,
@@ -347,25 +376,30 @@ async function getDefaultModel(
}
}
const anthropicProvider = instanceProviders.find((p) => p.id === "anthropic")
if (anthropicProvider) {
const defaultModelId = anthropicProvider.defaultModelId || anthropicProvider.models[0]?.id
if (defaultModelId) {
return {
providerId: "anthropic",
modelId: defaultModelId,
const recent = getRecentModelPreferenceForInstance(instanceId)
if (recent) {
return recent
}
for (const provider of instanceProviders) {
if (provider.defaultModelId) {
const model = provider.models.find((m) => m.id === provider.defaultModelId)
if (model) {
return {
providerId: provider.id,
modelId: model.id,
}
}
}
}
if (instanceProviders.length > 0) {
const firstProvider = instanceProviders[0]
const defaultModelId = firstProvider.defaultModelId || firstProvider.models[0]?.id
if (defaultModelId) {
const firstModel = firstProvider.models[0]
if (firstModel) {
return {
providerId: firstProvider.id,
modelId: defaultModelId,
modelId: firstModel.id,
}
}
}
@@ -469,6 +503,10 @@ async function createSession(instanceId: string, agent?: string): Promise<Sessio
const defaultModel = await getDefaultModel(instanceId, selectedAgent)
if (selectedAgent && isModelValid(instanceId, defaultModel)) {
setAgentModelPreference(instanceId, selectedAgent, defaultModel)
}
setLoading((prev) => {
const next = { ...prev }
next.creatingSession.set(instanceId, true)
@@ -1457,16 +1495,27 @@ async function updateSessionAgent(instanceId: string, sessionId: string, agent:
throw new Error("Session not found")
}
const nextModel = await getDefaultModel(instanceId, agent)
const shouldApplyModel = isModelValid(instanceId, nextModel)
setSessions((prev) => {
const next = new Map(prev)
const instanceSessions = new Map(prev.get(instanceId))
const session = instanceSessions.get(sessionId)
if (session) {
instanceSessions.set(sessionId, { ...session, agent })
next.set(instanceId, instanceSessions)
const map = new Map(prev.get(instanceId))
const current = map.get(sessionId)
if (current) {
map.set(sessionId, {
...current,
agent,
model: shouldApplyModel ? nextModel : current.model,
})
next.set(instanceId, map)
}
return next
})
if (agent && shouldApplyModel) {
setAgentModelPreference(instanceId, agent, nextModel)
}
}
async function updateSessionModel(
@@ -1480,16 +1529,28 @@ async function updateSessionModel(
throw new Error("Session not found")
}
if (!isModelValid(instanceId, model)) {
console.warn("Invalid model selection", model)
return
}
const currentAgent = session.agent
setSessions((prev) => {
const next = new Map(prev)
const instanceSessions = new Map(prev.get(instanceId))
const session = instanceSessions.get(sessionId)
if (session) {
instanceSessions.set(sessionId, { ...session, model })
next.set(instanceId, instanceSessions)
const map = new Map(prev.get(instanceId))
const existing = map.get(sessionId)
if (existing) {
map.set(sessionId, { ...existing, model })
next.set(instanceId, map)
}
return next
})
if (currentAgent) {
setAgentModelPreference(instanceId, currentAgent, model)
}
addRecentModelPreference(model)
}
function handleSessionCompacted(instanceId: string, event: any): void {