Improve session defaults and onboarding UI
This commit is contained in:
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user