Skip to content

Collaboration

build_cli_collaboration makes Claude Code and Codex work together on a task — Claude Code analyses, Codex critiques, a synthesizer plans, an executor implements — packaged as a single tool, the same way you'd pass claude_code or codex.

from lazytools.connectors.code_support import build_cli_collaboration

build_cli_collaboration(
    *,
    name: str = "cli_collaboration",
    description: str | None = None,
    claude_model: str = "claude-opus-4-8",
    codex_model: str = "gpt-5.4",
    synthesizer_model: str = "claude-opus-4-8",
    executor_model: str = "claude-opus-4-8",
    execute: bool = True,
) -> Agent

It returns a named Agent whose engine is a four-step Plan. Because an Agent is a tool in LazyBridge, the whole pipeline looks to the parent agent like one callable that takes a single task string.

Step 1  claude_analyst   claude_code(read)   analyse, propose an approach
Step 2  codex_analyst    codex(read)         critique/confirm  (sees step 1 via shared Memory)
Step 3  synthesizer      —                   merge into one concrete plan
Step 4  executor         claude_code(write)  implement the plan        (skipped when execute=False)
Parameter Type Default Meaning
name str "cli_collaboration" Tool name the parent agent sees (tool-map key).
description str \| None None Tool description shown to the parent LLM; a sensible default is used when None.
claude_model str "claude-opus-4-8" Model for the Claude-Code analyst (step 1).
codex_model str "gpt-5.4" Model for the Codex analyst/critic (step 2).
synthesizer_model str "claude-opus-4-8" Model that merges the analyses (step 3).
executor_model str "claude-opus-4-8" Model that implements the plan (step 4).
execute bool True True → implement (writes files). False → stop after synthesis (read-only "analyse + plan").

Examples

from lazytools.connectors.code_support import build_cli_collaboration

# The whole Claude Code + Codex pipeline as a single tool.
pipeline = build_cli_collaboration()
print(pipeline("Add rate limiting to the /api/login endpoint").text())
from lazybridge import Agent, LLMEngine
from lazytools.connectors.code_support import build_cli_collaboration

# Hand the collaboration to a higher-level orchestrator, alongside any
# other tools — it behaves like any other tool that takes a task string.
orchestrator = Agent(
    engine=LLMEngine("claude-opus-4-8"),
    tools=[build_cli_collaboration(name="deep_code_task")],
)
orchestrator("Use deep_code_task to add retries to the HTTP client")
from lazytools.connectors.code_support import build_cli_collaboration

# execute=False stops after synthesis — never writes files.
planner = build_cli_collaboration(execute=False)
print(planner("Propose a refactor of the payments module").text())

Why Plan, not AgentPool?

The flow is fixed and sequential (analyse → critique → synthesise → execute). Plan with from_step is simpler and more predictable, and each step frees memory before the next. Reach for AgentPool only when you need dynamic routing or a multi-round back-and-forth.

Pitfalls

  • Writes by default (execute=True). Pass execute=False for an analyse-and-plan-only run.
  • Shared Memory is sequential-only. The pipeline's dialogue memory is safe because Plan steps don't overlap; don't reuse the pattern under parallel execution without a per-agent memory.
  • Both CLIs must be installed and authenticated — the pipeline drives claude_code and codex in CLI mode. Run check_clis_available() first.

See also