Skip to content

Commit be503ba

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 bebe01c commit be503ba

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
@@ -357,11 +357,11 @@ function M.initialize()
357357
end
358358

359359
function M.agent_plan()
360-
state.current_mode = 'plan'
360+
require('opencode.core').switch_to_mode('plan')
361361
end
362362

363363
function M.agent_build()
364-
state.current_mode = 'build'
364+
require('opencode.core').switch_to_mode('build')
365365
end
366366

367367
function M.select_agent()
@@ -373,7 +373,7 @@ function M.select_agent()
373373
return
374374
end
375375

376-
state.current_mode = selection
376+
require('opencode.core').switch_to_mode(selection)
377377
end)
378378
end
379379

@@ -389,7 +389,7 @@ function M.switch_mode()
389389
-- Calculate next index, wrapping around if necessary
390390
local next_index = (current_index % #modes) + 1
391391

392-
state.current_mode = modes[next_index]
392+
require('opencode.core').switch_to_mode(modes[next_index])
393393
end
394394

395395
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
@@ -254,6 +256,58 @@ local function on_opencode_server()
254256
state.current_permission = nil
255257
end
256258

259+
--- Switches the current mode to the specified agent.
260+
--- @param mode string The agent/mode to switch to
261+
--- @return boolean success Returns true if the mode was switched successfully, false otherwise
262+
function M.switch_to_mode(mode)
263+
if not mode or mode == '' then
264+
vim.notify('Mode cannot be empty', vim.log.levels.ERROR)
265+
return false
266+
end
267+
268+
local config_file = require('opencode.config_file')
269+
local available_agents = config_file.get_opencode_agents()
270+
271+
if not vim.tbl_contains(available_agents, mode) then
272+
vim.notify(
273+
string.format('Invalid mode "%s". Available modes: %s', mode, table.concat(available_agents, ', ')),
274+
vim.log.levels.ERROR
275+
)
276+
return false
277+
end
278+
279+
state.current_mode = mode
280+
ui.render_output()
281+
return true
282+
end
283+
284+
--- Ensure the current_mode is set using the config.default_mode or falling back to the first available agent.
285+
--- @return boolean success Returns true if current_mode is set
286+
function M.ensure_current_mode()
287+
if state.current_mode == nil then
288+
local config_file = require('opencode.config_file')
289+
local available_agents = config_file.get_opencode_agents()
290+
291+
if not available_agents or #available_agents == 0 then
292+
vim.notify('No available agents found', vim.log.levels.ERROR)
293+
return false
294+
end
295+
296+
local default_mode = config.default_mode
297+
298+
-- Try to use the configured default mode if it's available
299+
if default_mode and vim.tbl_contains(available_agents, default_mode) then
300+
state.current_mode = default_mode
301+
else
302+
-- Fallback to first available agent
303+
state.current_mode = available_agents[1]
304+
end
305+
306+
ui.render_output()
307+
end
308+
return true
309+
end
310+
257311
function M.setup()
258312
state.subscribe('opencode_server', on_opencode_server)
259313

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)