diff --git a/lua/opencode/commands/handlers/agent.lua b/lua/opencode/commands/handlers/agent.lua index 01adc6c2..d6c8fe13 100644 --- a/lua/opencode/commands/handlers/agent.lua +++ b/lua/opencode/commands/handlers/agent.lua @@ -55,7 +55,7 @@ M.actions.switch_mode = Promise.async(function() local modes = config_file.get_opencode_agents():await() --[[@as string[] ]] local current_index = util.index_of(modes, state.store.get('current_mode')) - if current_index == -1 then + if current_index == nil then current_index = 0 end diff --git a/lua/opencode/config_file.lua b/lua/opencode/config_file.lua index 9038ea87..f0406385 100644 --- a/lua/opencode/config_file.lua +++ b/lua/opencode/config_file.lua @@ -51,16 +51,27 @@ M.get_workspace_snapshot_path = Promise.async(function() return home .. '/.local/share/opencode/snapshot/' .. project.id end) +local _providers_render_callback = false + ---@return Promise function M.get_opencode_providers() if not M.providers_promise then local state = require('opencode.state') M.providers_promise = state.api_client:list_providers() end - return M.providers_promise:catch(function(err) + local wrapped = M.providers_promise:catch(function(err) vim.notify('Error fetching Opencode providers: ' .. vim.inspect(err), vim.log.levels.ERROR) return nil end) + if not _providers_render_callback then + _providers_render_callback = true + wrapped:finally(function() + local ok, _ = pcall(function() + require('opencode.ui.topbar').render() + end) + end) + end + return wrapped end --- Get model information for a specific provider and model diff --git a/lua/opencode/state/renderer.lua b/lua/opencode/state/renderer.lua index 66b884fd..a2242b86 100644 --- a/lua/opencode/state/renderer.lua +++ b/lua/opencode/state/renderer.lua @@ -29,6 +29,9 @@ function M.update_pending_permissions(mutator) end ---@param cost number function M.set_cost(cost) + if not cost or cost <= 0 then + return + end return store.set('cost', cost) end @@ -42,7 +45,9 @@ end function M.set_stats(tokens_count, cost) return store.batch(function() store.set('tokens_count', tokens_count) - store.set('cost', cost) + if cost and cost > 0 then + store.set('cost', cost) + end end) end diff --git a/lua/opencode/ui/renderer/events.lua b/lua/opencode/ui/renderer/events.lua index 4270043b..4c38dfc9 100644 --- a/lua/opencode/ui/renderer/events.lua +++ b/lua/opencode/ui/renderer/events.lua @@ -350,8 +350,15 @@ function M.on_part_updated(properties, revert_index) end end - -- step-start / step-finish are bookkeeping only — nothing to render if part.type == 'step-start' or part.type == 'step-finish' then + if part.type == 'step-finish' and part.tokens then + local tokens = part.tokens + if tokens.input > 0 and part.cost and type(part.cost) == 'number' then + state.renderer.set_stats(tokens.input + tokens.output + tokens.cache.read + tokens.cache.write, part.cost) + elseif tokens.input > 0 then + state.renderer.set_tokens_count(tokens.input + tokens.output + tokens.cache.read + tokens.cache.write) + end + end return end diff --git a/lua/opencode/ui/topbar.lua b/lua/opencode/ui/topbar.lua index 4484ccc7..ad28b3ce 100644 --- a/lua/opencode/ui/topbar.lua +++ b/lua/opencode/ui/topbar.lua @@ -22,13 +22,22 @@ local function format_token_info() model_info = nil end local limit = state.tokens_count and model_info and model_info.limit and model_info.limit.context or 0 - table.insert(parts, util.format_number(state.tokens_count) or nil) + local formatted_count = util.format_number(state.tokens_count) + if formatted_count then + table.insert(parts, formatted_count) + end if limit > 0 then - table.insert(parts, util.format_percentage(state.tokens_count / limit) or nil) + local formatted_pct = util.format_percentage(state.tokens_count / limit) + if formatted_pct then + table.insert(parts, formatted_pct) + end end end - if config.ui.display_cost and state.cost then - table.insert(parts, util.format_cost(state.cost) or nil) + if config.ui.display_cost and state.cost and state.cost > 0 then + local formatted_cost = util.format_cost(state.cost) + if formatted_cost then + table.insert(parts, formatted_cost) + end end end @@ -37,21 +46,8 @@ local function format_token_info() return result end -local function create_winbar_text(description, token_info, win_width) - local left_content = '' - local right_content = token_info - - local desc_width = win_width - util.strdisplaywidth(left_content) - util.strdisplaywidth(right_content) - - local desc_formatted - if #description >= desc_width then - local ellipsis = '... ' - desc_formatted = description:sub(1, desc_width - #ellipsis) .. ellipsis - else - desc_formatted = description .. string.rep(' ', math.floor(desc_width - #description)) - end - - return left_content .. desc_formatted .. right_content +local function create_winbar_text(description, token_info, _) + return description .. '%=' .. token_info end local function get_session_desc()