Skip to content

fix(cli): add local_development.redis_enabled manifest opt-out (MAY-1086)#365

Open
IdkwhatImD0ing wants to merge 3 commits into
nextfrom
fix/may-1086-redis-enabled-manifest-flag
Open

fix(cli): add local_development.redis_enabled manifest opt-out (MAY-1086)#365
IdkwhatImD0ing wants to merge 3 commits into
nextfrom
fix/may-1086-redis-enabled-manifest-flag

Conversation

@IdkwhatImD0ing
Copy link
Copy Markdown
Contributor

@IdkwhatImD0ing IdkwhatImD0ing commented May 25, 2026

Summary

  • agentex agents run unconditionally sets REDIS_URL=redis://localhost:6379 in the agent process env. Combined with the module-level RedisStreamRepository from from agentex.lib import adk, agents that don't actually use adk.messages/adk.streaming see silent request hangs when no local Redis is reachable (e.g. Temporal-direct async agents running in restricted dev pods). The lazy redis.asyncio client only fails on first publish, so there's no startup error to surface.
  • Add an explicit local_development.redis_enabled: bool = true (default) flag on the agent manifest. Default preserves existing behavior; users with no local Redis can set false to opt out of the REDIS_URL default.
  • acp_type is not a reliable discriminator: examples/tutorials/10_async/00_base/110_pydantic_ai and 100_langgraph are acp_type: async and legitimately call adk.messages.create(...); several acp_type: sync tutorials also use adk.messages. Hence the explicit per-manifest opt-out instead of an acp_type-based rule.

Files

  • src/agentex/lib/sdk/config/local_development_config.py — new redis_enabled: bool = True field on LocalDevelopmentConfig.
  • src/agentex/lib/cli/handlers/run_handlers.pycreate_agent_environment skips the REDIS_URL default when local_development.redis_enabled is false.

Example manifest opt-out

local_development:
  agent:
    port: 8000
  redis_enabled: false

Test plan

  • rye run pyright on modified files — 0 errors.
  • rye run ruff check on modified files — clean.
  • Manual round-trip: default → REDIS_URL set; redis_enabled: falseREDIS_URL absent (verified against examples/tutorials/10_async/00_base/110_pydantic_ai/manifest.yaml).
  • Related test (tests/... matching local_development|run_handlers|manifest) passes.
  • Reviewer: confirm default-true is the right backwards-compat call vs. inverting to default-false.

Linear

MAY-1086

🤖 Generated with Claude Code

Greptile Summary

This PR adds a local_development.redis_enabled: bool = True field to LocalDevelopmentConfig and gates the automatic REDIS_URL=redis://localhost:6379 injection in create_agent_environment on that flag. The fix addresses silent request hangs in dev pods where no local Redis is reachable.

  • local_development_config.py: Adds redis_enabled field with default=True to preserve existing behavior; agents that don't use adk.messages/adk.streaming can set it to false.
  • run_handlers.py: The conditional now sets REDIS_URL in env_vars when opted in, and actively pops any inherited parent-shell REDIS_URL when opted out — ensuring the opt-out is clean even when the shell exports the variable.
  • test_run_handlers.py: Three parametric scenarios cover the default, opt-out-clean, and opt-out-with-stale-parent-env cases.

Confidence Score: 5/5

Safe to merge; the change is an additive opt-out flag with a backward-compatible default, and the core env-mutation logic is correctly ordered relative to the final env.update call.

The new field defaults to True, so all existing manifests see no behavior change. The opt-out path pops REDIS_URL from the os.environ snapshot before env.update(env_vars) is called, so the removal is durable. Tests cover the three relevant scenarios. No other code paths are affected.

No files require special attention.

Important Files Changed

Filename Overview
src/agentex/lib/sdk/config/local_development_config.py Adds redis_enabled: bool = Field(default=True) to LocalDevelopmentConfig; straightforward Pydantic field addition with no issues.
src/agentex/lib/cli/handlers/run_handlers.py Gates REDIS_URL injection on manifest.local_development.redis_enabled; opt-out path correctly pops the key from the inherited os.environ snapshot before env.update(env_vars) runs.
tests/lib/cli/test_run_handlers.py New test file covering default-true, explicit opt-out with clean env, and opt-out with stale parent-shell REDIS_URL; YAML template correctly places redis_enabled as a sibling of agent under local_development.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[create_agent_environment] --> B["env = dict(os.environ)"]
    B --> C["Build env_vars: TEMPORAL_ADDRESS, AGENT_NAME, ACP_TYPE, ACP_URL, ACP_PORT"]
    C --> D{"manifest.local_development.redis_enabled?"}
    D -- "True (default)" --> E["env_vars['REDIS_URL'] = 'redis://localhost:6379'"]
    D -- "False" --> F["env.pop('REDIS_URL', None)"]
    E --> G["Apply agent_config.env overrides to env_vars"]
    F --> G
    G --> H["env.update(env_vars)"]
    H --> I["return env"]
Loading

Reviews (3): Last reviewed commit: "test(cli): decouple run_handlers tests f..." | Re-trigger Greptile

…086)

agentex agents run unconditionally sets REDIS_URL=redis://localhost:6379 in
the agent process env. Combined with the module-level RedisStreamRepository
instantiated by `from agentex.lib import adk`, this causes silent request
hangs for agents that don't use adk.messages/adk.streaming when no local
Redis is reachable (e.g. Temporal-direct async agents in restricted dev
pods). The lazy redis.asyncio client only fails on first publish, so there
is no startup error to point at the misconfiguration.

Add an explicit `local_development.redis_enabled: bool = true` flag.
Default true preserves existing behavior; users with no local Redis can
set false to skip the REDIS_URL default. acp_type is not a reliable
discriminator here — the codebase has acp_type=async tutorials that
legitimately call adk.messages.create.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Comment thread src/agentex/lib/cli/handlers/run_handlers.py Outdated
Address staff-engineer review on #365:

- Pop REDIS_URL from the inherited env when redis_enabled is false. The
  previous implementation only avoided seeding a default, so a stale
  REDIS_URL exported by the parent shell still leaked into the agent
  process and reproduced the same silent hang the opt-out was meant to
  prevent.
- Drop the unreachable `local_development is None` short-circuit; the
  dict literal above already dereferences manifest.local_development with
  a # type: ignore[union-attr], so the None branch can never run.
- Add tests/lib/cli/test_run_handlers.py covering the three branches:
  default seeds REDIS_URL, opt-out with clean parent env clears it,
  opt-out with a parent-shell REDIS_URL still clears it.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@IdkwhatImD0ing
Copy link
Copy Markdown
Contributor Author

Follow-up commit f41703c9 addresses the staff-engineer review:

  1. Parent-env REDIS_URL leak (High)create_agent_environment now env.pop("REDIS_URL", None) in the opt-out branch, so a stale REDIS_URL from the parent shell can't survive redis_enabled: false. This was the same silent-hang bug the opt-out was meant to prevent.
  2. Unreachable is None guard (Medium) — Dropped. The dict literal a few lines above already dereferences manifest.local_development.agent.X with # type: ignore[union-attr], so the None arm was dead code. The new conditional mirrors that same # type: ignore.
  3. No test coverage (Medium) — Added tests/lib/cli/test_run_handlers.py with three cases: default seeds REDIS_URL, opt-out with clean parent env, opt-out with a stale parent-shell REDIS_URL. All pass.

Deferring the other review points:

  • redis_enabled naming — agree it's slightly misleading; happy to rename to seed_redis_url (or similar) if you prefer, but figured the parent-env leak was the load-bearing fix.
  • TEMPORAL_ADDRESS asymmetry — same bug class but lower urgency (Temporal already gated by is_temporal_agent() and fails loudly). Worth a separate ticket; let me know if you want me to file it.
  • from pydantic import validator (v1 import) — pre-existing in local_development_config.py, not introduced here. Out of scope for this PR.

Use a tmp_path YAML fixture rendered from a minimal inline template
instead of reading examples/tutorials/.../manifest.yaml, so the test
survives tutorial renames or removals while still exercising the real
AgentManifest.from_yaml loader.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.

1 participant