Skip to content

Commit 6235813

Browse files
authored
Detect VS Code agent via VSCODE_AGENT, remove COPILOT_MODEL heuristic (#1444)
## Why [VS Code 1.121](https://code.visualstudio.com/updates/v1_121) introduced the `VSCODE_AGENT` environment variable, set for any agent-initiated terminal command (Copilot Chat agent mode and other agent extensions). This is the official signal for VS Code agent usage. The previous heuristic detected `COPILOT_MODEL` and reported `copilot-vscode`, but `COPILOT_MODEL` is actually set by Copilot CLI users who bring their own key, not specifically by VS Code. This produced false positives and required a BYOK collapse workaround (drop `copilot-vscode` whenever `COPILOT_CLI` was also set). Over the last 13 weeks, the heuristic identified 3 users / 52 events; `copilot-cli` saw 539 users / 175k events. The signal was effectively dead. ## Changes - Add `VSCODE_AGENT` to `_KNOWN_AGENTS`, reported as `agent/vscode-agent`. - Remove the `COPILOT_MODEL` to `copilot-vscode` mapping. - Remove the BYOK collapse logic. `VSCODE_AGENT` can legitimately stack with `COPILOT_CLI` (e.g. running Copilot CLI from a VS Code agent terminal), so the multi-agent path covers it without special handling. ## Tests - [x] Updated `tests/test_user_agent.py`: new `vscode-agent` case, `VSCODE_AGENT + COPILOT_CLI` stacks to `multiple`. - [x] `pytest tests/test_user_agent.py` passes (42 tests). - [x] `make fmt` clean. This PR mirrors parallel changes in [databricks-sdk-go](databricks/databricks-sdk-go#1697), [databricks-sdk-java](databricks/databricks-sdk-java#810), and [sdk-js](databricks/sdk-js#152). NO_CHANGELOG=true
1 parent 51de41f commit 6235813

2 files changed

Lines changed: 10 additions & 28 deletions

File tree

databricks/sdk/useragent.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,6 @@ class _AgentRecord:
244244
_AgentRecord("CLINE_ACTIVE", "cline"), # https://github.com/cline/cline (v3.24.0+)
245245
_AgentRecord("CODEX_CI", "codex"), # https://github.com/openai/codex
246246
_AgentRecord("COPILOT_CLI", "copilot-cli"), # https://github.com/features/copilot
247-
_AgentRecord(
248-
"COPILOT_MODEL", "copilot-vscode"
249-
), # VS Code Copilot terminal, best-effort heuristic, not officially identified
250247
_AgentRecord("CURSOR_AGENT", "cursor"), # Closed source
251248
_AgentRecord("GEMINI_CLI", "gemini-cli"), # https://google-gemini.github.io/gemini-cli
252249
_AgentRecord(
@@ -255,6 +252,9 @@ class _AgentRecord:
255252
_AgentRecord("KIRO", "kiro"), # https://kiro.dev/ (Amazon)
256253
_AgentRecord("OPENCLAW_SHELL", "openclaw"), # https://github.com/anthropics/openclaw
257254
_AgentRecord("OPENCODE", "opencode"), # https://github.com/opencode-ai/opencode
255+
_AgentRecord(
256+
"VSCODE_AGENT", "vscode-agent"
257+
), # Set by VS Code 1.121+ for agent-initiated terminal commands (https://code.visualstudio.com/updates/v1_121)
258258
_AgentRecord("WINDSURF_AGENT", "windsurf"), # https://codeium.com/windsurf (Codeium)
259259
]
260260

@@ -291,12 +291,6 @@ def agent_provider() -> str:
291291

292292
matches = [a.product for a in _KNOWN_AGENTS if a.env_var in os.environ]
293293

294-
# Known BYOK false positive: Copilot CLI users often set COPILOT_MODEL
295-
# alongside COPILOT_CLI. That pair is a single copilot-cli signal, not a
296-
# stacked multi-agent setup.
297-
if "copilot-cli" in matches and "copilot-vscode" in matches:
298-
matches = [m for m in matches if m != "copilot-vscode"]
299-
300294
if len(matches) == 1:
301295
_agent_provider = matches[0]
302296
elif len(matches) > 1:

tests/test_user_agent.py

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,11 @@ def test_agent_provider_augment(clean_useragent_env):
235235
assert useragent.agent_provider() == "augment"
236236

237237

238-
def test_agent_provider_copilot_vscode(clean_useragent_env):
239-
os.environ["COPILOT_MODEL"] = "gpt-4"
238+
def test_agent_provider_vscode_agent(clean_useragent_env):
239+
os.environ["VSCODE_AGENT"] = "1"
240240
from databricks.sdk import useragent
241241

242-
assert useragent.agent_provider() == "copilot-vscode"
242+
assert useragent.agent_provider() == "vscode-agent"
243243

244244

245245
def test_agent_provider_kiro(clean_useragent_env):
@@ -334,23 +334,11 @@ def test_agent_provider_explicit_goose_wins_over_agent_cursor(clean_useragent_en
334334
assert useragent.agent_provider() == "goose"
335335

336336

337-
def test_agent_provider_copilot_cli_and_vscode_collapses_to_copilot_cli(clean_useragent_env):
338-
# Copilot CLI users (BYOK mode) often set COPILOT_MODEL alongside
339-
# COPILOT_CLI. Treat the pair as a single copilot-cli signal rather than
340-
# a stacked multi-agent setup.
337+
def test_agent_provider_vscode_agent_and_copilot_cli_reports_multiple(clean_useragent_env):
338+
# VSCODE_AGENT can legitimately stack with other agents (e.g. running
339+
# Copilot CLI from a VS Code agent terminal).
340+
os.environ["VSCODE_AGENT"] = "1"
341341
os.environ["COPILOT_CLI"] = "1"
342-
os.environ["COPILOT_MODEL"] = "gpt-4"
343-
from databricks.sdk import useragent
344-
345-
assert useragent.agent_provider() == "copilot-cli"
346-
347-
348-
def test_agent_provider_copilot_byok_collapse_then_still_multiple(clean_useragent_env):
349-
# The Copilot BYOK collapse only removes the copilot-vscode match. If
350-
# another agent is also present, the result is still "multiple".
351-
os.environ["COPILOT_CLI"] = "1"
352-
os.environ["COPILOT_MODEL"] = "gpt-4"
353-
os.environ["CLAUDECODE"] = "1"
354342
from databricks.sdk import useragent
355343

356344
assert useragent.agent_provider() == "multiple"

0 commit comments

Comments
 (0)