From 95a4a975edb9bb25f0849563d8b4f1f3f5ef12f5 Mon Sep 17 00:00:00 2001 From: simon Date: Tue, 26 May 2026 13:31:49 +0200 Subject: [PATCH 1/5] Detect VS Code agent via VSCODE_AGENT, remove COPILOT_MODEL heuristic VS Code 1.121+ sets VSCODE_AGENT for agent-initiated terminal commands. Detect it as `vscode-agent` in the User-Agent header. The previous COPILOT_MODEL heuristic reported `copilot-vscode` but COPILOT_MODEL is set by Copilot CLI BYOK users, not specifically by VS Code. The BYOK collapse logic (drop copilot-vscode when COPILOT_CLI is also set) is removed alongside the heuristic; VSCODE_AGENT can legitimately stack with COPILOT_CLI, which now correctly reports `multiple`. See: https://code.visualstudio.com/updates/v1_121 --- NEXT_CHANGELOG.md | 2 ++ databricks/sdk/useragent.py | 12 +++--------- tests/test_user_agent.py | 33 +++++++++++++++------------------ 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index 23d28d091..fcc6e48ff 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -4,6 +4,8 @@ ### New Features and Improvements +* Detect VS Code agent-initiated terminal commands via the `VSCODE_AGENT` environment variable (VS Code 1.121+). The User-Agent header now reports `agent/vscode-agent` when set. The previous `COPILOT_MODEL` heuristic (which reported `agent/copilot-vscode`) has been removed; it produced false positives for Copilot CLI BYOK users and never reliably identified VS Code. + ### Security ### Bug Fixes diff --git a/databricks/sdk/useragent.py b/databricks/sdk/useragent.py index 0536bb688..da04a5265 100644 --- a/databricks/sdk/useragent.py +++ b/databricks/sdk/useragent.py @@ -244,9 +244,6 @@ class _AgentRecord: _AgentRecord("CLINE_ACTIVE", "cline"), # https://github.com/cline/cline (v3.24.0+) _AgentRecord("CODEX_CI", "codex"), # https://github.com/openai/codex _AgentRecord("COPILOT_CLI", "copilot-cli"), # https://github.com/features/copilot - _AgentRecord( - "COPILOT_MODEL", "copilot-vscode" - ), # VS Code Copilot terminal, best-effort heuristic, not officially identified _AgentRecord("CURSOR_AGENT", "cursor"), # Closed source _AgentRecord("GEMINI_CLI", "gemini-cli"), # https://google-gemini.github.io/gemini-cli _AgentRecord( @@ -255,6 +252,9 @@ class _AgentRecord: _AgentRecord("KIRO", "kiro"), # https://kiro.dev/ (Amazon) _AgentRecord("OPENCLAW_SHELL", "openclaw"), # https://github.com/anthropics/openclaw _AgentRecord("OPENCODE", "opencode"), # https://github.com/opencode-ai/opencode + _AgentRecord( + "VSCODE_AGENT", "vscode-agent" + ), # Set by VS Code 1.121+ for agent-initiated terminal commands (https://code.visualstudio.com/updates/v1_121) _AgentRecord("WINDSURF_AGENT", "windsurf"), # https://codeium.com/windsurf (Codeium) ] @@ -291,12 +291,6 @@ def agent_provider() -> str: matches = [a.product for a in _KNOWN_AGENTS if a.env_var in os.environ] - # Known BYOK false positive: Copilot CLI users often set COPILOT_MODEL - # alongside COPILOT_CLI. That pair is a single copilot-cli signal, not a - # stacked multi-agent setup. - if "copilot-cli" in matches and "copilot-vscode" in matches: - matches = [m for m in matches if m != "copilot-vscode"] - if len(matches) == 1: _agent_provider = matches[0] elif len(matches) > 1: diff --git a/tests/test_user_agent.py b/tests/test_user_agent.py index c7f440515..44a446827 100644 --- a/tests/test_user_agent.py +++ b/tests/test_user_agent.py @@ -235,11 +235,20 @@ def test_agent_provider_augment(clean_useragent_env): assert useragent.agent_provider() == "augment" -def test_agent_provider_copilot_vscode(clean_useragent_env): +def test_agent_provider_vscode_agent(clean_useragent_env): + os.environ["VSCODE_AGENT"] = "1" + from databricks.sdk import useragent + + assert useragent.agent_provider() == "vscode-agent" + + +def test_agent_provider_copilot_model_alone_not_detected(clean_useragent_env): + # COPILOT_MODEL is set by Copilot CLI BYOK users and does not by itself + # identify any agent. It must not contribute to detection. os.environ["COPILOT_MODEL"] = "gpt-4" from databricks.sdk import useragent - assert useragent.agent_provider() == "copilot-vscode" + assert useragent.agent_provider() == "" def test_agent_provider_kiro(clean_useragent_env): @@ -334,23 +343,11 @@ def test_agent_provider_explicit_goose_wins_over_agent_cursor(clean_useragent_en assert useragent.agent_provider() == "goose" -def test_agent_provider_copilot_cli_and_vscode_collapses_to_copilot_cli(clean_useragent_env): - # Copilot CLI users (BYOK mode) often set COPILOT_MODEL alongside - # COPILOT_CLI. Treat the pair as a single copilot-cli signal rather than - # a stacked multi-agent setup. - os.environ["COPILOT_CLI"] = "1" - os.environ["COPILOT_MODEL"] = "gpt-4" - from databricks.sdk import useragent - - assert useragent.agent_provider() == "copilot-cli" - - -def test_agent_provider_copilot_byok_collapse_then_still_multiple(clean_useragent_env): - # The Copilot BYOK collapse only removes the copilot-vscode match. If - # another agent is also present, the result is still "multiple". +def test_agent_provider_vscode_agent_and_copilot_cli_reports_multiple(clean_useragent_env): + # VSCODE_AGENT can legitimately stack with other agents (e.g. running + # Copilot CLI from a VS Code agent terminal). + os.environ["VSCODE_AGENT"] = "1" os.environ["COPILOT_CLI"] = "1" - os.environ["COPILOT_MODEL"] = "gpt-4" - os.environ["CLAUDECODE"] = "1" from databricks.sdk import useragent assert useragent.agent_provider() == "multiple" From c3a2c76144d8f9777b7457f40e0cafc17ca7dea7 Mon Sep 17 00:00:00 2001 From: simon Date: Tue, 26 May 2026 13:39:50 +0200 Subject: [PATCH 2/5] Drop the residual COPILOT_MODEL test case --- tests/test_user_agent.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tests/test_user_agent.py b/tests/test_user_agent.py index 44a446827..fe52675c7 100644 --- a/tests/test_user_agent.py +++ b/tests/test_user_agent.py @@ -242,15 +242,6 @@ def test_agent_provider_vscode_agent(clean_useragent_env): assert useragent.agent_provider() == "vscode-agent" -def test_agent_provider_copilot_model_alone_not_detected(clean_useragent_env): - # COPILOT_MODEL is set by Copilot CLI BYOK users and does not by itself - # identify any agent. It must not contribute to detection. - os.environ["COPILOT_MODEL"] = "gpt-4" - from databricks.sdk import useragent - - assert useragent.agent_provider() == "" - - def test_agent_provider_kiro(clean_useragent_env): os.environ["KIRO"] = "1" from databricks.sdk import useragent From 45202ca50d756337e3a738b4016260754f38a2e6 Mon Sep 17 00:00:00 2001 From: simon Date: Tue, 26 May 2026 13:50:59 +0200 Subject: [PATCH 3/5] Drop NEXT_CHANGELOG entry (NO_CHANGELOG=true) --- NEXT_CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index fcc6e48ff..23d28d091 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -4,8 +4,6 @@ ### New Features and Improvements -* Detect VS Code agent-initiated terminal commands via the `VSCODE_AGENT` environment variable (VS Code 1.121+). The User-Agent header now reports `agent/vscode-agent` when set. The previous `COPILOT_MODEL` heuristic (which reported `agent/copilot-vscode`) has been removed; it produced false positives for Copilot CLI BYOK users and never reliably identified VS Code. - ### Security ### Bug Fixes From afd53a14b8156094085fe96f5d40afd481be9d89 Mon Sep 17 00:00:00 2001 From: simon Date: Wed, 27 May 2026 17:50:05 +0200 Subject: [PATCH 4/5] ci: re-trigger integration tests From 4e362f8459687fc3551a0613917c92a6ed03fe8f Mon Sep 17 00:00:00 2001 From: simon Date: Thu, 28 May 2026 18:01:10 +0200 Subject: [PATCH 5/5] ci: re-trigger CI