Agents¶
Each agent represents an AI coding agent environment, and is associated with:
a unique agent ID
a human-readable name
an icon (emoji / unicode character)
various metadata in its
info()method
Agent usage¶
Each agent is materialized by a Agent object, from which you can access various metadata:
>>> from extra_platforms import CLAUDE_CODE
>>> CLAUDE_CODE
Agent(id='claude_code', name='Claude Code')
>>> CLAUDE_CODE.id
'claude_code'
>>> CLAUDE_CODE.current
False
>>> CLAUDE_CODE.info()
{'id': 'claude_code', 'name': 'Claude Code', 'icon': '✴️', 'url': 'https://claude.ai/code', 'current': False}
To check if the current environment is running in a specific agent, use the corresponding detection function:
>>> from extra_platforms import is_claude_code
>>> is_claude_code()
False
The current agent can be obtained via the current_agent() function:
>>> from extra_platforms import current_agent
>>> current_agent()
Agent(id='unknown_agent', name='Unknown agent')
Absence is the normal case¶
Each AI coding agent advertises itself through a dedicated environment variable: CLAUDECODE for Claude Code, CLINE_ACTIVE for Cline, CURSOR_AGENT for Cursor. current_agent() expects a single agent to announce itself and raises RuntimeError if several match at once.
Outside an agent session, every detection function returns False and current_agent() returns UNKNOWN_AGENT. This makes is_unknown_agent() the idiomatic “not driven by an agent” check.
The LLM and AI_AGENT variables are used as expectation signals: when either is set but no agent is recognized, the miss is logged as a WARNING (a detection heuristic is probably missing and worth reporting); otherwise it is only logged as INFO. AI_AGENT carries the agent’s own name as its value, set by Crush and Pi among others, so an unrecognized value names the agent to add next.
Recognized agents¶
Icon |
Symbol |
Name |
Detection function |
|---|---|---|---|
✴️ |
Claude Code |
||
👾 |
Cline |
||
📕 |
OpenAI Codex |
||
✈️ |
GitHub Copilot CLI |
||
💘 |
Crush |
||
➤ |
Cursor |
||
♊ |
Gemini CLI |
||
π |
Pi |
Hint
The UNKNOWN_AGENT trait represents an unrecognized
agent. It is not included in the ALL_AGENTS group,
and will be returned by current_agent() if the current
agent is not recognized.
Groups of agents¶
There is only one group defined for agents: ALL_AGENTS, which includes all recognized agents.
Icon |
Symbol |
Description |
||
|---|---|---|---|---|
🧠 |
All AI coding agents |
⬥ |
---
config:
sankey:
height: 800
showValues: false
width: 800
---
sankey-beta
ALL_AGENTS,CLAUDE_CODE,1
ALL_AGENTS,CLINE,1
ALL_AGENTS,CODEX,1
ALL_AGENTS,COPILOT_CLI,1
ALL_AGENTS,CRUSH,1
ALL_AGENTS,CURSOR,1
ALL_AGENTS,GEMINI_CLI,1
ALL_AGENTS,PI,1
---
config:
mindmap:
padding: 5
---
mindmap
((🧠 ALL_AGENTS))
(✴️ CLAUDE_CODE)
(👾 CLINE)
(📕 CODEX)
(✈️ COPILOT_CLI)
(💘 CRUSH)
(➤ CURSOR)
(♊ GEMINI_CLI)
(π PI)
Predefined agents¶
Agent definitions and metadata.
- extra_platforms.CLAUDE_CODE = Agent(id='claude_code', name='Claude Code')¶
ID:
claude_codeAliases: -
Name: Claude Code
Icon: ✴️
Reference: <https://claude.ai/code>_
Detection function:
is_claude_code()Pytest decorators:
@skip_claude_code/@unless_claude_codeGroups (2):
ALL_AGENTS⬥,ALL_TRAITS
- extra_platforms.CLINE = Agent(id='cline', name='Cline')¶
ID:
clineAliases: -
Name: Cline
Icon: 👾
Reference: <https://cline.bot>_
Detection function:
is_cline()Pytest decorators:
@skip_cline/@unless_clineGroups (2):
ALL_AGENTS⬥,ALL_TRAITS
- extra_platforms.CODEX = Agent(id='codex', name='OpenAI Codex')¶
ID:
codexAliases: -
Name: OpenAI Codex
Icon: 📕
Reference: <https://github.com/openai/codex>_
Detection function:
is_codex()Pytest decorators:
@skip_codex/@unless_codexGroups (2):
ALL_AGENTS⬥,ALL_TRAITS
- extra_platforms.COPILOT_CLI = Agent(id='copilot_cli', name='GitHub Copilot CLI')¶
ID:
copilot_cliAliases: -
Name: GitHub Copilot CLI
Icon: ✈️
Reference: <https://github.com/github/copilot-cli>_
Detection function:
is_copilot_cli()Pytest decorators:
@skip_copilot_cli/@unless_copilot_cliGroups (2):
ALL_AGENTS⬥,ALL_TRAITS
- extra_platforms.CRUSH = Agent(id='crush', name='Crush')¶
ID:
crushAliases: -
Name: Crush
Icon: 💘
Reference: <https://github.com/charmbracelet/crush>_
Detection function:
is_crush()Pytest decorators:
@skip_crush/@unless_crushGroups (2):
ALL_AGENTS⬥,ALL_TRAITS
- extra_platforms.CURSOR = Agent(id='cursor', name='Cursor')¶
ID:
cursorAliases: -
Name: Cursor
Icon: ➤
Reference: <https://cursor.com>_
Detection function:
is_cursor()Pytest decorators:
@skip_cursor/@unless_cursorGroups (2):
ALL_AGENTS⬥,ALL_TRAITS
- extra_platforms.GEMINI_CLI = Agent(id='gemini_cli', name='Gemini CLI')¶
ID:
gemini_cliAliases: -
Name: Gemini CLI
Icon: ♊
Reference: <https://github.com/google-gemini/gemini-cli>_
Detection function:
is_gemini_cli()Pytest decorators:
@skip_gemini_cli/@unless_gemini_cliGroups (2):
ALL_AGENTS⬥,ALL_TRAITS
- extra_platforms.PI = Agent(id='pi', name='Pi')¶
ID:
piAliases: -
Name: Pi
Icon: π
Reference: <https://github.com/earendil-works/pi>_
Detection function:
is_pi()Pytest decorators:
@skip_pi/@unless_piGroups (2):
ALL_AGENTS⬥,ALL_TRAITS
- extra_platforms.UNKNOWN_AGENT = Agent(id='unknown_agent', name='Unknown agent')¶
ID:
unknown_agentAliases: -
Name: Unknown agent
Icon: ❓
Reference: <https://en.wikipedia.org/wiki/AI_agent>_
Detection function:
is_unknown_agent()Pytest decorators:
@skip_unknown_agent/@unless_unknown_agentGroups (2):
ALL_TRAITS,UNKNOWN⬥