diff --git a/lua/opencode/services/session_runtime.lua b/lua/opencode/services/session_runtime.lua index 8c439100..9fa3948b 100644 --- a/lua/opencode/services/session_runtime.lua +++ b/lua/opencode/services/session_runtime.lua @@ -241,8 +241,10 @@ end ---@param opts? SendMessageOpts M.cancel = Promise.async(function() - if state.active_session and state.jobs.is_running() then - vim.g.opencode_abort_count = (vim.g.opencode_abort_count or 0) + 1 + if state.active_session then + if state.jobs.is_running() then + vim.g.opencode_abort_count = (vim.g.opencode_abort_count or 0) + 1 + end local permissions = state.pending_permissions or {} if #permissions > 0 and state.api_client then diff --git a/tests/unit/services_session_runtime_spec.lua b/tests/unit/services_session_runtime_spec.lua index 663156f7..11f3aa33 100644 --- a/tests/unit/services_session_runtime_spec.lua +++ b/tests/unit/services_session_runtime_spec.lua @@ -689,6 +689,38 @@ describe('opencode.services.session_runtime', function() abort_stub:revert() end) + + it('aborts when the model is processing on the server but no client request is in flight', function() + state.session.set_active({ id = 'sess1' }) + store.set('job_count', 0) + + local abort_stub = stub(state.api_client, 'abort_session').invokes(function() + return Promise.new():resolve(true) + end) + + session_runtime.cancel():wait() + + assert.stub(abort_stub).was_called() + + abort_stub:revert() + end) + + it('does not count cancel toward the server-restart threshold when no client request is in flight', function() + state.session.set_active({ id = 'sess1' }) + store.set('job_count', 0) + vim.g.opencode_abort_count = 0 + + for _ = 1, 5 do + session_runtime.cancel():wait() + end + + assert.is_equal(0, vim.g.opencode_abort_count) + + store.set('job_count', 1) + vim.g.opencode_abort_count = 0 + session_runtime.cancel():wait() + assert.is_equal(1, vim.g.opencode_abort_count) + end) end) describe('opencode_ok (version checks)', function()