Skip to content

Commit 54e8308

Browse files
fix: Respect user set default_mode and improve agent management
- The default_mode option was not being respected when setting the state current_mode. The current_mode is now set when first opening the opencode window. - The mode switching is now wrapped in a "switch_to_mode" function to ensure the mode exists in the available agents for more control. - The build and plan agents were added to the available agents even if explicitly disabled in the opencode config -> leading to a hang when sending messages to opencode. They are now prepended if they are not disabled. - The agent list was always randomly returned, it is now sorted before using it.
1 parent 0f2d1e5 commit 54e8308

4 files changed

Lines changed: 72 additions & 8 deletions

File tree

lua/opencode/api.lua

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -350,12 +350,12 @@ function M.initialize()
350350
end
351351

352352
function M.agent_plan()
353-
state.current_mode = 'plan'
353+
require('opencode.core').switch_to_mode('plan')
354354
require('opencode.ui.topbar').render()
355355
end
356356

357357
function M.agent_build()
358-
state.current_mode = 'build'
358+
require('opencode.core').switch_to_mode('build')
359359
require('opencode.ui.topbar').render()
360360
end
361361

@@ -368,7 +368,7 @@ function M.select_agent()
368368
return
369369
end
370370

371-
state.current_mode = selection
371+
require('opencode.core').switch_to_mode(selection)
372372
require('opencode.ui.topbar').render()
373373
end)
374374
end
@@ -385,7 +385,7 @@ function M.switch_mode()
385385
-- Calculate next index, wrapping around if necessary
386386
local next_index = (current_index % #modes) + 1
387387

388-
state.current_mode = modes[next_index]
388+
require('opencode.core').switch_to_mode(modes[next_index])
389389
require('opencode.ui.topbar').render()
390390
end
391391

lua/opencode/config_file.lua

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,23 @@ function M.get_opencode_agents()
5151
end
5252
local agents = {}
5353
for agent, opts in pairs(cfg.agent or {}) do
54-
if opts.mode == 'primary' or opts.mode == 'all' then
54+
-- Only include agents that are enabled and have the right mode
55+
if opts.disable ~= true and (opts.mode == 'primary' or opts.mode == 'all') then
5556
table.insert(agents, agent)
5657
end
5758
end
58-
for _, mode in ipairs({ 'build', 'plan' }) do
59+
60+
-- Sort the agents before prepending the default agents
61+
table.sort(agents)
62+
63+
-- Only add build/plan as fallbacks if they're not explicitly disabled in config
64+
for _, mode in ipairs({ 'plan', 'build' }) do
5965
if not vim.tbl_contains(agents, mode) then
60-
table.insert(agents, mode)
66+
local mode_config = cfg.agent and cfg.agent[mode]
67+
-- Only add if not explicitly disabled or if no config exists (default behavior)
68+
if mode_config == nil or (mode_config.disable ~= true) then
69+
table.insert(agents, 1, mode)
70+
end
6171
end
6272
end
6373
return agents

lua/opencode/core.lua

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ function M.open(opts)
4444
state.opencode_server_job = server_job.ensure_server() --[[@as OpencodeServer]]
4545
end
4646

47+
M.ensure_current_mode()
48+
4749
if not M.opencode_ok() then
4850
return
4951
end
@@ -226,6 +228,58 @@ function M.opencode_ok()
226228
return true
227229
end
228230

231+
--- Switches the current mode to the specified agent.
232+
--- @param mode string The agent/mode to switch to
233+
--- @return boolean success Returns true if the mode was switched successfully, false otherwise
234+
function M.switch_to_mode(mode)
235+
if not mode or mode == '' then
236+
vim.notify('Mode cannot be empty', vim.log.levels.ERROR)
237+
return false
238+
end
239+
240+
local config_file = require('opencode.config_file')
241+
local available_agents = config_file.get_opencode_agents()
242+
243+
if not vim.tbl_contains(available_agents, mode) then
244+
vim.notify(
245+
string.format('Invalid mode "%s". Available modes: %s', mode, table.concat(available_agents, ', ')),
246+
vim.log.levels.ERROR
247+
)
248+
return false
249+
end
250+
251+
state.current_mode = mode
252+
ui.render_output()
253+
return true
254+
end
255+
256+
--- Ensure the current_mode is set using the config.default_mode or falling back to the first available agent.
257+
--- @return boolean success Returns true if current_mode is set
258+
function M.ensure_current_mode()
259+
if state.current_mode == nil then
260+
local config_file = require('opencode.config_file')
261+
local available_agents = config_file.get_opencode_agents()
262+
263+
if not available_agents or #available_agents == 0 then
264+
vim.notify('No available agents found', vim.log.levels.ERROR)
265+
return false
266+
end
267+
268+
local default_mode = config.default_mode
269+
270+
-- Try to use the configured default mode if it's available
271+
if default_mode and vim.tbl_contains(available_agents, default_mode) then
272+
state.current_mode = default_mode
273+
else
274+
-- Fallback to first available agent
275+
state.current_mode = available_agents[1]
276+
end
277+
278+
ui.render_output()
279+
end
280+
return true
281+
end
282+
229283
function M.setup()
230284
local OpencodeApiClient = require('opencode.api_client')
231285
state.api_client = OpencodeApiClient.new()

lua/opencode/state.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ local _state = {
5050
last_output_window_position = nil,
5151
last_code_win_before_opencode = nil,
5252
display_route = nil,
53-
current_mode = config.default_mode,
53+
current_mode = nil,
5454
last_output = 0,
5555
-- context
5656
last_sent_context = nil,

0 commit comments

Comments
 (0)