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.
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_readand 0cache_creationtokens across hundreds of Clauderequests (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 copilotalways setsCOPILOT_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 isClaude. The OpenAI Chat Completions wire format has no field to carry an
Anthropic
cache_controlbreakpoint, so no caching can happen on that pathunless 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=anthropicprovider type(https://docs.github.com/en/copilot/concepts/agents/about-copilot-cli), and
inspecting the shipped runtime (
@github/copilotnpm package,prebuilds/linux-x64/runtime.node) shows a dedicatedsrc/runtime/src/model/interaction/prompt_cache_request.rsmodule("Anthropic prompt-cache eligibility telemetry"), an
attemptCacheControlstage in its outbound request pipeline,
ephemeral_5m_input_tokens/ephemeral_1h_input_tokens/cache_creationusage fields, and aStainless-generated Anthropic SDK client (
anthropic-version,x-api-keyheaders) — 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/anthropicendpoint instead of the MLflow one.Expected behavior
When the model selected for Copilot is a Claude model, ucode should set
COPILOT_PROVIDER_TYPE=anthropicand pointCOPILOT_PROVIDER_BASE_URLatthe same native Anthropic gateway path
claude.pyuses, so Copilot's owncache_control logic actually runs. Codex (gpt-5) has no native-dialect
provider on Copilot's side and should keep using
openaiagainst the MLflowgateway.
Fix
A draft PR is up: fixes
agents/copilot.py/databricks.pyto branch theprovider type and base URL by model family, using
COPILOT_PROVIDER_API_KEY(Copilot's native-Anthropic auth header,
x-api-key) instead ofCOPILOT_PROVIDER_BEARER_TOKENfor the Claude path — matching how ClaudeCode already authenticates against this same gateway via its
apiKeyHelper/x-api-keyflow.Open question / follow-up: I haven't verified end-to-end against a live
workspace that Databricks'
/ai-gateway/anthropicaccepts the token viax-api-keyfrom 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.