Skip to content

Commit a4b397c

Browse files
guillaumeboehmsudo-tee
authored andcommitted
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 9f49d74 commit a4b397c

File tree

4 files changed

+72
-8
lines changed

4 files changed

+72
-8
lines changed

lua/opencode/api.lua

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -367,11 +367,11 @@ function M.initialize()
367367
end
368368

369369
function M.agent_plan()
370-
state.current_mode = 'plan'
370+
require('opencode.core').switch_to_mode('plan')
371371
end
372372

373373
function M.agent_build()
374-
state.current_mode = 'build'
374+
require('opencode.core').switch_to_mode('build')
375375
end
376376

377377
function M.select_agent()
@@ -383,7 +383,7 @@ function M.select_agent()
383383
return
384384
end
385385

386-
state.current_mode = selection
386+
require('opencode.core').switch_to_mode(selection)
387387
end)
388388
end
389389

@@ -399,7 +399,7 @@ function M.switch_mode()
399399
-- Calculate next index, wrapping around if necessary
400400
local next_index = (current_index % #modes) + 1
401401

402-
state.current_mode = modes[next_index]
402+
require('opencode.core').switch_to_mode(modes[next_index])
403403
end
404404

405405
function M.with_header(lines, show_welcome)

lua/opencode/config_file.lua

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,23 @@ function M.get_opencode_agents()
7777
end
7878
local agents = {}
7979
for agent, opts in pairs(cfg.agent or {}) do
80-
if opts.mode == 'primary' or opts.mode == 'all' then
80+
-- Only include agents that are enabled and have the right mode
81+
if opts.disable ~= true and (opts.mode == 'primary' or opts.mode == 'all') then
8182
table.insert(agents, agent)
8283
end
8384
end
84-
for _, mode in ipairs({ 'build', 'plan' }) do
85+
86+
-- Sort the agents before prepending the default agents
87+
table.sort(agents)
88+
89+
-- Only add build/plan as fallbacks if they're not explicitly disabled in config
90+
for _, mode in ipairs({ 'plan', 'build' }) do
8591
if not vim.tbl_contains(agents, mode) then
86-
table.insert(agents, mode)
92+
local mode_config = cfg.agent and cfg.agent[mode]
93+
-- Only add if not explicitly disabled or if no config exists (default behavior)
94+
if mode_config == nil or (mode_config.disable ~= true) then
95+
table.insert(agents, 1, mode)
96+
end
8797
end
8898
end
8999
return agents

lua/opencode/core.lua

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

48+
M.ensure_current_mode()
49+
4850
local are_windows_closed = state.windows == nil
4951

5052
if are_windows_closed then
@@ -272,6 +274,58 @@ local function on_opencode_server()
272274
state.current_permission = nil
273275
end
274276

277+
--- Switches the current mode to the specified agent.
278+
--- @param mode string The agent/mode to switch to
279+
--- @return boolean success Returns true if the mode was switched successfully, false otherwise
280+
function M.switch_to_mode(mode)
281+
if not mode or mode == '' then
282+
vim.notify('Mode cannot be empty', vim.log.levels.ERROR)
283+
return false
284+
end
285+
286+
local config_file = require('opencode.config_file')
287+
local available_agents = config_file.get_opencode_agents()
288+
289+
if not vim.tbl_contains(available_agents, mode) then
290+
vim.notify(
291+
string.format('Invalid mode "%s". Available modes: %s', mode, table.concat(available_agents, ', ')),
292+
vim.log.levels.ERROR
293+
)
294+
return false
295+
end
296+
297+
state.current_mode = mode
298+
ui.render_output()
299+
return true
300+
end
301+
302+
--- Ensure the current_mode is set using the config.default_mode or falling back to the first available agent.
303+
--- @return boolean success Returns true if current_mode is set
304+
function M.ensure_current_mode()
305+
if state.current_mode == nil then
306+
local config_file = require('opencode.config_file')
307+
local available_agents = config_file.get_opencode_agents()
308+
309+
if not available_agents or #available_agents == 0 then
310+
vim.notify('No available agents found', vim.log.levels.ERROR)
311+
return false
312+
end
313+
314+
local default_mode = config.default_mode
315+
316+
-- Try to use the configured default mode if it's available
317+
if default_mode and vim.tbl_contains(available_agents, default_mode) then
318+
state.current_mode = default_mode
319+
else
320+
-- Fallback to first available agent
321+
state.current_mode = available_agents[1]
322+
end
323+
324+
ui.render_output()
325+
end
326+
return true
327+
end
328+
275329
function M.setup()
276330
state.subscribe('opencode_server', on_opencode_server)
277331

lua/opencode/state.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ local _state = {
5353
last_output_window_position = nil,
5454
last_code_win_before_opencode = nil,
5555
display_route = nil,
56-
current_mode = config.default_mode,
56+
current_mode = nil,
5757
last_output = 0,
5858
-- context
5959
last_sent_context = nil,

0 commit comments

Comments
 (0)