Skip to content

Commit f0f1e51

Browse files
authored
fix(core): implement proper configOptions for acp (anomalyco#21134)
1 parent 4712c18 commit f0f1e51

1 file changed

Lines changed: 84 additions & 0 deletions

File tree

packages/opencode/src/acp/agent.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ import {
2121
type Role,
2222
type SessionInfo,
2323
type SetSessionModelRequest,
24+
type SessionConfigOption,
25+
type SetSessionConfigOptionRequest,
26+
type SetSessionConfigOptionResponse,
2427
type SetSessionModeRequest,
2528
type SetSessionModeResponse,
2629
type ToolCallContent,
@@ -601,6 +604,7 @@ export namespace ACP {
601604

602605
return {
603606
sessionId,
607+
configOptions: load.configOptions,
604608
models: load.models,
605609
modes: load.modes,
606610
_meta: load._meta,
@@ -660,6 +664,11 @@ export namespace ACP {
660664
result.modes.currentModeId = lastUser.agent
661665
this.sessionManager.setMode(sessionId, lastUser.agent)
662666
}
667+
result.configOptions = buildConfigOptions({
668+
currentModelId: result.models.currentModelId,
669+
availableModels: result.models.availableModels,
670+
modes: result.modes,
671+
})
663672
}
664673

665674
for (const msg of messages ?? []) {
@@ -1266,6 +1275,11 @@ export namespace ACP {
12661275
availableModels,
12671276
},
12681277
modes,
1278+
configOptions: buildConfigOptions({
1279+
currentModelId: formatModelIdWithVariant(model, currentVariant, availableVariants, true),
1280+
availableModels,
1281+
modes,
1282+
}),
12691283
_meta: buildVariantMeta({
12701284
model,
12711285
variant: this.sessionManager.getVariant(sessionId),
@@ -1305,6 +1319,44 @@ export namespace ACP {
13051319
this.sessionManager.setMode(params.sessionId, params.modeId)
13061320
}
13071321

1322+
async setSessionConfigOption(params: SetSessionConfigOptionRequest): Promise<SetSessionConfigOptionResponse> {
1323+
const session = this.sessionManager.get(params.sessionId)
1324+
const providers = await this.sdk.config
1325+
.providers({ directory: session.cwd }, { throwOnError: true })
1326+
.then((x) => x.data!.providers)
1327+
const entries = sortProvidersByName(providers)
1328+
1329+
if (params.configId === "model") {
1330+
if (typeof params.value !== "string") throw RequestError.invalidParams("model value must be a string")
1331+
const selection = parseModelSelection(params.value, providers)
1332+
this.sessionManager.setModel(session.id, selection.model)
1333+
this.sessionManager.setVariant(session.id, selection.variant)
1334+
} else if (params.configId === "mode") {
1335+
if (typeof params.value !== "string") throw RequestError.invalidParams("mode value must be a string")
1336+
const availableModes = await this.loadAvailableModes(session.cwd)
1337+
if (!availableModes.some((mode) => mode.id === params.value)) {
1338+
throw RequestError.invalidParams(JSON.stringify({ error: `Mode not found: ${params.value}` }))
1339+
}
1340+
this.sessionManager.setMode(session.id, params.value)
1341+
} else {
1342+
throw RequestError.invalidParams(JSON.stringify({ error: `Unknown config option: ${params.configId}` }))
1343+
}
1344+
1345+
const updatedSession = this.sessionManager.get(session.id)
1346+
const model = updatedSession.model ?? (await defaultModel(this.config, session.cwd))
1347+
const availableVariants = modelVariantsFromProviders(entries, model)
1348+
const currentModelId = formatModelIdWithVariant(model, updatedSession.variant, availableVariants, true)
1349+
const availableModels = buildAvailableModels(entries, { includeVariants: true })
1350+
const modeState = await this.resolveModeState(session.cwd, session.id)
1351+
const modes = modeState.currentModeId
1352+
? { availableModes: modeState.availableModes, currentModeId: modeState.currentModeId }
1353+
: undefined
1354+
1355+
return {
1356+
configOptions: buildConfigOptions({ currentModelId, availableModels, modes }),
1357+
}
1358+
}
1359+
13081360
async prompt(params: PromptRequest) {
13091361
const sessionID = params.sessionId
13101362
const session = this.sessionManager.get(sessionID)
@@ -1760,4 +1812,36 @@ export namespace ACP {
17601812

17611813
return { model: parsed, variant: undefined }
17621814
}
1815+
1816+
function buildConfigOptions(input: {
1817+
currentModelId: string
1818+
availableModels: ModelOption[]
1819+
modes?: { availableModes: ModeOption[]; currentModeId: string } | undefined
1820+
}): SessionConfigOption[] {
1821+
const options: SessionConfigOption[] = [
1822+
{
1823+
id: "model",
1824+
name: "Model",
1825+
category: "model",
1826+
type: "select",
1827+
currentValue: input.currentModelId,
1828+
options: input.availableModels.map((m) => ({ value: m.modelId, name: m.name })),
1829+
},
1830+
]
1831+
if (input.modes) {
1832+
options.push({
1833+
id: "mode",
1834+
name: "Session Mode",
1835+
category: "mode",
1836+
type: "select",
1837+
currentValue: input.modes.currentModeId,
1838+
options: input.modes.availableModes.map((m) => ({
1839+
value: m.id,
1840+
name: m.name,
1841+
...(m.description ? { description: m.description } : {}),
1842+
})),
1843+
})
1844+
}
1845+
return options
1846+
}
17631847
}

0 commit comments

Comments
 (0)