use std::collections::BTreeMap;
use std::path::{Path, PathBuf};
use nemo_fabric_core::{DiscoveryConfig, FabricConfig, MetadataConfig, SkillConfig};
use crate::assets::{EmbeddedFile, StagedAssets};
use crate::presets::{self, Preset};
pub(crate) const CODE_REVIEW_WORKSPACE: &str =
include_str!("../assets/examples/code-review/repo/calculator.py");
pub(crate) const CODE_REVIEW_SKILL: &str =
include_str!("../assets/examples/code-review/skills/code-review.md");
const CODE_REVIEW_FILES: &[EmbeddedFile] = &[
EmbeddedFile {
path: "repo/calculator.py",
contents: CODE_REVIEW_WORKSPACE,
},
EmbeddedFile {
path: "skills/code-review.md",
contents: CODE_REVIEW_SKILL,
},
];
const CODE_REVIEW_VARIANTS: &[&str] = &["scripted", "hermes", "claude", "codex", "deepagents"];
#[derive(Debug, Clone, Copy)]
pub struct Example {
pub name: &'static str,
pub description: &'static str,
pub default_variant: &'static str,
pub variants: &'static [&'static str],
}
impl Example {
fn preset(self, variant: Option<&str>) -> Result<Preset, String> {
let variant = variant.unwrap_or(self.default_variant);
if !self.variants.contains(&variant) {
return Err(format!(
"unknown variant {variant:?} for example {:?}; available: {}",
self.name,
self.variants.join(", ")
));
}
presets::find(variant).ok_or_else(|| {
format!(
"example {:?} references missing preset {variant:?}",
self.name
)
})
}
pub fn config(self, variant: Option<&str>) -> Result<FabricConfig, String> {
code_review_config(self.preset(variant)?)
}
pub fn select(self, variant: Option<&str>) -> Result<SelectedExample, String> {
let preset = self.preset(variant)?;
let config = code_review_config(preset)?;
let files = self.embedded_files(preset);
let assets = StagedAssets::create(&files)
.map_err(|error| format!("failed to stage example {:?}: {error}", self.name))?;
Ok(SelectedExample {
example: self,
variant: preset,
config,
assets,
})
}
pub(crate) fn embedded_files(self, preset: Preset) -> Vec<EmbeddedFile> {
let mut files = Vec::from(preset.embedded_files());
files.extend_from_slice(CODE_REVIEW_FILES);
files
}
}
#[derive(Debug)]
pub struct SelectedExample {
pub example: Example,
pub variant: Preset,
pub config: FabricConfig,
assets: StagedAssets,
}
impl SelectedExample {
pub fn base_dir(&self) -> &Path {
self.assets.path()
}
}
pub fn all() -> &'static [Example] {
&EXAMPLES
}
pub fn find(name: &str) -> Option<Example> {
EXAMPLES
.iter()
.copied()
.find(|example| example.name == name)
}
const EXAMPLES: [Example; 1] = [Example {
name: "code-review",
description: "Review a small Python workspace with a deterministic default or a skill-capable harness.",
default_variant: "scripted",
variants: CODE_REVIEW_VARIANTS,
}];
fn code_review_config(preset: Preset) -> Result<FabricConfig, String> {
let mut config = preset.config()?;
config.metadata = MetadataConfig {
name: "code-review-agent".to_string(),
description: Some("Maintained example for reviewing a small Python workspace.".to_string()),
extensions: BTreeMap::new(),
};
config.discovery = Some(DiscoveryConfig {
local_paths: vec![PathBuf::from("adapters")],
extensions: BTreeMap::new(),
});
let environment = config
.environment
.as_mut()
.expect("CLI presets always define an execution environment");
environment.workspace = Some(PathBuf::from("repo"));
if preset.name != "scripted" {
config.skills = Some(SkillConfig {
paths: vec![PathBuf::from("skills/code-review.md")],
extensions: BTreeMap::new(),
});
}
Ok(config)
}
#[cfg(test)]
mod tests {
use nemo_fabric_core::{ResolveContext, RunRequest, resolve_run_plan_from_config, run_plan};
use super::*;
#[test]
fn variants_reuse_the_preset_catalog() {
let example = find("code-review").expect("code review example");
for variant in example.variants {
assert!(presets::find(variant).is_some(), "missing preset {variant}");
}
}
#[test]
fn code_review_stages_one_shared_asset_tree_and_runs() {
let selected = find("code-review")
.expect("code review example")
.select(Some("scripted"))
.expect("select example");
assert!(selected.base_dir().join("repo/calculator.py").is_file());
assert!(selected.base_dir().join("skills/code-review.md").is_file());
assert!(
selected.config.skills.is_none(),
"the scripted smoke variant does not declare skill support"
);
assert!(
find("code-review")
.expect("code review example")
.select(Some("hermes"))
.expect("select Hermes example")
.config
.skills
.is_some(),
"maintained harness variants consume the staged skill"
);
let plan = resolve_run_plan_from_config(
selected.config.clone(),
ResolveContext::new(selected.base_dir()),
)
.expect("plan example");
assert_eq!(plan.agent_name, "code-review-agent");
assert_eq!(
plan.environment_plan
.as_ref()
.expect("environment")
.workspace
.as_ref(),
Some(&selected.base_dir().join("repo"))
);
let result =
run_plan(&plan, RunRequest::text("review")).expect("run deterministic example variant");
assert_eq!(result.output["response"], "review");
}
}