Copilot Token Auto Refresh Daemon | Generated by AI
Session ID: ses_31a4979a7ffe9rU42KDzISEti3 Created: 3/13/2026, 1:41:10 PM Updated: 3/13/2026, 1:41:26 PM
User
like this , import threading
copilot_token_cache = {“token”: None, “expires_at”: 0}
def refresh_copilot_token_loop(github_token: str): “"”Background thread: auto-refresh Copilot token before expiry””” while True: token_data = get_copilot_token(github_token) copilot_token_cache[“token”] = token_data[“token”] copilot_token_cache[“expires_at”] = token_data[“expires_at”]
refresh_in = token_data.get("refresh_in", 1500)
sleep_seconds = max(refresh_in - 60, 30) # refresh 60s before expiry
print(f"🔄 Next Copilot token refresh in {sleep_seconds}s")
time.sleep(sleep_seconds)
def start_token_refresh_daemon(github_token: str): thread = threading.Thread( target=refresh_copilot_token_loop, args=(github_token,), daemon=True ) thread.start() , import os
GITHUB_TOKEN_FILE = os.path.expanduser(“~/.copilot_github_token”)
def load_or_auth_github_token() -> str: “"”Load saved token or run device flow””” if os.path.exists(GITHUB_TOKEN_FILE): with open(GITHUB_TOKEN_FILE) as f: token = f.read().strip() if token: print(“✅ Loaded saved GitHub token.”) return token
# Run device flow
device_data = get_device_code()
github_token = poll_for_access_token(
device_data["device_code"],
interval=device_data.get("interval", 5)
)
# Persist token securely (chmod 600)
with open(GITHUB_TOKEN_FILE, "w") as f:
f.write(github_token)
os.chmod(GITHUB_TOKEN_FILE, 0o600)
return github_token
def main(): github_token = load_or_auth_github_token()
# Get initial Copilot token
token_data = get_copilot_token(github_token)
copilot_token_cache["token"] = token_data["token"]
copilot_token_cache["expires_at"] = token_data["expires_at"]
# Start background refresh
start_token_refresh_daemon(github_token)
# Now call the LLM
answer = call_copilot_llm("What is GitHub Copilot?")
print("🤖 Copilot says:", answer)
if name == “main”: main() , also add refresh token logic
Assistant (Build · google/gemini-3-flash-preview · 16.3s)
Thinking:
Analyzing Authentication Strategy
I’m currently focused on dissecting the provided code snippets to understand the proposed authentication flow, especially the “refresh token logic.” My immediate task is to identify how best to integrate these pieces into a coherent Python script that reliably manages GitHub Copilot authentication, focusing on the robustness of the token refreshing mechanism.
Refining Copilot Token Management
I’m now zeroing in on integrating the provided refresh token logic within a comprehensive structure for Copilot authentication. My focus is on synthesizing a complete implementation in Python, which should incorporate all necessary parts like GitHub token handling and the Copilot token exchange. I am also working on adding the functionality that was requested specifically, and handling the logic where the access token is returned.
I will implement a Python script that integrates the GitHub Device Flow for authentication, handles Copilot token exchange, and maintains a background refresh loop as requested.
Implementation Plan
- Authentication Flow: Implement
get_device_codeandpoll_for_access_tokenusing GitHub’s OAuth API. - Token Exchange: Implement
get_copilot_tokento exchange the GitHub OAuth token for a temporary Copilot session token. - LLM Interaction: Implement
call_copilot_llmto demonstrate using the cached token with the Copilot API. - Background Refresh: Integrate the
threadinglogic you provided to keep the Copilot token valid indefinitely.
I’ll start by creating the copilot_proxy.py script.
copilot_proxy.py
import os
import time
import json
import threading
import requests
# Constants
GITHUB_TOKEN_FILE = os.path.expanduser("~/.copilot_github_token")
DEVICE_CODE_URL = "https://github.com/login/device/code"
ACCESS_TOKEN_URL = "https://github.com/login/oauth/access_token"
COPILOT_TOKEN_URL = "https://api.github.com/copilot_internal/v2/token"
COPILOT_CHAT_URL = "https://api.githubcopilot.com/chat/completions"
CLIENT_ID = "Iv1.b507a3d205f504c4" # GitHub CLI Client ID
# Global Cache
copilot_token_cache = {"token": None, "expires_at": 0}
def get_device_code():
"""Request a device code from GitHub"""
response = requests.post(
DEVICE_CODE_URL,
headers={"Accept": "application/json"},
data={"client_id": CLIENT_ID, "scope": "read:user"}
)
response.raise_for_status()
data = response.json()
print(f"🔗 Please visit: {data['verification_uri']}")
print(f"🔢 Enter code: {data['user_code']}")
return data
def poll_for_access_token(device_code, interval):
"""Poll GitHub for the access token after user authorization"""
print("⏳ Waiting for authorization...")
while True:
response = requests.post(
ACCESS_TOKEN_URL,
headers={"Accept": "application/json"},
data={
"client_id": CLIENT_ID,
"device_code": device_code,
"grant_type": "urn:ietf:params:oauth:grant-type:device_code"
}
)
data = response.json()
if "access_token" in data:
return data["access_token"]
error = data.get("error")
if error == "authorization_pending":
time.sleep(interval)
elif error == "slow_down":
time.sleep(interval + 5)
else:
raise Exception(f"Failed to get token: {data.get('error_description')}")
def get_copilot_token(github_token):
"""Exchange GitHub token for a Copilot session token"""
response = requests.get(
COPILOT_TOKEN_URL,
headers={
"Authorization": f"token {github_token}",
"Accept": "application/json",
}
)
response.raise_for_status()
return response.json()
def refresh_copilot_token_loop(github_token: str):
"""Background thread: auto-refresh Copilot token before expiry"""
while True:
try:
token_data = get_copilot_token(github_token)
copilot_token_cache["token"] = token_data["token"]
copilot_token_cache["expires_at"] = token_data["expires_at"]
refresh_in = token_data.get("refresh_in", 1500)
# Refresh 60s before expiry, but at least every 30s
sleep_seconds = max(refresh_in - 60, 30)
print(f"🔄 Next Copilot token refresh in {sleep_seconds}s")
time.sleep(sleep_seconds)
except Exception as e:
print(f"❌ Token refresh failed: {e}")
time.sleep(10) # Retry soon on failure
def start_token_refresh_daemon(github_token: str):
thread = threading.Thread(
target=refresh_copilot_token_loop,
args=(github_token,),
daemon=True
)
thread.start()
def load_or_auth_github_token() -> str:
"""Load saved token or run device flow"""
if os.path.exists(GITHUB_TOKEN_FILE):
with open(GITHUB_TOKEN_FILE) as f:
token = f.read().strip()
if token:
# Basic validation: check if token still works
try:
get_copilot_token(token)
print("✅ Loaded saved GitHub token.")
return token
except:
print("⚠️ Saved token invalid. Re-authenticating...")
device_data = get_device_code()
github_token = poll_for_access_token(
device_data["device_code"],
interval=device_data.get("interval", 5)
)
with open(GITHUB_TOKEN_FILE, "w") as f:
f.write(github_token)
os.chmod(GITHUB_TOKEN_FILE, 0o600)
return github_token
def call_copilot_llm(prompt: str):
"""Make a request to the Copilot Chat API using the cached token"""
if not copilot_token_cache["token"]:
raise Exception("Copilot token not available")
response = requests.post(
COPILOT_CHAT_URL,
headers={
"Authorization": f"Bearer {copilot_token_cache['token']}",
"Content-Type": "application/json",
"Editor-Version": "vscode/1.80.0",
},
json={
"messages": [{"role": "user", "content": prompt}],
"model": "gpt-4"
}
)
response.raise_for_status()
return response.json()["choices"][0]["message"]["content"]
def main():
try:
github_token = load_or_auth_github_token()
# Get initial Copilot token
token_data = get_copilot_token(github_token)
copilot_token_cache["token"] = token_data["token"]
copilot_token_cache["expires_at"] = token_data["expires_at"]
# Start background refresh
start_token_refresh_daemon(github_token)
# Demonstration
print("🤖 Calling Copilot LLM...")
answer = call_copilot_llm("What is GitHub Copilot?")
print(f"\n🤖 Copilot says:\n{answer}")
# Keep main thread alive to see refreshes if needed
print("\n(Script will stay active for 2 minutes to show refresh logic...)")
time.sleep(120)
except KeyboardInterrupt:
print("\n👋 Exiting...")
if __name__ == "__main__":
main()
This implementation includes:
- Device Flow Authentication: Uses the GitHub CLI Client ID to get an OAuth token.
- Persistence: Saves the GitHub token to
~/.copilot_github_tokenwith restricted permissions. - Threaded Refresh: Periodically updates the short-lived Copilot session token (which usually expires in 25-30 minutes).
- LLM Integration: A working
call_copilot_llmfunction that uses the VS Code editor headers required by the Copilot API.
You can run this script to authenticate and start using Copilot in your CLI applications.
Thinking:
[REDACTED]