oc mini v2 (#38278)

This commit is contained in:
Simon Klee 2026-07-22 11:50:21 +02:00 committed by GitHub
commit 58d18be590
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 178 additions and 12 deletions

View file

@ -115,6 +115,7 @@ type RuntimeState = {
shown: boolean
aborting: boolean
model: RunInput["model"]
defaultModel: RunInput["model"]
providers: RunProvider[]
variants: string[]
activeVariant: string | undefined
@ -212,6 +213,7 @@ async function runInteractiveRuntime(input: RunRuntimeInput, deps: RunRuntimeDep
shown: !session.first,
aborting: false,
model: ctx.model ?? session.model,
defaultModel: undefined,
providers: [],
variants: [],
activeVariant: resolveVariant(ctx.variant, session.variant, savedVariant, []),
@ -286,17 +288,19 @@ async function runInteractiveRuntime(input: RunRuntimeInput, deps: RunRuntimeDep
await settleForm(next.sessionID, next.formID)
},
onCycleVariant: () => {
if (!state.model || state.variants.length === 0) {
const model = state.model ?? state.defaultModel
if (!model || state.variants.length === 0) {
return {
status: "no variants available",
}
}
if (!state.model) state.model = model
state.activeVariant = cycleVariant(state.activeVariant, state.variants)
void input.host.preferences.saveVariant(state.model, state.activeVariant)
void input.host.preferences.saveVariant(model, state.activeVariant)
return {
status: state.activeVariant ? `variant ${state.activeVariant}` : "variant default",
modelLabel: formatModelLabel(state.model, state.activeVariant, state.providers),
modelLabel: formatModelLabel(model, state.activeVariant, state.providers),
variant: state.activeVariant,
}
},
@ -335,7 +339,8 @@ async function runInteractiveRuntime(input: RunRuntimeInput, deps: RunRuntimeDep
}
},
onVariantSelect: async (variant) => {
if (!state.model || state.variants.length === 0) {
const model = state.model ?? state.defaultModel
if (!model || state.variants.length === 0) {
return {
status: "no variants available",
}
@ -347,11 +352,12 @@ async function runInteractiveRuntime(input: RunRuntimeInput, deps: RunRuntimeDep
}
}
if (!state.model) state.model = model
state.activeVariant = variant
void input.host.preferences.saveVariant(state.model, state.activeVariant)
void input.host.preferences.saveVariant(model, state.activeVariant)
return {
status: state.activeVariant ? `variant ${state.activeVariant}` : "variant default",
modelLabel: formatModelLabel(state.model, state.activeVariant, state.providers),
modelLabel: formatModelLabel(model, state.activeVariant, state.providers),
variant: state.activeVariant,
variants: state.variants,
}
@ -602,7 +608,8 @@ async function runInteractiveRuntime(input: RunRuntimeInput, deps: RunRuntimeDep
) {
if (!currentClient(attempt)) return
state.providers = info.providers
state.variants = variantsFor(state.providers, state.model)
const model = state.model ?? state.defaultModel
state.variants = variantsFor(state.providers, model)
state.activeVariant = boot
? resolveVariant(ctx.variant, current, saved, state.variants)
: current && !state.variants.includes(current)
@ -611,11 +618,11 @@ async function runInteractiveRuntime(input: RunRuntimeInput, deps: RunRuntimeDep
if (footer.isClosed) return
footer.event({ type: "models", providers: info.providers })
footer.event({ type: "variants", variants: state.variants, current: state.activeVariant })
if (state.model)
if (model)
footer.event({
type: "model",
model: formatModelLabel(state.model, state.activeVariant, state.providers),
selection: state.model,
model: formatModelLabel(model, state.activeVariant, state.providers),
selection: model,
})
}
@ -627,6 +634,50 @@ async function runInteractiveRuntime(input: RunRuntimeInput, deps: RunRuntimeDep
task: Promise<void>
}
| undefined
let defaultModelLoad: Promise<void> | undefined
let defaultModelQueued = false
const loadDefaultModel = (attempt: ClientAttempt) => {
if (state.model || !currentClient(attempt)) return
if (defaultModelLoad) {
defaultModelQueued = true
return
}
defaultModelQueued = false
defaultModelLoad = attempt.sdk.model
.default(
{
location: {
directory: state.location.directory,
workspace: state.location.workspaceID,
},
},
{ signal: attempt.signal },
)
.then(async (result) => {
if (!result.data || state.model || !currentClient(attempt)) return
const model = { providerID: result.data.providerID, modelID: result.data.id }
const changed =
state.defaultModel?.providerID !== model.providerID || state.defaultModel.modelID !== model.modelID
const saved = changed ? await input.host.preferences.resolveVariant(model) : undefined
if (state.model || !currentClient(attempt)) return
state.defaultModel = model
state.variants = variantsFor(state.providers, model)
if (changed)
state.activeVariant = resolveVariant(ctx.variant, state.activeVariant, saved, state.variants)
if (state.activeVariant) state.model = model
footer.event({ type: "variants", variants: state.variants, current: state.activeVariant })
footer.event({
type: "model",
model: formatModelLabel(model, state.activeVariant, state.providers),
selection: model,
})
})
.catch(() => {})
.finally(() => {
defaultModelLoad = undefined
if (defaultModelQueued) loadDefaultModel(clientAttempt())
})
}
const requestCatalogRefresh = (signal?: AbortSignal): Promise<void> => {
const attempt = clientAttempt(signal)
if (!currentClient(attempt)) return Promise.resolve()
@ -658,6 +709,7 @@ async function runInteractiveRuntime(input: RunRuntimeInput, deps: RunRuntimeDep
if (!currentClient(attempt)) return
if (catalog) applyCatalog(catalog, attempt)
if (info) applyModelInfo(info, state.activeVariant, attempt)
loadDefaultModel(attempt)
}
})()
refresh.task = task

View file

@ -380,7 +380,19 @@ async function resolveSelectedModel(
.then((response) => response.model)
if (session) return { ...session, variant: next.variant }
const fallback = await sdk.model.default(undefined, { signal: next.signal }).then((response) => response.data)
const fallback = await sdk.model
.default(
input.location
? {
location: {
directory: input.location.directory,
workspace: input.location.workspaceID,
},
}
: undefined,
{ signal: next.signal },
)
.then((response) => response.data)
if (!fallback) return
return { providerID: fallback.providerID, id: fallback.id, variant: next.variant }
}