How Agent Reach Auto-Detects Between Local Computer and Server Environments
Agent Reach uses a four-tier detection strategy in agent_reach/utils/paths.py that checks environment variables, CI indicators, TTY status, and config directory writability to determine whether it is running on a local workstation or a headless server.
Agent Reach is an open-source automation framework hosted in the Panniantong/Agent-Reach repository that must adapt its behavior depending on execution context. Understanding how Agent Reach auto-detects between local computer and server environments is essential for debugging configuration issues and ensuring your automation scripts behave correctly across different contexts.
The Detection Logic in agent_reach/utils/paths.py
The core classification logic resides in the is_server() function within agent_reach/utils/paths.py. This utility evaluates four distinct signals in sequence to classify the execution environment as either local or server.
Step 1: Check for Explicit Environment Variable Hint
The function first inspects the AGENT_REACH_ENV environment variable. If set to "server", the function immediately returns True. If set to "local", it returns False. This allows users to override automatic detection when necessary.
Step 2: Detect CI Environment Variables
When no explicit hint is present, the code checks for common CI environment variables. The presence of any of the following variables causes the function to classify the environment as a server: CI, GITHUB_ACTIONS, GITLAB_CI, or TRAVIS.
Step 3: Interactive TTY Fallback
If no CI variables are found, the function checks whether the process has an attached terminal using sys.stdin.isatty(). A return value of True indicates an interactive local session, while False suggests a headless server environment.
Step 4: Config Directory Writability Test
As a final safety net, the function attempts to create or write to the user-specific config directory ~/.agent-reach. If this operation fails due to read-only filesystem constraints common in CI containers, the environment is classified as a server.
# agent_reach/utils/paths.py
def is_server() -> bool:
"""Return True when running on a non‑interactive server/CI."""
# 1️⃣ explicit hint
env = os.getenv("AGENT_REACH_ENV", "").lower()
if env in ("server", "local"):
return env == "server"
# 2️⃣ CI detection
ci_vars = ("CI", "GITHUB_ACTIONS", "GITLAB_CI", "TRAVIS")
if any(os.getenv(v) for v in ci_vars):
return True
# 3️⃣ TTY check
if sys.stdin.isatty():
return False
# 4️⃣ Config‑dir writability test
try:
Config()._ensure_dir()
return False
except OSError:
return True
How Detection Results Drive Behavior Across the Codebase
The is_server() function is imported throughout the Agent Reach codebase to conditionally adjust behavior. The result is cached in Config.is_server and consulted by the CLI, doctor, and configuration manager.
CLI Output Adjustments in agent_reach/cli.py
The CLI entry point uses the detection result to toggle between interactive and quiet modes. When is_server() returns True, the application disables colorful output and progress bars suitable for headless environments.
# agent_reach/cli.py (excerpt)
from .utils.paths import is_server
def main():
if is_server():
# no colourful output, no progress bars
logger.info("Running in head‑less/server mode")
else:
# interactive prompts, colour, progress bars
logger.info("Running on a local workstation")
Diagnostic Reporting in agent_reach/doctor.py
The doctor command imports is_server() to report the detected environment in its diagnostics output, helping users verify their current execution context.
# agent_reach/doctor.py (excerpt)
from .utils.paths import is_server
def run():
env = "server" if is_server() else "local"
print(f"Environment detected: {env}")
Credential Safety in agent_reach/config.py
The configuration manager uses the detection to prevent accidental credential storage on servers. When running in server mode, it refuses to write sensitive keys ending in "token" or "key".
# agent_reach/config.py (excerpt)
from .utils.paths import is_server
def set(self, key: str, value: Any):
if is_server() and key.lower().endswith(("token", "key")):
raise RuntimeError("Refusing to store credentials on a non‑interactive server")
self.data[key] = value
self.save()
Summary
- The
is_server()function inagent_reach/utils/paths.pyimplements a four-tier detection strategy to auto-detect between local computer and server environments. - Detection follows this priority order: explicit
AGENT_REACH_ENVvariable → CI environment variables → TTY check → config directory writability test. - The result is cached and used by
agent_reach/cli.py,agent_reach/doctor.py, andagent_reach/config.pyto adapt logging, diagnostics, and security behaviors. - Local environments receive interactive output with colors and progress bars, while server environments run headless with safety guards against credential leakage.
Frequently Asked Questions
How can I force Agent Reach to run in server mode regardless of environment detection?
Set the environment variable AGENT_REACH_ENV=server before executing any commands. This bypasses all automatic detection logic in agent_reach/utils/paths.py and forces the application to behave as if it were running on a headless server.
Why does Agent Reach detect my local terminal as a server environment?
If is_server() returns True on your local machine, check that your terminal is a proper TTY and that you have write permissions to ~/.agent-reach. Containerized environments or redirected stdin/stdout (e.g., piping commands) may cause sys.stdin.isatty() to return False, triggering server mode detection.
Which CI platforms are automatically detected by Agent Reach?
The code explicitly checks for CI, GITHUB_ACTIONS, GITLAB_CI, and TRAVIS environment variables. If any of these are present, the environment is classified as a server regardless of other signals.
Can I use the is_server() function in my own Agent Reach extensions?
Yes, you can import is_server() from agent_reach.utils.paths to ensure your custom plugins respect the same environment detection rules as the core application. This maintains consistency in logging, interactivity, and security checks across the entire codebase.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →