This commit is contained in:
jif-oai
2025-10-14 14:03:15 +01:00
parent 9320565658
commit f073bc5ccf
4 changed files with 303 additions and 6 deletions

View File

@@ -0,0 +1,229 @@
# Codex Infty
Codex Infty is a small orchestration layer that coordinates multiple Codex roles (Solver, Director, Verifier(s)) to drive longer, multistep objectives with minimal human intervention. It provides:
- A run orchestrator that routes messages between roles and advances the workflow.
- A durable run store on disk with metadata and standard subfolders.
- Default role prompts for Solver/Director/Verifier.
- A lightweight progress reporting hook for UIs/CLIs.
The crate is designed to be embedded (via the library API) and also powers the `codex infty` CLI commands.
## HighLevel Flow
```
objective → Solver
Solver → direction_request → Director → directive → Solver
Solver → verification_request → Verifier(s) → aggregated summary → Solver
… (iterate) …
Solver → final_delivery → Orchestrator returns RunOutcome
```
- The Solver always speaks structured JSON. The orchestrator parses those messages and decides the next hop.
- The Director provides crisp guidance (also JSON) that is forwarded back to the Solver.
- One or more Verifiers assess claims and return verdicts; the orchestrator aggregates results and reports a summary to the Solver.
- On final_delivery, the orchestrator resolves and validates the deliverable path and returns the `RunOutcome`.
## Directory Layout (Run Store)
When a run is created, a directory is initialized with this structure:
```
<runs_root>/<run_id>/
artifacts/ # longlived artifacts produced by the Solver
memory/ # durable notes, claims, context
index/ # indexes and caches
deliverable/ # final output(s) assembled by the Solver
run.json # run metadata (id, timestamps, roles)
```
See: `codex-infty/src/run_store.rs`.
- The orchestrator persists rollout paths and optional config paths for each role into `run.json`.
- Metadata timestamps are updated on significant events (role spawns, handoffs, final delivery).
- Final deliverables must remain within the run directory. Paths are canonicalized and validated.
## Roles and Prompts
Default base instructions are injected per role if the provided `Config` has none:
- Solver: `codex-infty/src/prompts/solver.md`
- Director: `codex-infty/src/prompts/director.md`
- Verifier: `codex-infty/src/prompts/verifier.md`
You can provide your own instructions by prepopulating `Config.base_instructions`.
## Solver Signal Contract
The Solver communicates intent using JSON messages (possibly wrapped in a fenced block). The orchestrator accepts three shapes:
- Direction request (sent to Director):
```json
{"type":"direction_request","prompt":"<question or decision>"}
```
- Verification request (sent to Verifier(s)):
```json
{"type":"verification_request","claim_path":"memory/claims/<file>.json","notes":null}
```
- Final delivery (completes the run):
```json
{"type":"final_delivery","deliverable_path":"deliverable/summary.txt","summary":"<short text>"}
```
JSON may be fenced as ```json … ```; the orchestrator will strip the fence.
## Key Types and Modules
- Orchestrator: `codex-infty/src/orchestrator.rs`
- `InftyOrchestrator`: spawns/resumes role sessions, drives the event loop, and routes signals.
- `execute_new_run` / `execute_existing_run`: oneshot helpers that spawn/resume and then drive.
- `spawn_run` / `resume_run`: set up sessions and the run store.
- `call_role`, `relay_assistant_to_role`, `post_to_role`, `await_first_assistant`, `stream_events`: utilities when integrating custom flows.
- Run store: `codex-infty/src/run_store.rs`
- `RunStore`, `RunMetadata`, `RoleMetadata`: metadata and persistence helpers.
- Types: `codex-infty/src/types.rs`
- `RoleConfig`: wraps a `Config` and sets sensible defaults for autonomous flows (no approvals, full sandbox access). Also used to persist optional config paths.
- `RunParams`, `ResumeParams`: input to spawn/resume runs.
- `RunExecutionOptions`: perrun options (objective, timeouts).
- `RunOutcome`: returned on successful final delivery.
- Signals: `codex-infty/src/signals.rs`
- DTOs for director responses and verifier verdicts, and the aggregated summary type.
- Progress: `codex-infty/src/progress.rs`
- `ProgressReporter` trait: hook for UIs/CLIs to observe solver/director/verifier activity.
## Orchestrator Workflow (Details)
1. Spawn or resume role sessions (Solver, Director, and zero or more Verifiers). Default prompts are applied if the roles `Config` has no base instructions.
2. Optionally post an `objective` to the Solver. The progress reporter is notified and the orchestrator waits for the first Solver signal.
3. On `direction_request`:
- Post a structured request to the Director and await the first assistant message.
- Parse it into a `DirectiveResponse` and forward the normalized JSON to the Solver.
4. On `verification_request`:
- Send structured requests to each Verifier and await each first assistant message.
- Aggregate verdicts into an `AggregatedVerifierVerdict` and post the summary back to the Solver.
5. On `final_delivery`:
- Canonicalize and validate that `deliverable_path` stays within the run directory.
- Notify the progress reporter, touch the run store, and return `RunOutcome`.
Note: The orchestrator does not rerun verification after `final_delivery`. Verification is performed whenever the Solver issues a `verification_request` during the run.
## Library Usage
```rust
use std::sync::Arc;
use codex_core::{CodexAuth, config::Config};
use codex_infty::{InftyOrchestrator, RoleConfig, RunParams, RunExecutionOptions};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 1) Load or build a Config for each role
let solver_cfg: Config = load_config();
let mut director_cfg = solver_cfg.clone();
director_cfg.model = "o4-mini".into();
// 2) Build role configs
let solver = RoleConfig::new("solver", solver_cfg.clone());
let director = RoleConfig::new("director", director_cfg);
let verifiers = vec![RoleConfig::new("verifier-alpha", solver_cfg.clone())];
// 3) Create an orchestrator (using default runs root)
let auth = CodexAuth::from_api_key("sk-…");
let orchestrator = InftyOrchestrator::new(auth)?;
// 4) Execute a new run with an objective
let params = RunParams {
run_id: "my-run".into(),
run_root: None, // use default ~/.codex/infty/<run_id>
solver,
director,
verifiers,
};
let mut opts = RunExecutionOptions::default();
opts.objective = Some("Implement feature X".into());
let outcome = orchestrator.execute_new_run(params, opts).await?;
println!("deliverable: {}", outcome.deliverable_path.display());
Ok(())
}
# fn load_config() -> codex_core::config::Config { codex_core::config::Config::default() }
```
Resuming an existing run:
```rust
use codex_infty::{InftyOrchestrator, ResumeParams, RoleConfig};
async fn resume_example(orchestrator: &InftyOrchestrator) -> anyhow::Result<()> {
let solver = RoleConfig::new("solver", load_config());
let director = RoleConfig::new("director", load_config());
let verifiers = vec![];
let resume = ResumeParams {
run_path: std::path::PathBuf::from("/path/to/run"),
solver,
director,
verifiers,
};
let outcome = orchestrator.execute_existing_run(resume, Default::default()).await?;
println!("{}", outcome.run_id);
Ok(())
}
# fn load_config() -> codex_core::config::Config { codex_core::config::Config::default() }
```
## CLI Quickstart
The CLI (`codex`) exposes Infty helpers under the `infty` subcommand. Examples:
```bash
# Create a run and immediately drive toward completion
codex infty create --run-id demo --objective "Build and test feature"
# Inspect runs
codex infty list
codex infty show demo
# Send a one-off message to a role in a running/resumable run
codex infty drive demo solver "Summarize progress"
```
Flags allow customizing the Directors model and reasoning effort; see `codex infty create --help`.
## Progress Reporting
Integrate your UI by implementing `ProgressReporter` and attaching it with `InftyOrchestrator::with_progress(...)`. Youll receive callbacks on key milestones (objective posted, solver messages, director response, verification summaries, final delivery, etc.).
## Safety and Guardrails
- `RoleConfig::new` sets `SandboxPolicy::DangerFullAccess` and `AskForApproval::Never` to support autonomous flows. Adjust if your environment requires stricter policies.
- Deliverable paths are validated to stay inside the run directory and are fully canonicalized.
- JSON payloads are schemachecked where applicable (e.g., solver signals and final delivery shape).
## Tests
Run the crates tests:
```bash
cargo test -p codex-infty
```
Many tests rely on mocked SSE streams and will autoskip in sandboxes where network is disabled.
## When to Use This Crate
Use `codex-infty` when you want a minimal, pragmatic multirole loop with:
- Clear role separation and routing.
- Durable, restartresilient state on disk.
- Simple integration points (progress hooks and helper APIs).
Its intentionally small and focused so it can be embedded into larger tools or extended to meet your workflows.