Skip to content

Commit 69e3fb2

Browse files
committed
fix(agent): use clients release assets for updates
1 parent 6ddfbb1 commit 69e3fb2

3 files changed

Lines changed: 84 additions & 85 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ members = [
1414
]
1515

1616
[workspace.package]
17-
version = "1.21.4"
17+
version = "1.21.5"
1818
edition = "2024"
1919
authors = ["Terraphim Team <team@terraphim.ai>"]
2020
documentation = "https://terraphim.ai"

crates/terraphim_agent/src/main.rs

Lines changed: 78 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1832,7 +1832,9 @@ fn main() -> Result<()> {
18321832
// Check for updates on startup (non-blocking, debug logging on failure)
18331833
let rt = Runtime::new()?;
18341834
rt.block_on(async {
1835-
let config = UpdaterConfig::new("terraphim-agent").with_version(env!("CARGO_PKG_VERSION"));
1835+
let config = UpdaterConfig::new("terraphim-agent")
1836+
.with_repo("terraphim", "terraphim-clients")
1837+
.with_version(env!("CARGO_PKG_VERSION"));
18361838
let updater = TerraphimUpdater::new(config);
18371839
if let Err(e) = updater.check_update().await {
18381840
log::debug!("Update check failed: {}", e);
@@ -2130,7 +2132,9 @@ async fn run_offline_command(
21302132
// CheckUpdate is stateless - handle before TuiService initialization
21312133
if let Command::CheckUpdate = &command {
21322134
println!("Checking for terraphim-agent updates...");
2133-
let config = UpdaterConfig::new("terraphim-agent").with_version(env!("CARGO_PKG_VERSION"));
2135+
let config = UpdaterConfig::new("terraphim-agent")
2136+
.with_repo("terraphim", "terraphim-clients")
2137+
.with_version(env!("CARGO_PKG_VERSION"));
21342138
let updater = TerraphimUpdater::new(config);
21352139
match updater.check_update().await {
21362140
Ok(status) => {
@@ -2147,7 +2151,9 @@ async fn run_offline_command(
21472151
// Update is stateless - handle before TuiService initialization
21482152
if let Command::Update = &command {
21492153
println!("Updating terraphim-agent...");
2150-
let config = UpdaterConfig::new("terraphim-agent").with_version(env!("CARGO_PKG_VERSION"));
2154+
let config = UpdaterConfig::new("terraphim-agent")
2155+
.with_repo("terraphim", "terraphim-clients")
2156+
.with_version(env!("CARGO_PKG_VERSION"));
21512157
let updater = TerraphimUpdater::new(config);
21522158
match updater.check_and_update().await {
21532159
Ok(status) => {
@@ -3844,20 +3850,20 @@ fn evolution_path() -> std::path::PathBuf {
38443850

38453851
fn load_evolution() -> terraphim_agent_evolution::AgentEvolutionSystem {
38463852
let path = evolution_path();
3847-
if path.exists() {
3848-
if let Ok(data) = std::fs::read_to_string(&path) {
3849-
#[derive(serde::Deserialize)]
3850-
struct EvolutionState {
3851-
memory: terraphim_agent_evolution::MemoryState,
3852-
lessons: terraphim_agent_evolution::LessonsState,
3853-
}
3854-
if let Ok(state) = serde_json::from_str::<EvolutionState>(&data) {
3855-
let mut evolution =
3856-
terraphim_agent_evolution::AgentEvolutionSystem::new("cli-agent".to_string());
3857-
evolution.memory.current_state = state.memory;
3858-
evolution.lessons.current_state = state.lessons;
3859-
return evolution;
3860-
}
3853+
if path.exists()
3854+
&& let Ok(data) = std::fs::read_to_string(&path)
3855+
{
3856+
#[derive(serde::Deserialize)]
3857+
struct EvolutionState {
3858+
memory: terraphim_agent_evolution::MemoryState,
3859+
lessons: terraphim_agent_evolution::LessonsState,
3860+
}
3861+
if let Ok(state) = serde_json::from_str::<EvolutionState>(&data) {
3862+
let mut evolution =
3863+
terraphim_agent_evolution::AgentEvolutionSystem::new("cli-agent".to_string());
3864+
evolution.memory.current_state = state.memory;
3865+
evolution.lessons.current_state = state.lessons;
3866+
return evolution;
38613867
}
38623868
}
38633869
terraphim_agent_evolution::AgentEvolutionSystem::new("cli-agent".to_string())
@@ -3942,14 +3948,23 @@ async fn run_memory_command(sub: MemorySub, output: &CommandOutputConfig) -> Res
39423948
serde_json::json!({ "status": "ok", "action": "distill", "format": format })
39433949
);
39443950
} else {
3945-
println!("Memory distill: routing to learn compile + export-kg (format: {})", format);
3951+
println!(
3952+
"Memory distill: routing to learn compile + export-kg (format: {})",
3953+
format
3954+
);
39463955
}
39473956
Ok(())
39483957
}
3949-
MemorySub::Scope { role, project, check } => {
3958+
MemorySub::Scope {
3959+
role,
3960+
project,
3961+
check,
3962+
} => {
39503963
let (role_clone, project_clone) = (role.clone(), project.clone());
39513964
if check {
3952-
println!("Memory scope --check: verifying no permissioned items in public locations");
3965+
println!(
3966+
"Memory scope --check: verifying no permissioned items in public locations"
3967+
);
39533968
let config_dir = dirs::config_dir()
39543969
.unwrap_or_else(|| std::path::PathBuf::from("."))
39553970
.join("terraphim");
@@ -3959,10 +3974,10 @@ async fn run_memory_command(sub: MemorySub, output: &CommandOutputConfig) -> Res
39593974
for entry in std::fs::read_dir(&kg_dir)? {
39603975
let entry = entry?;
39613976
let path = entry.path();
3962-
if path.is_dir() && path.file_name().map_or(false, |n| n != "projects") {
3977+
if path.is_dir() && path.file_name().is_some_and(|n| n != "projects") {
39633978
println!(" found role KG: {}", path.display());
39643979
}
3965-
if path.is_dir() && path.file_name().map_or(false, |n| n == "projects") {
3980+
if path.is_dir() && path.file_name().is_some_and(|n| n == "projects") {
39663981
for p in std::fs::read_dir(&path)? {
39673982
let p = p?;
39683983
println!(" found project KG: {}", p.path().display());
@@ -4057,12 +4072,7 @@ async fn run_memory_command(sub: MemorySub, output: &CommandOutputConfig) -> Res
40574072

40584073
let evolution = load_evolution();
40594074
let items: Vec<&MemoryItem> = if all {
4060-
evolution
4061-
.memory
4062-
.current_state
4063-
.short_term
4064-
.iter()
4065-
.collect()
4075+
evolution.memory.current_state.short_term.iter().collect()
40664076
} else if let Some(ref id) = lesson_id {
40674077
evolution
40684078
.memory
@@ -4127,11 +4137,8 @@ async fn run_memory_command(sub: MemorySub, output: &CommandOutputConfig) -> Res
41274137
);
41284138
}
41294139

4130-
let avg_composite = scores
4131-
.iter()
4132-
.map(|(_, s)| s.composite())
4133-
.sum::<f64>()
4134-
/ scores.len() as f64;
4140+
let avg_composite =
4141+
scores.iter().map(|(_, s)| s.composite()).sum::<f64>() / scores.len() as f64;
41354142
println!("\nAverage composite score: {:.2}", avg_composite);
41364143
}
41374144
Ok(())
@@ -4179,7 +4186,10 @@ async fn run_memory_command(sub: MemorySub, output: &CommandOutputConfig) -> Res
41794186
}
41804187
Ok(())
41814188
}
4182-
MemorySub::Rubric { project, output: outfile } => {
4189+
MemorySub::Rubric {
4190+
project,
4191+
output: outfile,
4192+
} => {
41834193
use terraphim_agent_evolution::MemoryItem;
41844194

41854195
let evolution = load_evolution();
@@ -4196,32 +4206,27 @@ async fn run_memory_command(sub: MemorySub, output: &CommandOutputConfig) -> Res
41964206
.map(|item| (*item, score_memory_item(item)))
41974207
.collect();
41984208

4199-
let avg_composite = scores
4200-
.iter()
4201-
.map(|(_, s)| s.composite())
4202-
.sum::<f64>()
4203-
/ scores.len() as f64;
4209+
let avg_composite =
4210+
scores.iter().map(|(_, s)| s.composite()).sum::<f64>() / scores.len() as f64;
42044211

42054212
let avg_dimensions = RubricScore {
42064213
faithfulness: scores.iter().map(|(_, s)| s.faithfulness).sum::<f64>()
42074214
/ scores.len() as f64,
4208-
scope: scores.iter().map(|(_, s)| s.scope).sum::<f64>()
4209-
/ scores.len() as f64,
4215+
scope: scores.iter().map(|(_, s)| s.scope).sum::<f64>() / scores.len() as f64,
42104216
provenance: scores.iter().map(|(_, s)| s.provenance).sum::<f64>()
42114217
/ scores.len() as f64,
42124218
actionability: scores.iter().map(|(_, s)| s.actionability).sum::<f64>()
42134219
/ scores.len() as f64,
4214-
decay: scores.iter().map(|(_, s)| s.decay).sum::<f64>()
4215-
/ scores.len() as f64,
4216-
risk: scores.iter().map(|(_, s)| s.risk).sum::<f64>()
4217-
/ scores.len() as f64,
4220+
decay: scores.iter().map(|(_, s)| s.decay).sum::<f64>() / scores.len() as f64,
4221+
risk: scores.iter().map(|(_, s)| s.risk).sum::<f64>() / scores.len() as f64,
42184222
};
42194223

42204224
let mut offender_list: Vec<(&MemoryItem, f64)> = scores
42214225
.iter()
42224226
.map(|(item, s)| (*item, s.composite()))
42234227
.collect();
4224-
offender_list.sort_by(|a, b| a.1.partial_cmp(&b.1).unwrap_or(std::cmp::Ordering::Equal));
4228+
offender_list
4229+
.sort_by(|a, b| a.1.partial_cmp(&b.1).unwrap_or(std::cmp::Ordering::Equal));
42254230
let top_offenders: Vec<_> = offender_list.iter().take(3).collect();
42264231

42274232
let retirement_recs: Vec<&MemoryItem> = scores
@@ -4238,15 +4243,10 @@ async fn run_memory_command(sub: MemorySub, output: &CommandOutputConfig) -> Res
42384243
"**Generated:** {}\n",
42394244
chrono::Utc::now().to_rfc3339()
42404245
));
4241-
report.push_str(&format!(
4242-
"**Items analysed:** {}\n\n",
4243-
items.len()
4244-
));
4246+
report.push_str(&format!("**Items analysed:** {}\n\n", items.len()));
42454247

42464248
report.push_str("## Overall Scores\n\n");
4247-
report.push_str(&format!(
4248-
"| Dimension | Score | Status |\n|---|---|---|\n"
4249-
));
4249+
report.push_str("| Dimension | Score | Status |\n|---|---|---|\n");
42504250
for (name, value) in [
42514251
("Faithfulness", avg_dimensions.faithfulness),
42524252
("Scope", avg_dimensions.scope),
@@ -4306,8 +4306,6 @@ async fn run_memory_command(sub: MemorySub, output: &CommandOutputConfig) -> Res
43064306
Ok(())
43074307
}
43084308
MemorySub::List { item_type, limit } => {
4309-
4310-
43114309
let evolution = load_evolution();
43124310
let state = &evolution.memory.current_state;
43134311

@@ -4317,7 +4315,9 @@ async fn run_memory_command(sub: MemorySub, output: &CommandOutputConfig) -> Res
43174315
.short_term
43184316
.iter()
43194317
.filter(|m| {
4320-
format!("{:?}", m.item_type).to_lowercase().contains(&filter)
4318+
format!("{:?}", m.item_type)
4319+
.to_lowercase()
4320+
.contains(&filter)
43214321
})
43224322
.take(limit)
43234323
.collect::<Vec<_>>()
@@ -4352,11 +4352,7 @@ async fn run_memory_command(sub: MemorySub, output: &CommandOutputConfig) -> Res
43524352
} else {
43534353
println!("Memory items ({} total):", items.len());
43544354
for (i, m) in items.iter().enumerate() {
4355-
let first_line = m
4356-
.content
4357-
.lines()
4358-
.next()
4359-
.unwrap_or(&m.content);
4355+
let first_line = m.content.lines().next().unwrap_or(&m.content);
43604356
println!(
43614357
" {}. [{:?}] {} -- {:?} importance (accessed {}x)",
43624358
i + 1,
@@ -4379,8 +4375,6 @@ async fn run_memory_command(sub: MemorySub, output: &CommandOutputConfig) -> Res
43794375
Ok(())
43804376
}
43814377
MemorySub::Show { id, json } => {
4382-
4383-
43844378
let evolution = load_evolution();
43854379

43864380
let memory_item = evolution
@@ -4400,11 +4394,7 @@ async fn run_memory_command(sub: MemorySub, output: &CommandOutputConfig) -> Res
44004394
v.extend(ls.success_patterns.iter());
44014395
v
44024396
};
4403-
let lesson = all_lessons
4404-
.iter()
4405-
.find(|l| l.id == id)
4406-
.cloned()
4407-
.cloned();
4397+
let lesson = all_lessons.iter().find(|l| l.id == id).cloned().cloned();
44084398

44094399
if memory_item.is_none() && lesson.is_none() {
44104400
eprintln!("No memory item or lesson found with ID: {}", id);
@@ -4450,7 +4440,11 @@ async fn run_memory_command(sub: MemorySub, output: &CommandOutputConfig) -> Res
44504440
println!(" impact: {:?}", l.impact);
44514441
println!(" confidence: {:.0}%", l.confidence * 100.0);
44524442
println!(" learned: {}", l.learned_at);
4453-
println!(" applied: {} times (success rate: {:.0}%)", l.applied_count, l.success_rate * 100.0);
4443+
println!(
4444+
" applied: {} times (success rate: {:.0}%)",
4445+
l.applied_count,
4446+
l.success_rate * 100.0
4447+
);
44544448
println!(" validated: {}", if l.validated { "yes" } else { "no" });
44554449
if !l.tags.is_empty() {
44564450
println!(" tags: {}", l.tags.join(", "));
@@ -4467,9 +4461,10 @@ async fn run_memory_command(sub: MemorySub, output: &CommandOutputConfig) -> Res
44674461
}
44684462
Ok(())
44694463
}
4470-
MemorySub::Export { format, output: outfile } => {
4471-
4472-
4464+
MemorySub::Export {
4465+
format,
4466+
output: outfile,
4467+
} => {
44734468
let evolution = load_evolution();
44744469

44754470
let memory_items: Vec<serde_json::Value> = evolution
@@ -4535,15 +4530,12 @@ async fn run_memory_command(sub: MemorySub, output: &CommandOutputConfig) -> Res
45354530
"markdown" => {
45364531
let mut md = String::new();
45374532
md.push_str("# Memory Export\n\n");
4538-
md.push_str(&format!("**Agent:** cli-agent\n"));
4533+
md.push_str("**Agent:** cli-agent\n");
45394534
md.push_str(&format!(
45404535
"**Exported:** {}\n\n",
45414536
chrono::Utc::now().to_rfc3339()
45424537
));
4543-
md.push_str(&format!(
4544-
"## Memory Items ({})\n\n",
4545-
memory_items.len()
4546-
));
4538+
md.push_str(&format!("## Memory Items ({})\n\n", memory_items.len()));
45474539
for m in &memory_items {
45484540
md.push_str(&format!(
45494541
"- **{}** [{:?}]: {} (importance: {:?}, accessed: {}x)\n",
@@ -4594,12 +4586,11 @@ async fn run_memory_command(sub: MemorySub, output: &CommandOutputConfig) -> Res
45944586
for entry in std::fs::read_dir(&artefact_base)? {
45954587
let entry = entry?;
45964588
let path = entry.path();
4597-
if path.extension().map_or(false, |e| e == "json") {
4598-
if let Ok(data) = std::fs::read_to_string(&path) {
4599-
if let Ok(metrics) = serde_json::from_str::<RunMetrics>(&data) {
4600-
runs.push(metrics);
4601-
}
4602-
}
4589+
if path.extension().is_some_and(|e| e == "json")
4590+
&& let Ok(data) = std::fs::read_to_string(&path)
4591+
&& let Ok(metrics) = serde_json::from_str::<RunMetrics>(&data)
4592+
{
4593+
runs.push(metrics);
46034594
}
46044595
}
46054596
}
@@ -4627,7 +4618,10 @@ async fn run_memory_command(sub: MemorySub, output: &CommandOutputConfig) -> Res
46274618
if artefact_base.exists() {
46284619
println!(" artefact directory: {}", artefact_base.display());
46294620
} else {
4630-
println!(" no artefact directory found (expected at: {})", artefact_base.display());
4621+
println!(
4622+
" no artefact directory found (expected at: {})",
4623+
artefact_base.display()
4624+
);
46314625
}
46324626
}
46334627
return Ok(());

crates/terraphim_agent/tests/update_functionality_tests.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,11 @@ async fn test_updater_configuration() {
157157
assert_eq!(config.bin_name, "terraphim-agent");
158158
assert_eq!(config.repo_owner, "terraphim");
159159
assert_eq!(config.repo_name, "terraphim-ai");
160+
161+
// terraphim-agent CLI release assets live in terraphim-clients.
162+
let config = UpdaterConfig::new("terraphim-agent").with_repo("terraphim", "terraphim-clients");
163+
assert_eq!(config.repo_owner, "terraphim");
164+
assert_eq!(config.repo_name, "terraphim-clients");
160165
assert!(config.show_progress);
161166

162167
// Test custom configuration

0 commit comments

Comments
 (0)