Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/next-release/enhancement-UserAgent-53908.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type": "enhancement",
"category": "User Agent",
"description": "Expose ``is_agentic_caller`` so callers can detect the agentic callers already reported in the User-Agent."
}
17 changes: 17 additions & 0 deletions awscli/botocore/useragent.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,23 @@ def _agentic_env_var_is_set(env_var, expected_value):
return value == expected_value


def is_agentic_caller():
"""Return True if the current process appears to be driven by a known
agentic caller (e.g. Claude Code, Gemini CLI, Codex).

Detection uses the same environment-variable signals that populate the
``AGENTIC_CALLER_*`` metrics in the User-Agent header, so callers that
want to adapt their behavior for agents stay in sync with what the SDK
already reports.
"""
return any(
_agentic_env_var_is_set(env_var, expected_value)
for env_var, _feature_id, expected_value in (
_USERAGENT_AGENTIC_CALLER_ENV_VAR_MAPPINGS
)
)


def _register_agentic_caller_env_features():
for (
env_var,
Expand Down
35 changes: 35 additions & 0 deletions tests/unit/botocore/test_useragent.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
UserAgentComponent,
UserAgentComponentSizeConfig,
UserAgentString,
is_agentic_caller,
register_feature_id,
sanitize_user_agent_string_component,
)
Expand Down Expand Up @@ -78,6 +79,40 @@ def test_sanitize_ua_string_component(raw_str, allow_hash, expected_str):
assert actual_str == expected_str


def test_is_agentic_caller_false_when_no_env_set():
# clear_agentic_caller_env fixture unsets all agentic caller env vars.
assert is_agentic_caller() is False


@pytest.mark.parametrize(
'env_var, value',
[
('CLAUDECODE', '1'),
('GEMINI_CLI', '1'),
('CODEX_THREAD_ID', 'some-thread-id'),
('KIRO_SESSION_ID', 'some-session-id'),
('OPENCODE', 'anything'),
('CURSOR_AGENT', '1'),
('PI_CODING_AGENT', 'true'),
],
)
def test_is_agentic_caller_true_when_env_set(monkeypatch, env_var, value):
monkeypatch.setenv(env_var, value)
assert is_agentic_caller() is True


def test_is_agentic_caller_false_when_value_does_not_match(monkeypatch):
# CLAUDECODE only counts when it equals '1'.
monkeypatch.setenv('CLAUDECODE', '0')
assert is_agentic_caller() is False


def test_is_agentic_caller_false_when_env_empty(monkeypatch):
# An env var expecting any non-empty value must not match ''.
monkeypatch.setenv('CODEX_THREAD_ID', '')
assert is_agentic_caller() is False


def test_basic_user_agent_string():
ua = UserAgentString(
platform_name='linux',
Expand Down
Loading