Skip to content

Wire --concurrent flag and close concurrent execution gaps - #1036

Merged
jwbron merged 8 commits into
mainfrom
egg/concurrent-cli-gaps
Mar 12, 2026
Merged

Wire --concurrent flag and close concurrent execution gaps#1036
jwbron merged 8 commits into
mainfrom
egg/concurrent-cli-gaps

Conversation

@james-in-a-box

Copy link
Copy Markdown
Contributor

Summary

PR #1031 added concurrent agent execution infrastructure but left no CLI surface to enable it. This PR closes the activation gaps:

  • egg-sdlc --concurrent: New flag passes config={"concurrent_execution": true} to the orchestrator when creating pipelines in both issue and local mode. Also wired through _restart_pipeline() so restarts preserve the setting.
  • egg-orch pipeline create --concurrent: Same flag on the lower-level CLI, passes config in the API request body.
  • egg-pipeline-watch concurrent status: Full DAG mode now shows agent readiness states, consensus progress, and message bus stats. Compact mode shows a condensed agent state indicator.
  • Docs: docs/guides/sdlc-pipeline.md now documents the --concurrent CLI flag with usage examples, in addition to the existing config JSON reference.
  • orch_cli.py docstring: Added the 4 missing concurrent-mode commands (message send/poll/status, signal readiness).

The critical gap (consensus-driven phase advancement) is tracked in #1035.

Issue: #1035

Test plan:

  • All 3 modified Python files pass py_compile
  • Run egg-sdlc -r egg -i <n> --concurrent and verify pipeline is created with concurrent_execution: true in config
  • Run egg-orch pipeline create --repo owner/repo --concurrent and verify config in response
  • Run egg-pipeline-watch against a concurrent pipeline and verify agent readiness / consensus / message stats render

Repository owner deleted a comment from james-in-a-box Bot Mar 12, 2026
Repository owner deleted a comment from james-in-a-box Bot Mar 12, 2026
Repository owner deleted a comment from james-in-a-box Bot Mar 12, 2026
Repository owner deleted a comment from james-in-a-box Bot Mar 12, 2026
Repository owner deleted a comment from james-in-a-box Bot Mar 12, 2026
Repository owner deleted a comment from james-in-a-box Bot Mar 12, 2026
Repository owner deleted a comment from james-in-a-box Bot Mar 12, 2026
Repository owner deleted a comment from james-in-a-box Bot Mar 12, 2026
Repository owner deleted a comment from james-in-a-box Bot Mar 12, 2026
@james-in-a-box

This comment has been minimized.

@james-in-a-box

james-in-a-box Bot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor Author
Autofix tracking
{"Lint/Python": 3}

@james-in-a-box

This comment has been minimized.

@james-in-a-box

This comment has been minimized.

@james-in-a-box

This comment has been minimized.

@james-in-a-box

This comment has been minimized.

@james-in-a-box

This comment has been minimized.

@egg-reviewer egg-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No agent-mode design concerns. This PR is pure CLI infrastructure: wiring the --concurrent flag through existing entry points and adding concurrent status rendering to egg-pipeline-watch. No agent prompts, pre-fetching, structured output requirements, or LLM API calls involved.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@egg-reviewer egg-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thorough review complete. This is a clean, well-structured PR that correctly wires the --concurrent flag through all the right paths. No blocking issues found.

Verified

  • OrchClient.create_pipeline() already accepts a config parameter — the PR correctly uses it.
  • Both CLI paths (orch_cli.py via orch_request and sdlc_cli.py via OrchClient) send config as JSON body correctly.
  • All three callers of _restart_pipeline() pass the new config parameter.
  • --concurrent and --network-mode operate on different keys in the request body — no overwrite risk.
  • egg-pipeline-watch rendering handles both dict and str forms of agent info correctly.
  • Docstring additions in orch_cli.py accurately reflect commands that already exist from #1031.

Non-blocking suggestions

1. Duplicate config construction in run_issue_mode (sdlc_cli.py)

The expression {"concurrent_execution": True} if concurrent else None is repeated three times (lines 483, 507, 537). Build it once at the top of the function:

def run_issue_mode(client, issue_number, repo=None, concurrent=False):
    ...
    config: dict[str, object] | None = {"concurrent_execution": True} if concurrent else None
    ...
    # Then reuse `config` at lines 507 and 537 instead of rebuilding it

Line 507 already reassigns config to the same value it already holds. Line 537 creates a separate config2 variable with the identical expression. Both are unnecessary — just reuse the one defined at line 483.

2. Readability of compact agent rendering (egg-pipeline-watch:139-141)

Lines 139-141 pack a lot into two lines:

state_icons = {"READY": GREEN + "R", "WORKING": CYAN + "W", "BLOCKED": YELLOW + "B", "OBJECTING": RED + "X"}
parts = [f"{state_icons.get(info.get('state', 'WORKING') if isinstance(info, dict) else str(info), DIM + '?')}{RESET}" for _, info in sorted(agents.items())]

The second line is ~180 characters with nested .get() calls, isinstance, and a ternary inside an f-string inside a list comprehension. Consider breaking it into a small loop (like _render_concurrent_info already does for the full-mode rendering), or at least extract the key lookup:

def _agent_icon(info, state_icons):
    state = info.get("state", "WORKING") if isinstance(info, dict) else str(info)
    return f"{state_icons.get(state, DIM + '?')}{RESET}"

3. Missing tests

No tests were added for the new concurrent parameter in run_issue_mode, run_local_mode, _restart_pipeline, or cmd_pipeline_create. A basic test verifying that concurrent=True results in config={"concurrent_execution": True} being passed to create_pipeline would catch regressions.

@james-in-a-box

This comment has been minimized.

@james-in-a-box

This comment has been minimized.

@james-in-a-box

Copy link
Copy Markdown
Contributor Author

All three suggestions addressed in 3b45548:

  1. Duplicate config construction — Moved config assignment to the top of run_issue_mode() and reused it in all three call sites. Removed the redundant config2 variable.

  2. Compact agent icon readability — Extracted _agent_icon() helper and a module-level _STATE_ICONS dict. The list comprehension is now a clean one-liner.

  3. Tests — Added 6 tests covering _restart_pipeline, run_local_mode, and run_issue_mode with concurrent=True/False, verifying the config dict passed to create_pipeline.

All 7519 tests pass, lint clean.

@james-in-a-box

This comment has been minimized.

@egg-reviewer egg-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No agent-mode design concerns in the delta. The changes since last review (3b45548) address code quality feedback: DRY config construction, extracted icon helper, and new tests. No agent prompts, pre-fetching, or LLM API changes involved.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@jwbron
jwbron merged commit 668f128 into main Mar 12, 2026
28 checks passed

@egg-reviewer egg-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed the delta from 3ace31c to 3b45548. All three suggestions from the previous review were properly addressed.

Verified

1. DRY config construction (fixed)

config is now assigned once at line 479 of sdlc_cli.py and reused in all three call sites (lines 491, 515, 544). The redundant re-assignment and config2 variable are both gone. Traced the code to confirm config is never mutated between uses — it's only passed through as a kwarg.

2. Readable agent icon helper (fixed)

_STATE_ICONS dict and _agent_icon() function are extracted to module level in egg-pipeline-watch. The list comprehension is now a clean one-liner:

parts = [_agent_icon(info) for _, info in sorted(agents.items())]

Verified that _agent_icon handles all state types correctly: dict with known state, dict with unknown state, dict with no state key (defaults to WORKING), and non-dict values (falls back to ?). The full-mode _render_concurrent_info correctly keeps its own state_colors dict since it maps to colors only (not icons).

3. Tests added (fixed)

6 tests covering _restart_pipeline, run_local_mode, and run_issue_mode with concurrent=True/False. All 6 pass. Tests correctly verify that config={"concurrent_execution": True} (or None) is forwarded to create_pipeline.

No new issues introduced.

— Authored by egg

@james-in-a-box

Copy link
Copy Markdown
Contributor Author

egg review completed. View run logs

11 previous review(s) hidden.

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