Skip to content

feat: add Pi provider and brainstorm benchmark variants#40

Merged
El-Fitz merged 6 commits into
mainfrom
feat/pi-provider-brainstorm-variants
Jun 1, 2026
Merged

feat: add Pi provider and brainstorm benchmark variants#40
El-Fitz merged 6 commits into
mainfrom
feat/pi-provider-brainstorm-variants

Conversation

@El-Fitz

@El-Fitz El-Fitz commented May 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add benchmark-only brainstorm iteration strategies behind hidden CLI config
  • add Pi provider adapter using Pi JSON event streams, with Pi/OpenCode/Codex as default provider set
  • update docs, TODOs, and handoff to prefer Pi-backed benchmark routing while keeping OpenCode supported

Verification

  • cargo fmt --all -- --check
  • cargo test -p tundish_providers
  • cargo test -p refinery_cli
  • cargo clippy --workspace --all-targets -- -D warnings
  • manual brainstorm dry-run with pi + opencode model specs

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new PiProvider adapter to support model routing via the pi CLI, updates default provider configurations, and implements experimental brainstorm iteration strategies (blind, score-only, own-reviews, full-visibility) behind a hidden CLI flag. The reviewer feedback focuses on code optimizations and robustness, specifically recommending direct comparison of ModelId instances to avoid string allocations during sorting, parsing numeric scores that may be returned as strings in JSON, and preserving the USERPROFILE environment variable on Windows to ensure cross-platform compatibility for the pi CLI.

Comment thread crates/refinery_core/src/brainstorm.rs Outdated
history_text.push_str("No peer evaluations were available for this answer.\n");
} else {
let mut reviews = entry.reviews.clone();
reviews.sort_by(|a, b| a.evaluator.to_string().cmp(&b.evaluator.to_string()));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Since ModelId implements Ord, you can compare the evaluators directly instead of converting them to String via to_string(). This avoids unnecessary string allocations during sorting.

Suggested change
reviews.sort_by(|a, b| a.evaluator.to_string().cmp(&b.evaluator.to_string()));
reviews.sort_by(|a, b| a.evaluator.cmp(&b.evaluator));

Comment thread crates/refinery_core/src/brainstorm.rs Outdated
for round in history {
let _ = writeln!(history_text, "<round number=\"{}\">", round.round);
let mut proposals: Vec<(&ModelId, &String)> = round.proposals.iter().collect();
proposals.sort_by(|(a, _), (b, _)| a.to_string().cmp(&b.to_string()));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Since ModelId implements Ord, you can compare the model IDs directly instead of converting them to String via to_string(). This avoids unnecessary string allocations during sorting.

Suggested change
proposals.sort_by(|(a, _), (b, _)| a.to_string().cmp(&b.to_string()));
proposals.sort_by(|(a, _), (b, _)| a.cmp(b));

history_text.push_str("<evaluations>\n");
let mut reviews = round.evaluations.get(model_id).cloned().unwrap_or_default();
reviews.sort_by(|a, b| a.evaluator.to_string().cmp(&b.evaluator.to_string()));
for review in reviews {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Since ModelId implements Ord, you can compare the evaluators directly instead of converting them to String via to_string(). This avoids unnecessary string allocations during sorting.

            reviews.sort_by(|a, b| a.evaluator.cmp(&b.evaluator));

Comment thread crates/refinery_core/src/brainstorm.rs Outdated
Comment on lines +232 to +234
let score = parsed
.get("score")
.and_then(|v| v.as_u64().map(|u| u as f64).or_else(|| v.as_f64()))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

LLMs sometimes return numeric scores as strings in JSON (e.g., "score": "8" instead of "score": 8). To make score parsing more robust and prevent evaluation failures, we should also attempt to parse string values as f64.

Suggested change
let score = parsed
.get("score")
.and_then(|v| v.as_u64().map(|u| u as f64).or_else(|| v.as_f64()))
let score = parsed
.get("score")
.and_then(|v| {
v.as_u64().map(|u| u as f64)
.or_else(|| v.as_f64())
.or_else(|| v.as_str().and_then(|s| s.parse::<f64>().ok()))
})

Comment thread crates/tundish_providers/src/pi.rs Outdated
Comment on lines +111 to +116
let home = std::env::var("HOME").ok();
let mut env_vars: Vec<(&str, &str)> =
vec![("PI_SKIP_VERSION_CHECK", "1"), ("PI_TELEMETRY", "0")];
if let Some(ref h) = home {
env_vars.push(("HOME", h.as_str()));
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

On Windows, the pi CLI might look for its configuration and credentials in the user's profile directory via the USERPROFILE environment variable rather than HOME. To ensure cross-platform compatibility, we should also preserve and pass USERPROFILE if it is set.

        let home = std::env::var("HOME").ok();
        let user_profile = std::env::var("USERPROFILE").ok();
        let mut env_vars: Vec<(&str, &str)> =
            vec![("PI_SKIP_VERSION_CHECK", "1"), ("PI_TELEMETRY", "0")];
        if let Some(ref h) = home {
            env_vars.push(("HOME", h.as_str()));
        }
        if let Some(ref up) = user_profile {
            env_vars.push(("USERPROFILE", up.as_str()));
        }

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 78c635fd-20c4-4400-8958-bc73b39bb53e

📥 Commits

Reviewing files that changed from the base of the PR and between eb29537 and 7966a7c.

📒 Files selected for processing (3)
  • crates/refinery_core/src/brainstorm.rs
  • docs/HANDOFF.md
  • todos/013-brainstorm-strategy-benchmarks.md
✅ Files skipped from review due to trivial changes (2)
  • todos/013-brainstorm-strategy-benchmarks.md
  • docs/HANDOFF.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/refinery_core/src/brainstorm.rs

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added Pi provider support enabling multi-provider model routing via pi/<provider>/<model> identifiers.
    • Introduced experimental --iteration-strategy option for brainstorm runs to control visibility of prior answers and evaluation scores across iterations.
    • Brainstorm runs now capture and report iteration strategy in outputs and benchmark analyses.
  • Documentation

    • Updated CLI examples to use new model identifier format (pi/openai/*, codex-cli, opencode/*).
    • Restructured credentials workflow with provider-local configuration guidance.

Walkthrough

Adds configurable brainstorm iteration strategies and wires them through core logic, CLI args, dry-run/JSON/text outputs, and benchmark metadata; implements a Pi CLI provider adapter with tool mapping and JSONL response parsing; updates model-spec parsing, shared schemas, tests, and documentation.

Changes

Brainstorm Iteration Strategy and Pi Provider Integration

Layer / File(s) Summary
Provider foundation: Cargo feature + module
crates/tundish_providers/Cargo.toml, crates/tundish_providers/src/lib.rs
Pi feature added to defaults; pi module declared and integrated into provider dispatch.
Pi provider implementation and JSONL parsing
crates/tundish_providers/src/pi.rs
PiProvider added with CLI-arg building, env passthrough, process spawn, and extract_pi_response JSONL parsing; includes unit tests for arg building, response extraction, and error propagation.
Pi tool mapping
crates/tundish_providers/src/tools.rs
pi_tool mapper added with unit test for canonical→pi tool name translations.
Model spec parsing and CLI validation
crates/refinery_cli/src/commands/common.rs
parse_model_spec reworked to require pi/<provider>/<model> or opencode/<provider>/<model>, preserve codex-cli alias, reject legacy provider shorthands, and add unit tests.
Shared DryRunOutput schema
crates/refinery_cli/src/commands/common.rs, crates/refinery_cli/src/commands/converge.rs, crates/refinery_cli/src/commands/synthesize.rs
Add optional iteration_strategy to DryRunOutput; converge and synthesize dry-run outputs set iteration_strategy: None.
Benchmark analyzer: metadata reading & reporting
crates/refinery_cli/src/commands/benchmark_brainstorm.rs
RunBenchmarkOutput gains optional iteration_strategy; RunMetadata added; load_run_metadata reads metadata.json (absent→Ok(None)); analyze_run and text output include iteration_strategy.
Brainstorm CLI wiring
crates/refinery_cli/src/commands/brainstorm.rs
Hidden --iteration-strategy arg added to BrainstormArgs (default score-only); wired into BrainstormConfig; outputs (dry-run and success JSON/text) include iteration_strategy.
Core brainstorm types and prompt builders
crates/refinery_core/src/brainstorm.rs
Add BrainstormIterationStrategy enum; add iteration_strategy to BrainstormConfig and BrainstormResult; implement strategy-specific prompt builders and evaluation parsing helpers.
Brainstorm loop, evaluation, and history tracking
crates/refinery_core/src/brainstorm.rs
Track per-evaluator review histories and visibility history; parse evaluation responses for score and rationale; adapt proposer prompts per strategy; save round artifacts with rationales; include iteration_strategy in results.
Metadata and artifact saving
crates/refinery_core/src/brainstorm.rs
Extend save_round_artifacts to accept round_reviews; evaluation artifacts include rationale; save_run_metadata writes metadata.json with iteration_strategy and key config.
Documentation: README CLI usage and credentials
README.md
Command examples updated to use pi/openai/*, codex-cli, opencode/*; credentials section restructured to provider-local tooling (Pi/OpenCode) and extraneous placeholders removed.
Documentation: commands README, handoff, plans, todos
crates/refinery_cli/src/commands/README.md, docs/HANDOFF.md, docs/plans/..., todos/*
Commands README updated with Pi/codex examples and benchmark guidance; handoff and plans/todos updated to record iteration_strategy work and next benchmark steps.
Environment example
.env.example
Replace example provider env vars with optional Codex CLI API key guidance and comment about local Pi/OpenCode credential management.

Sequence Diagram

sequenceDiagram
  participant User
  participant BrainstormCli
  participant BrainstormLoop
  participant PiProvider
  participant Storage

  User->>BrainstormCli: brainstorm --iteration-strategy blind
  BrainstormCli->>BrainstormLoop: start with BrainstormConfig(iteration_strategy)
  BrainstormLoop->>PiProvider: send_message(proposer prompt)
  PiProvider-->>BrainstormLoop: assistant text (proposals)
  BrainstormLoop->>Storage: save proposals & round artifacts
  BrainstormLoop->>PiProvider: send_message(evaluate proposals)
  PiProvider-->>BrainstormLoop: evaluation (score + rationale)
  BrainstormLoop->>Storage: save evaluation artifacts (include rationale)
  BrainstormLoop->>Storage: save metadata.json (iteration_strategy)
  BrainstormLoop-->>BrainstormCli: return BrainstormResult (with iteration_strategy)
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly Related PRs

Poem

🐰 I nibble prompts beneath the moon,
Pi hums JSON and whistles soon,
Strategies shuffle, scores take flight,
Proposals, rationales—saved each night,
A rabbit cheers the code's delight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 64.41% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: adding a Pi provider adapter and brainstorm benchmark iteration strategy variants.
Description check ✅ Passed The description is directly related to the changeset, covering the three main objectives: benchmark-only iteration strategies, Pi provider adapter, and documentation updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/pi-provider-brainstorm-variants

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
crates/refinery_cli/src/commands/common.rs (1)

295-311: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reject malformed nested model paths for pi/opencode in parser.

parse_model_spec currently accepts invalid specs like pi//gpt-5.4 and opencode//glm-5 because it only checks the first split. That allows bad input past CLI validation and fails later at provider/runtime.

Proposed fix
 pub fn parse_model_spec(input: &str) -> Result<ModelId, String> {
     if input.contains('/') {
         let (provider, model) = input.split_once('/').unwrap();
         if provider.is_empty() || model.is_empty() {
             return Err(format!("Invalid model spec: '{input}'"));
         }
+        if matches!(provider, "pi" | "opencode") {
+            let Some((subprovider, submodel)) = model.split_once('/') else {
+                return Err(format!(
+                    "Provider '{provider}' requires '<sub-provider>/<model>', got '{input}'"
+                ));
+            };
+            if subprovider.is_empty() || submodel.is_empty() {
+                return Err(format!(
+                    "Provider '{provider}' requires '<sub-provider>/<model>', got '{input}'"
+                ));
+            }
+        }
         Ok(ModelId::from_parts(provider, model))
     } else {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/refinery_cli/src/commands/common.rs` around lines 295 - 311, The
parser accepts malformed nested paths like "pi//gpt-5.4" because
parse_model_spec only checks the first split; update the branch that handles
input.contains('/') so after let (provider, model) =
input.split_once('/').unwrap() you also reject cases where provider or model are
empty or either contains additional '/' (e.g., model.contains('/') or
provider.contains('/')) or the input contains "//"; return Err(...) for those
cases instead of proceeding to ModelId::from_parts, ensuring valid
single-slashed specs only.
docs/plans/2026-05-23-001-research-brainstorm-strategy-benchmarks-plan.md (1)

11-13: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update the plan header review date for this edit pass.

This plan got a substantive update, but **Reviewed:** is still 2026-05-23. Please refresh it to the current review date using the required header format.

As per coding guidelines, "Update plan headers with review dates using format 'Reviewed: YYYY-MM-DD (via /$SKILL / $COMMAND)'".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/plans/2026-05-23-001-research-brainstorm-strategy-benchmarks-plan.md`
around lines 11 - 13, Update the plan header line that currently reads
"**Reviewed:** 2026-05-23 (via `/coderabbit / review`)" to the current review
date in the required format; replace the date token with today's YYYY-MM-DD and
keep the "(via `/$SKILL / $COMMAND`)" suffix (e.g., "**Reviewed:** 2026-05-28
(via `/coderabbit / review`)") so the header for the plan (the line beginning
with "**Reviewed:**") reflects the new review timestamp.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/refinery_core/src/brainstorm.rs`:
- Around line 349-350: The current manual compare using proposals.sort_by(|(a,
_), (b, _)| a.to_string().cmp(&b.to_string())) should be replaced with
proposals.sort_by_key(|(id, _)| id.to_string()) to satisfy the Clippy
unnecessary_sort_by lint; update the sorting call on the proposals Vec created
from round.proposals.iter().collect() accordingly so it uses sort_by_key with a
closure that returns id.to_string().
- Around line 360-362: Replace the unnecessary sort_by call on reviews with
sort_by_key to satisfy Clippy: instead of reviews.sort_by(|a, b|
a.evaluator.to_string().cmp(&b.evaluator.to_string())), call
reviews.sort_by_key(|r| r.evaluator.to_string()) so the sorting uses the
evaluator string as the key; update the code around the reviews variable in the
brainstorm logic where round.evaluations.get(model_id) is cloned and sorted.
- Around line 313-314: Replace the explicit comparator used in the reviews sort
with a key-based sort to satisfy Clippy: in the block where you clone
entry.reviews into let mut reviews and call reviews.sort_by(|a, b|
a.evaluator.to_string().cmp(&b.evaluator.to_string())), change it to use
reviews.sort_by_key(...) and provide the key extractor that returns
a.evaluator.to_string() (i.e., sort_by_key(|r| r.evaluator.to_string())). This
keeps behavior identical while removing the unnecessary_sort_by lint.

---

Outside diff comments:
In `@crates/refinery_cli/src/commands/common.rs`:
- Around line 295-311: The parser accepts malformed nested paths like
"pi//gpt-5.4" because parse_model_spec only checks the first split; update the
branch that handles input.contains('/') so after let (provider, model) =
input.split_once('/').unwrap() you also reject cases where provider or model are
empty or either contains additional '/' (e.g., model.contains('/') or
provider.contains('/')) or the input contains "//"; return Err(...) for those
cases instead of proceeding to ModelId::from_parts, ensuring valid
single-slashed specs only.

In `@docs/plans/2026-05-23-001-research-brainstorm-strategy-benchmarks-plan.md`:
- Around line 11-13: Update the plan header line that currently reads
"**Reviewed:** 2026-05-23 (via `/coderabbit / review`)" to the current review
date in the required format; replace the date token with today's YYYY-MM-DD and
keep the "(via `/$SKILL / $COMMAND`)" suffix (e.g., "**Reviewed:** 2026-05-28
(via `/coderabbit / review`)") so the header for the plan (the line beginning
with "**Reviewed:**") reflects the new review timestamp.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b75bc887-7d30-41ad-9c16-8f97f101369c

📥 Commits

Reviewing files that changed from the base of the PR and between c1643cd and 5a7a24d.

📒 Files selected for processing (17)
  • .env.example
  • README.md
  • crates/refinery_cli/src/commands/README.md
  • crates/refinery_cli/src/commands/benchmark_brainstorm.rs
  • crates/refinery_cli/src/commands/brainstorm.rs
  • crates/refinery_cli/src/commands/common.rs
  • crates/refinery_cli/src/commands/converge.rs
  • crates/refinery_cli/src/commands/synthesize.rs
  • crates/refinery_core/src/brainstorm.rs
  • crates/tundish_providers/Cargo.toml
  • crates/tundish_providers/src/lib.rs
  • crates/tundish_providers/src/pi.rs
  • crates/tundish_providers/src/tools.rs
  • docs/HANDOFF.md
  • docs/plans/2026-05-23-001-research-brainstorm-strategy-benchmarks-plan.md
  • todos/013-brainstorm-strategy-benchmarks.md
  • todos/022-opencode-concurrency-sqlite-wal.md
📜 Review details
🧰 Additional context used
📓 Path-based instructions (4)
.env*

📄 CodeRabbit inference engine (CLAUDE.md)

Copy .env.example to .env and fill in credentials for environment setup

Files:

  • .env.example
**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.rs: Run cargo test --workspace to run all tests
Use cargo build --workspace to build all crates

Files:

  • crates/tundish_providers/src/tools.rs
  • crates/refinery_cli/src/commands/converge.rs
  • crates/tundish_providers/src/lib.rs
  • crates/refinery_cli/src/commands/benchmark_brainstorm.rs
  • crates/tundish_providers/src/pi.rs
  • crates/refinery_cli/src/commands/common.rs
  • crates/refinery_cli/src/commands/synthesize.rs
  • crates/refinery_cli/src/commands/brainstorm.rs
  • crates/refinery_core/src/brainstorm.rs
docs/plans/**

📄 CodeRabbit inference engine (CLAUDE.md)

docs/plans/**: Update plan headers with enhancement dates using format 'Enhanced: YYYY-MM-DD (via /deepen-plan)'
Update plan headers with review dates using format 'Reviewed: YYYY-MM-DD (via /$SKILL / $COMMAND)'
Update plan headers with completion dates using format 'Completed: YYYY-MM-DD'
Add addendums to plans using format 'Addendum: YYYY-MM-DD — description of what was added and why'
Create a dedicated plan when picking up a milestone from a roadmap or general plan if the milestone does not have one

Files:

  • docs/plans/2026-05-23-001-research-brainstorm-strategy-benchmarks-plan.md
docs/HANDOFF.md

📄 CodeRabbit inference engine (CLAUDE.md)

Update docs/HANDOFF.md before compaction or at session end with project state, architecture gotchas, open work, and review process

Files:

  • docs/HANDOFF.md
🪛 GitHub Actions: CI / 0_Check.txt
crates/refinery_core/src/brainstorm.rs

[error] 314-314: Clippy (unnecessary_sort_by) failed: use sort_by_key instead of sort_by with a.evaluator.to_string().cmp(&b.evaluator.to_string()). Command: cargo clippy --workspace -- -D warnings.


[error] 350-350: Clippy (unnecessary_sort_by) failed: use sort_by_key instead of sort_by with a.to_string().cmp(&b.to_string()). Command: cargo clippy --workspace -- -D warnings.


[error] 361-361: Clippy (unnecessary_sort_by) failed: use sort_by_key instead of sort_by with a.evaluator.to_string().cmp(&b.evaluator.to_string()). Command: cargo clippy --workspace -- -D warnings.

🪛 GitHub Actions: CI / Check
crates/refinery_core/src/brainstorm.rs

[error] 314-314: Clippy (unnecessary_sort_by / clippy::unnecessary-sort-by): consider using sort_by_key. Replacing reviews.sort_by(|a, b| a.evaluator.to_string().cmp(&b.evaluator.to_string())) with reviews.sort_by_key(|a| a.evaluator.to_string()).


[error] 350-350: Clippy (unnecessary_sort_by / clippy::unnecessary-sort-by): consider using sort_by_key. Replacing proposals.sort_by(|(a, _), (b, _)| a.to_string().cmp(&b.to_string())) with proposals.sort_by_key(|(a, _)| a.to_string()).


[error] 361-361: Clippy (unnecessary_sort_by / clippy::unnecessary-sort-by): consider using sort_by_key. Replacing reviews.sort_by(|a, b| a.evaluator.to_string().cmp(&b.evaluator.to_string())) with reviews.sort_by_key(|a| a.evaluator.to_string()).

🔇 Additional comments (21)
crates/refinery_cli/src/commands/common.rs (1)

27-29: LGTM!

Also applies to: 135-137, 529-552

crates/refinery_core/src/brainstorm.rs (7)

17-57: LGTM!


200-243: LGTM!


245-265: LGTM!


389-411: LGTM!


450-455: LGTM!

Also applies to: 466-468, 486-498, 599-613, 685-704, 774-788, 804-804, 886-886


896-954: LGTM!


1029-1148: LGTM!

crates/tundish_providers/Cargo.toml (1)

9-14: LGTM!

crates/tundish_providers/src/lib.rs (2)

39-45: Run full Rust workspace verification before merge.

This PR changes multiple Rust files; please run cargo test --workspace and cargo build --workspace (not only package-scoped checks) to satisfy repo verification requirements.

As per coding guidelines, "**/*.rs: Run cargo test --workspace to run all testsandUse cargo build --workspace to build all crates`."


13-14: LGTM!

Also applies to: 30-31, 91-101

crates/tundish_providers/src/pi.rs (4)

38-88: LGTM!


90-135: LGTM!


137-247: LGTM!


248-319: LGTM!

crates/tundish_providers/src/tools.rs (1)

43-57: LGTM!

Also applies to: 101-107

crates/refinery_cli/src/commands/brainstorm.rs (2)

8-9: LGTM!

Also applies to: 35-37, 48-48, 168-168, 179-179, 206-206, 252-252, 312-312


35-37: Workspace Rust checks couldn’t run here—Rust toolchain default is missing.

cargo build --workspace / cargo test --workspace failed with: rustup could not choose a version of cargo ... no default is configured. Rerun after setting the toolchain (e.g., rustup default stable) or explicitly (e.g., cargo +stable build --workspace and cargo +stable test --workspace) before merge.

crates/refinery_cli/src/commands/converge.rs (1)

100-100: LGTM!

crates/refinery_cli/src/commands/synthesize.rs (1)

113-113: LGTM!

crates/refinery_cli/src/commands/benchmark_brainstorm.rs (1)

47-48: LGTM!

Also applies to: 86-89, 135-137, 157-157, 164-174, 476-478

Comment thread crates/refinery_core/src/brainstorm.rs Outdated
Comment thread crates/refinery_core/src/brainstorm.rs Outdated
Comment thread crates/refinery_core/src/brainstorm.rs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 59e0445226

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/tundish_providers/src/pi.rs Outdated
Comment on lines +112 to +115
let mut env_vars: Vec<(&str, &str)> =
vec![("PI_SKIP_VERSION_CHECK", "1"), ("PI_TELEMETRY", "0")];
if let Some(ref h) = home {
env_vars.push(("HOME", h.as_str()));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Forward Pi credential environment variables

When Pi credentials are supplied through environment variables (Pi's provider docs list OPENAI_API_KEY, ANTHROPIC_API_KEY, custom interpolation variables, etc. as credential sources), spawn_cli clears the child environment and this adapter only re-injects HOME plus telemetry flags. In shells or CI where pi --model openai/... works because the key is in the environment, refinery --models pi/openai/... will run Pi without that key and fail authentication; forward Pi's credential/config env vars or resolve them before spawning.

Useful? React with 👍 / 👎.

@El-Fitz

El-Fitz commented May 31, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the CodeRabbit/GHA feedback in 59e0445:

  • Replaced the three sort_by calls in brainstorm.rs with sort_by_key.
  • Tightened parse_model_spec validation for malformed pi/opencode nested model specs and added regression tests.
  • Refreshed the benchmark plan review date.

Local verification:

  • cargo fmt --all -- --check
  • cargo test -p refinery_cli parse_model_spec --quiet
  • cargo test -p refinery_core brainstorm --quiet
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo build --workspace
  • cargo test --workspace

GitHub Actions and CodeRabbit are passing; Buildkite is still pending/scheduled.

@El-Fitz

El-Fitz commented May 31, 2026

Copy link
Copy Markdown
Contributor Author

Also addressed the Gemini/Codex feedback in eb29537:

  • Gemini: sorted ModelId values directly instead of allocating strings.
  • Gemini: brainstorm evaluation parsing now accepts numeric scores returned as JSON strings (with a regression test).
  • Gemini: Pi now preserves USERPROFILE when present for Windows compatibility.
  • Codex: Pi provider now forwards a whitelist of Pi credential/config environment variables after env_clear, so env-based Pi credentials continue to work.

Re-ran:

  • cargo fmt --all -- --check
  • cargo test -p refinery_core parse_brainstorm_evaluation_accepts_string_score --quiet
  • cargo test -p tundish_providers pi --quiet
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo build --workspace
  • cargo test --workspace

@El-Fitz

El-Fitz commented May 31, 2026

Copy link
Copy Markdown
Contributor Author

Fixed the GitHub Actions Clippy failure in 5517441 by changing the proposal sort to the form requested by CI's newer Clippy: proposals.sort_by_key(|(id, _)| *id).\n\nRe-ran locally:\n\n- cargo fmt --all -- --check\n- cargo clippy --workspace -- -D warnings\n- cargo test -p refinery_core parse_brainstorm_evaluation_accepts_string_score --quiet

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5517441c71

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

env_vars
}

const PI_PASSTHROUGH_ENV: &[&str] = &[

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include all documented Pi credential env vars

In the current allowlist, Pi runs under spawn_cli's cleared environment without several credential sources that Pi documents, such as HF_TOKEN, MINIMAX_CN_API_KEY, and Bedrock role/proxy variables like AWS_CONTAINER_CREDENTIALS_*, AWS_WEB_IDENTITY_TOKEN_FILE, and AWS_ENDPOINT_URL_BEDROCK_RUNTIME (see Pi's Providers docs). In those environments pi --model ... authenticates normally, but the same model through Refinery loses the required variables and fails before producing an answer; extend this passthrough or avoid an allowlist for Pi credential resolution.

Useful? React with 👍 / 👎.

@El-Fitz El-Fitz added this pull request to the merge queue Jun 1, 2026
Merged via the queue into main with commit defabfa Jun 1, 2026
5 checks passed
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