Skip to content

Renew Copilot auth token before each LLM API request attempt#401

Closed
itkonen wants to merge 6 commits intoeditor-code-assistant:masterfrom
itkonen:master
Closed

Renew Copilot auth token before each LLM API request attempt#401
itkonen wants to merge 6 commits intoeditor-code-assistant:masterfrom
itkonen:master

Conversation

@itkonen
Copy link
Copy Markdown

@itkonen itkonen commented Apr 8, 2026

This is my attempt to fix the Github Copilot token expiration problem which tends to occur in the middle of long agentic workflows (#126):

LLM response status: 401 body: unauthorized: token expired

It interrupts the task, even though the session remains intact so that I can ask the agent to continue. Github Copilot tokens seem to have really short lifespans, so this error tends to occur quite often.

Warning: I don't know much Clojure, and I cannot really evaluate the PR which I ended up with by iterating with Copilot, so this might be mere AI slop. But hopefully the PR gives some idea where the problem occurs.

Copilot Summary:

This pull request implements proactive renewal of GitHub Copilot and other provider auth tokens before each LLM API request attempt, ensuring that long-running or agentic workflows do not fail due to expired tokens. It introduces a new provider-auth-fn mechanism that replaces the previous static provider-auth approach, allowing the system to always use a fresh token and retry with renewed credentials as needed. Comprehensive tests have been added to verify this behavior for both sync and async LLM API requests, including retries.

Auth Token Renewal and LLM API Improvements:

  • Added a provider-auth-fn option to sync-or-async-prompt! in llm_api.clj, which is invoked before each LLM API request (including retries) to ensure a fresh auth token is used. This replaces the previous static provider-auth approach. [1] [2] [3] [4]
  • Introduced silent-provider-auth-fn in chat/lifecycle.clj to renew provider auth tokens without interrupting ongoing requests on error, and updated chat and rewrite features to use this function for proactive token refresh. [1] [2] [3]
  • Updated the changelog to document the new token renewal behavior for GitHub Copilot.

Testing and Reliability:

  • Added extensive tests in llm_api_test.clj to verify that provider-auth-fn is invoked before every sync and async prompt attempt, including retries, and that its result is correctly passed to the LLM API.
  • Enhanced rewrite feature tests to ensure that the new token renewal mechanism is triggered and returns the expected auth. [1] [2]

Minor Fixes:

  • Fixed a bug in login.clj where chat status and login provider were not correctly reset when chat-id was nil.

@zikajk
Copy link
Copy Markdown
Member

zikajk commented Apr 8, 2026

@itkonen Sorry, i just did the fix 5 hours ago, here: #399

Your approach resolves auth before prompt! starts, but the problem is inside prompt! - when tool calls like spawn_agent run for 30+ seconds, the token expires mid-stream. The provider needs fresh auth for recursive calls, but it's already "baked in" from the start.

My fix renews and propagates fresh auth inside on-tools-called!, right before the provider's continuation runs. I've also added a 60-second buffer before expiration and skip-models-sync? to avoid redundant syncs during renewals.

On retries

We haven't added retry logic for 401s yet. The 60-second buffer should prevent most expiry cases proactively. If we see the need, we can add targeted retry logic separately - but we'd want to be careful about loops.

Thanks.

@ericdallo
Copy link
Copy Markdown
Member

Fixed in #399, thank you!

@ericdallo ericdallo closed this Apr 8, 2026
@itkonen
Copy link
Copy Markdown
Author

itkonen commented Apr 8, 2026

Well that's great news, thank you! I'm glad it's getting fixed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants