From c7ef8d0aebcfd540c5285dcad2a99794f6067bb6 Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Fri, 1 Aug 2025 02:38:45 +0200 Subject: [PATCH] feat(providers): prioritize gh clie auth if available for github models Also add healthchecks Signed-off-by: Tomas Slusny --- README.md | 2 -- lua/CopilotChat/config/providers.lua | 35 ++++++++++++++++++++++++---- lua/CopilotChat/health.lua | 11 ++++++--- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 19e790c6..333b8495 100644 --- a/README.md +++ b/README.md @@ -40,8 +40,6 @@ CopilotChat.nvim is a Neovim plugin that brings GitHub Copilot Chat capabilities ## Optional Dependencies -- [copilot.vim](https://github.com/github/copilot.vim) - For `:Copilot setup` authorization, otherwise in-built method i used - - [tiktoken_core](https://github.com/gptlang/lua-tiktoken) - For accurate token counting - Arch Linux: Install [`luajit-tiktoken-bin`](https://aur.archlinux.org/packages/luajit-tiktoken-bin) or [`lua51-tiktoken-bin`](https://aur.archlinux.org/packages/lua51-tiktoken-bin) from AUR - Via luarocks: `sudo luarocks install --lua-version 5.1 tiktoken_core` diff --git a/lua/CopilotChat/config/providers.lua b/lua/CopilotChat/config/providers.lua index 5b35a2b4..d2ac7976 100644 --- a/lua/CopilotChat/config/providers.lua +++ b/lua/CopilotChat/config/providers.lua @@ -99,7 +99,7 @@ end --- Get the github copilot oauth cached token (gu_ token) ---@return string -local function get_github_token(tag) +local function get_github_copilot_token(tag) local function config_path() local config = vim.fs.normalize('$XDG_CONFIG_HOME') if config and vim.uv.fs_stat(config) then @@ -157,6 +157,33 @@ local function get_github_token(tag) return github_device_flow(tag, 'Iv1.b507a08c87ecfe98', '') end +local function get_github_models_token(tag) + local token = get_token(tag) + if token then + return token + end + + -- loading token from the environment only in GitHub Codespaces + local codespaces = os.getenv('CODESPACES') + token = os.getenv('GITHUB_TOKEN') + if token and codespaces then + return set_token(tag, token, false) + end + + -- loading token from gh cli if available + if vim.fn.executable('gh') == 0 then + local result = utils.system({ 'gh', 'auth', 'token', '-h', 'github.com' }) + if result and result.code == 0 and result.stdout then + local gh_token = vim.trim(result.stdout) + if gh_token ~= '' and not gh_token:find('no oauth token') then + return set_token(tag, gh_token, false) + end + end + end + + return github_device_flow(tag, '178c6fc778ccc68e1d6a', 'read:user copilot') +end + ---@class CopilotChat.config.providers.Options ---@field model CopilotChat.client.Model ---@field temperature number? @@ -188,7 +215,7 @@ M.copilot = { local response, err = utils.curl_get('https://api.github.com/copilot_internal/v2/token', { json_response = true, headers = { - ['Authorization'] = 'Token ' .. get_github_token('github_copilot'), + ['Authorization'] = 'Token ' .. get_github_copilot_token('github_copilot'), }, }) @@ -209,7 +236,7 @@ M.copilot = { local response, err = utils.curl_get('https://api.github.com/copilot_internal/user', { json_response = true, headers = { - ['Authorization'] = 'Token ' .. get_github_token('github_copilot'), + ['Authorization'] = 'Token ' .. get_github_copilot_token('github_copilot'), }, }) @@ -430,7 +457,7 @@ M.github_models = { get_headers = function() return { - ['Authorization'] = 'Bearer ' .. github_device_flow('github_models', 'Ov23liqtJusaUH38tIoK', 'read:user copilot'), + ['Authorization'] = 'Bearer ' .. get_github_models_token('github_models'), } end, diff --git a/lua/CopilotChat/health.lua b/lua/CopilotChat/health.lua index acfc5bd2..1c8bc3b4 100644 --- a/lua/CopilotChat/health.lua +++ b/lua/CopilotChat/health.lua @@ -55,8 +55,6 @@ function M.check() error('setup: not called, required for plugin to work. See `:h CopilotChat-installation`.') end - start('CopilotChat.nvim [filesystem]') - local testfile = os.tmpname() local f = io.open(testfile, 'w') local writable = false @@ -104,6 +102,13 @@ function M.check() ok('lynx: ' .. lynx_version) end + local gh_version = run_command('gh', '--version') + if gh_version == false then + warn('gh: missing, optional for improved GitHub authorization. See "https://cli.github.com/".') + else + ok('gh: ' .. gh_version) + end + start('CopilotChat.nvim [dependencies]') if lualib_installed('plenary') then @@ -118,7 +123,7 @@ function M.check() ok('copilot: ' .. (has_copilot and 'copilot.lua' or 'copilot.vim')) else warn( - 'copilot: missing, optional for improved auth implementation. Install "github/copilot.vim" or "zbirenbaum/copilot.lua" plugins.' + 'copilot: missing, optional for improved Copilot authorization. Install "github/copilot.vim" or "zbirenbaum/copilot.lua" plugins.' ) end