Skip to content

feat: detect all coding agents in user-agent, not just Claude Code#519

Merged
lukepiette merged 2 commits into
mainfrom
feat/agent-source-tracking-all-agents
Jun 23, 2026
Merged

feat: detect all coding agents in user-agent, not just Claude Code#519
lukepiette merged 2 commits into
mainfrom
feat/agent-source-tracking-all-agents

Conversation

@lukepiette

Copy link
Copy Markdown
Contributor

Summary

Extends agent source tracking in the SDK's User-Agent beyond CLAUDECODE to the full set of coding-agent harnesses, so traffic from Cursor, Codex, Gemini CLI, Copilot, Cline, Replit, and others is attributed (today everything except Claude Code shows up untagged).

The detection registry mirrors runpodctl PR #280 and Hugging Face's public agent-harnesses list so traffic is attributed under the same identifiers across surfaces (MCP, runpodctl, Python SDK).

Changes

  • Add runpod/agent.py: an ordered harness registry (claude-code, cursor, cursor-cli, codex, gemini-cli, github-copilot, cline, cowork, replit, zed, goose, kiro, and more), plus a sanitized generic AI_AGENT fallback. First match wins; specific signals (e.g. cursor-cli, cowork) are ordered before broader ones they co-occur with.
  • Wire agent.detect() into construct_user_agent(), replacing the single CLAUDECODE check. The emitted tag format is unchanged: (via <agent>).
  • Tests: tests/test_agent.py (detection precedence, empty-value handling, AI_AGENT sanitization + 64-char cap) and updated tests/test_user_agent.py (now clears all known agent env vars; adds a non-Claude agent case).

Test plan

  • tests/test_agent.py and tests/test_user_agent.py pass (18 tests)
  • Import smoke test: construct_user_agent() emits (via claude-code) when run inside Claude Code
  • CI green

🤖 Generated with Claude Code

Extends agent source tracking beyond CLAUDECODE to the full set of coding
agent harnesses, mirroring runpodctl PR #280 and Hugging Face's public
agent-harnesses registry so traffic is attributed under the same identifiers
across surfaces.

- Add runpod/agent.py: ordered harness registry (claude-code, cursor,
  cursor-cli, codex, gemini-cli, github-copilot, cline, replit, zed, etc.)
  plus a sanitized generic AI_AGENT fallback.
- Wire agent.detect() into construct_user_agent(), replacing the single
  CLAUDECODE check. Emits "(via <agent>)" as before.
- Tests for detection precedence, sanitization, and the user-agent string.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Extends the RunPod Python SDK’s User-Agent agent-source attribution from a single CLAUDECODE check to a broader registry of coding-agent “harness” environment signals, with a generic AI_AGENT fallback to support additional/unknown tools.

Changes:

  • Added runpod/agent.py with an ordered harness registry, detect() logic, and AI_AGENT sanitization/length cap.
  • Updated construct_user_agent() to append (via <agent>) using agent.detect() rather than only detecting Claude Code.
  • Added tests/test_agent.py and expanded tests/test_user_agent.py to cover detection precedence, empty handling, sanitization, and non-Claude agent tagging.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
runpod/agent.py New module providing agent detection + sanitization and helper APIs.
runpod/user_agent.py Integrates agent detection into the emitted User-Agent string.
tests/test_agent.py New unit tests for registry matching, precedence, and AI_AGENT behavior.
tests/test_user_agent.py Updates UA tests to clear all agent env vars and adds a non-Claude agent case.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread runpod/user_agent.py Outdated
Comment thread runpod/agent.py
- user_agent.py: use agent.suffix() instead of re-implementing the
  "(via <id>)" fragment, so the format lives in one place and cannot drift.
- agent.detect(): strip env var values before matching, so a whitespace-only
  value does not count as detection (aligns harness matching with the
  docstring and the AI_AGENT path, which already strips).
- Add a test for the whitespace-only case.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@lukepiette lukepiette merged commit d14c67c into main Jun 23, 2026
9 checks passed
@lukepiette lukepiette deleted the feat/agent-source-tracking-all-agents branch June 23, 2026 17:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants