detect_agent 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,121 @@
1
+ import os
2
+ from pathlib import Path
3
+ from typing import Literal, TypedDict, Union
4
+
5
+ DEVIN_LOCAL_PATH = "/opt/.devin"
6
+
7
+ CURSOR: Literal["cursor"] = "cursor"
8
+ CURSOR_CLI: Literal["cursor-cli"] = "cursor-cli"
9
+ CLAUDE: Literal["claude"] = "claude"
10
+ COWORK: Literal["cowork"] = "cowork"
11
+ DEVIN: Literal["devin"] = "devin"
12
+ REPLIT: Literal["replit"] = "replit"
13
+ GEMINI: Literal["gemini"] = "gemini"
14
+ CODEX: Literal["codex"] = "codex"
15
+ ANTIGRAVITY: Literal["antigravity"] = "antigravity"
16
+ AUGMENT_CLI: Literal["augment-cli"] = "augment-cli"
17
+ OPENCODE: Literal["opencode"] = "opencode"
18
+ GITHUB_COPILOT: Literal["github-copilot"] = "github-copilot"
19
+ GITHUB_COPILOT_CLI: Literal["github-copilot-cli"] = "github-copilot-cli"
20
+
21
+ KnownAgentNames = Literal[
22
+ "cursor",
23
+ "cursor-cli",
24
+ "claude",
25
+ "cowork",
26
+ "devin",
27
+ "replit",
28
+ "gemini",
29
+ "codex",
30
+ "antigravity",
31
+ "augment-cli",
32
+ "opencode",
33
+ "github-copilot",
34
+ ]
35
+
36
+
37
+ class KnownAgentDetails(TypedDict):
38
+ name: KnownAgentNames
39
+
40
+
41
+ class AgentResultAgent(TypedDict):
42
+ is_agent: Literal[True]
43
+ agent: KnownAgentDetails
44
+
45
+
46
+ class AgentResultNone(TypedDict):
47
+ is_agent: Literal[False]
48
+ agent: None
49
+
50
+
51
+ AgentResult = Union[AgentResultAgent, AgentResultNone]
52
+
53
+ KNOWN_AGENTS = {
54
+ "CURSOR": CURSOR,
55
+ "CURSOR_CLI": CURSOR_CLI,
56
+ "CLAUDE": CLAUDE,
57
+ "COWORK": COWORK,
58
+ "DEVIN": DEVIN,
59
+ "REPLIT": REPLIT,
60
+ "GEMINI": GEMINI,
61
+ "CODEX": CODEX,
62
+ "ANTIGRAVITY": ANTIGRAVITY,
63
+ "AUGMENT_CLI": AUGMENT_CLI,
64
+ "OPENCODE": OPENCODE,
65
+ "GITHUB_COPILOT": GITHUB_COPILOT,
66
+ }
67
+
68
+
69
+ def determine_agent() -> AgentResult:
70
+ ai_agent = os.environ.get("AI_AGENT")
71
+ if ai_agent:
72
+ name = ai_agent.strip()
73
+ if name:
74
+ if name in (GITHUB_COPILOT, GITHUB_COPILOT_CLI):
75
+ return {"is_agent": True, "agent": {"name": GITHUB_COPILOT}}
76
+ return {"is_agent": True, "agent": {"name": name}} # type: ignore[return-value]
77
+
78
+ if os.environ.get("CURSOR_TRACE_ID"):
79
+ return {"is_agent": True, "agent": {"name": CURSOR}}
80
+
81
+ if os.environ.get("CURSOR_AGENT"):
82
+ return {"is_agent": True, "agent": {"name": CURSOR_CLI}}
83
+
84
+ if os.environ.get("GEMINI_CLI"):
85
+ return {"is_agent": True, "agent": {"name": GEMINI}}
86
+
87
+ if (
88
+ os.environ.get("CODEX_SANDBOX")
89
+ or os.environ.get("CODEX_CI")
90
+ or os.environ.get("CODEX_THREAD_ID")
91
+ ):
92
+ return {"is_agent": True, "agent": {"name": CODEX}}
93
+
94
+ if os.environ.get("ANTIGRAVITY_AGENT"):
95
+ return {"is_agent": True, "agent": {"name": ANTIGRAVITY}}
96
+
97
+ if os.environ.get("AUGMENT_AGENT"):
98
+ return {"is_agent": True, "agent": {"name": AUGMENT_CLI}}
99
+
100
+ if os.environ.get("OPENCODE_CLIENT"):
101
+ return {"is_agent": True, "agent": {"name": OPENCODE}}
102
+
103
+ if os.environ.get("CLAUDECODE") or os.environ.get("CLAUDE_CODE"):
104
+ if os.environ.get("CLAUDE_CODE_IS_COWORK"):
105
+ return {"is_agent": True, "agent": {"name": COWORK}}
106
+ return {"is_agent": True, "agent": {"name": CLAUDE}}
107
+
108
+ if os.environ.get("REPL_ID"):
109
+ return {"is_agent": True, "agent": {"name": REPLIT}}
110
+
111
+ if (
112
+ os.environ.get("COPILOT_MODEL")
113
+ or os.environ.get("COPILOT_ALLOW_ALL")
114
+ or os.environ.get("COPILOT_GITHUB_TOKEN")
115
+ ):
116
+ return {"is_agent": True, "agent": {"name": GITHUB_COPILOT}}
117
+
118
+ if Path(DEVIN_LOCAL_PATH).exists():
119
+ return {"is_agent": True, "agent": {"name": DEVIN}}
120
+
121
+ return {"is_agent": False, "agent": None}
detect_agent/py.typed ADDED
File without changes
@@ -0,0 +1,118 @@
1
+ Metadata-Version: 2.4
2
+ Name: detect_agent
3
+ Version: 0.1.0
4
+ Summary: Detect if code is running in an AI agent or automated development environment
5
+ Project-URL: Homepage, https://github.com/togethercomputer/detect_agent
6
+ Project-URL: Repository, https://github.com/togethercomputer/detect_agent
7
+ Project-URL: Changelog, https://github.com/togethercomputer/detect_agent/blob/main/CHANGELOG.md
8
+ Requires-Python: >=3.9
9
+ Provides-Extra: dev
10
+ Requires-Dist: pytest>=7.0; extra == 'dev'
11
+ Requires-Dist: ruff>=0.8.0; extra == 'dev'
12
+ Description-Content-Type: text/markdown
13
+
14
+ # detect_agent
15
+
16
+ > This is a Python Port of Vercels NPM package
17
+
18
+ A lightweight utility for detecting if code is being executed by an AI agent or automated development environment.
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ uv add detect_agent
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ```python
29
+ from detect_agent import determine_agent
30
+
31
+ result = determine_agent()
32
+
33
+ if result["is_agent"]:
34
+ print(f"Running in {result["agent"]["name"]} environment");
35
+ ```
36
+
37
+ ## Supported Agents
38
+
39
+ This package can detect the following AI agents and development environments:
40
+
41
+ - **Custom agents** via `AI_AGENT` environment variable
42
+ - **Cursor** (cursor editor and cursor-cli)
43
+ - **Claude Code** (Anthropic's Claude)
44
+ - **Devin** (Cognition Labs)
45
+ - **Gemini CLI** (Google)
46
+ - **Codex** (OpenAI)
47
+ - **Antigravity** (Google DeepMind)
48
+ - **GitHub Copilot** (via `AI_AGENT=github-copilot|github-copilot-cli`, `COPILOT_MODEL`, `COPILOT_ALLOW_ALL`, or `COPILOT_GITHUB_TOKEN`)
49
+ - **Replit** (online IDE)
50
+
51
+ ## The AI_AGENT Standard
52
+
53
+ We're promoting `AI_AGENT` as a universal environment variable standard for AI development tools. This allows any tool or library to easily detect when it's running in an AI-driven environment.
54
+
55
+ ### For AI Tool Developers
56
+
57
+ Set the `AI_AGENT` environment variable to identify your tool:
58
+
59
+ ```bash
60
+ export AI_AGENT="your-tool-name"
61
+ # or
62
+ AI_AGENT="your-tool-name" your-command
63
+ ```
64
+
65
+ ### Recommended Naming Convention
66
+
67
+ - Use lowercase with hyphens for multi-word names
68
+ - Include version information if needed, separated by an `@` symbol
69
+ - Examples: `claude-code`, `cursor-cli`, `devin@1`, `custom-agent@2.0`
70
+
71
+ ## Development
72
+
73
+ ```bash
74
+ uv sync --extra dev
75
+ uv run pytest
76
+ # Lint and format check (CI)
77
+ uv run ruff check . && uv run ruff format --check .
78
+ # Fix and format
79
+ uv run ruff check . --fix && uv run ruff format .
80
+ ```
81
+
82
+ ## Use Cases
83
+
84
+ ### Adaptive Behavior
85
+
86
+ ```python
87
+ from detect_agent import determine_agent
88
+ import os
89
+
90
+ def setup_environment():
91
+ result = determine_agent()
92
+
93
+ if (result["is_agent"]) {
94
+ # Running in AI environment - adjust behavior
95
+ os.environ.setdefault("TOGETHER_LOG", "debug")
96
+ print(f"🤖 Detected AI agent: {result["agent"]["name"]}");
97
+ ```
98
+
99
+ ### Telemetry and Analytics
100
+
101
+ ```python
102
+ from detect_agent import determine_agent
103
+
104
+ def track_usage(event: string):
105
+ result = determine_agent();
106
+
107
+ analytics.track(event, {
108
+ "agent": result["agent"]["name"] if result["is_agent"] else "human",
109
+ })
110
+ ```
111
+ ### Adding New Agent Support
112
+
113
+ To add support for a new AI agent:
114
+
115
+ 1. Add detection logic to `main.py`
116
+ 2. Add comprehensive test cases in `test.py`
117
+ 3. Update this README with the new agent information
118
+ 4. Follow the existing priority order pattern
@@ -0,0 +1,5 @@
1
+ detect_agent/__init__.py,sha256=jFCeNQyMjXSqwYRbQx3-IpeV1aKTX72pwjM_Tcy3TpM,3469
2
+ detect_agent/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ detect_agent-0.1.0.dist-info/METADATA,sha256=ZIF5W8J0e-slmiQuWOb3ndXGiaY2DbWysxf8Grv3bf8,3170
4
+ detect_agent-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
5
+ detect_agent-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any