Skip to content

Copilot CLI gets zero prompt-cache hits on Claude models — ucode forces the openai provider type instead of Copilot's native anthropic one #494

Description

@larsmoan

Summary

Copilot CLI never gets an Anthropic prompt-cache hit when talking to Claude
models through ucode, even though the same shared system/tool prefix repeats
on every turn. Production AI Gateway usage data for Copilot CLI users showed
0 cache_read and 0 cache_creation tokens across hundreds of Claude
requests (some with 100K+ input tokens), while the same users' one-off native
Claude Code request on the same workspace hit ~65% cache immediately.

Root cause

ucode configure copilot always sets COPILOT_PROVIDER_TYPE=openai
(agents/copilot.py:render_env_overlay), pointing Copilot CLI at Databricks'
OpenAI-compatible MLflow chat-completions gateway
({workspace}/ai-gateway/mlflow/v1) — even when the selected model is
Claude
. The OpenAI Chat Completions wire format has no field to carry an
Anthropic cache_control breakpoint, so no caching can happen on that path
unless the gateway itself synthesizes breakpoints server-side from an
OpenAI-shaped request, which it evidently doesn't.

This isn't a Copilot CLI limitation. Copilot CLI documents a native
COPILOT_PROVIDER_TYPE=anthropic provider type
(https://docs.github.com/en/copilot/concepts/agents/about-copilot-cli), and
inspecting the shipped runtime (@github/copilot npm package,
prebuilds/linux-x64/runtime.node) shows a dedicated
src/runtime/src/model/interaction/prompt_cache_request.rs module
("Anthropic prompt-cache eligibility telemetry"), an attemptCacheControl
stage in its outbound request pipeline, ephemeral_5m_input_tokens /
ephemeral_1h_input_tokens / cache_creation usage fields, and a
Stainless-generated Anthropic SDK client (anthropic-version, x-api-key
headers) — i.e. Copilot's runtime genuinely implements native Anthropic
cache-control insertion. ucode just never routes it down that code path for
Claude models; every other Anthropic-capable agent ucode configures
(claude, opencode, pi) already gets pointed at Databricks' native
{workspace}/ai-gateway/anthropic endpoint instead of the MLflow one.

Expected behavior

When the model selected for Copilot is a Claude model, ucode should set
COPILOT_PROVIDER_TYPE=anthropic and point COPILOT_PROVIDER_BASE_URL at
the same native Anthropic gateway path claude.py uses, so Copilot's own
cache_control logic actually runs. Codex (gpt-5) has no native-dialect
provider on Copilot's side and should keep using openai against the MLflow
gateway.

Fix

A draft PR is up: fixes agents/copilot.py/databricks.py to branch the
provider type and base URL by model family, using COPILOT_PROVIDER_API_KEY
(Copilot's native-Anthropic auth header, x-api-key) instead of
COPILOT_PROVIDER_BEARER_TOKEN for the Claude path — matching how Claude
Code already authenticates against this same gateway via its
apiKeyHelper/x-api-key flow.

Open question / follow-up: I haven't verified end-to-end against a live
workspace that Databricks' /ai-gateway/anthropic accepts the token via
x-api-key from Copilot's client the same way it does from Claude Code's —
logically it should (same endpoint, same auth convention), but this needs a
real run to confirm cache hits actually appear in system.ai_gateway.usage.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions