From a049cdacdb07f0a89d5c74e7e664fcd8845c0332 Mon Sep 17 00:00:00 2001 From: Victoria Fischer Date: Thu, 11 Jun 2026 21:41:29 +0200 Subject: [PATCH] artifacts: make beets more forgiving, and handle errors with logs --- src/archive.rs | 26 ++++++++++++++------------ src/prediction.rs | 9 ++++++++- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/archive.rs b/src/archive.rs index 03f8495..e4c6350 100644 --- a/src/archive.rs +++ b/src/archive.rs @@ -3,7 +3,7 @@ use std::process::{Command, Stdio}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use crate::artifacts::{Artifact, Track}; +use crate::artifacts::{Artifact, SourceID, Track}; #[derive(Debug, Default, Serialize, Deserialize, Clone, JsonSchema)] @@ -19,8 +19,8 @@ pub struct BeatsQueryArgs { struct BeetsTrack { album: String, artist: String, - genres: Vec, - label: String, + genres: Option>, + label: Option, title: String, year: u32 } @@ -29,18 +29,19 @@ impl Into for BeetsTrack { fn into(self) -> Artifact { Artifact::Track(Track { title: self.title, - label: Some(self.label), + label: self.label, year: Some(self.year), - genres: self.genres, + genres: self.genres.unwrap_or_default(), album: Some(self.album), artist: Some(self.artist), - bpm: None + bpm: None, + sources: vec![SourceID::Beets] }) } } impl BeatsQueryArgs { - pub fn execute(self) -> Result { + pub fn execute(self) -> Result, ()> { let mut beets_cmd = Command::new("beet"); beets_cmd.args(["export", "-f", "json", "-i", "title,label,year,genres,album,artist"]); if let Some(artist) = self.artist { @@ -61,11 +62,12 @@ impl BeatsQueryArgs { log::debug!("Executing beets: {:?}", beets_cmd); if let Ok(output) = beets_cmd.stdout(Stdio::piped()).spawn().unwrap().wait_with_output() { - if let Ok(track) = serde_json::from_str::(str::from_utf8(&output.stdout).unwrap()) { - Ok(track.into()) - } else { - log::error!("Failed to decode beets json"); - Err(()) + match serde_json::from_str::>(str::from_utf8(&output.stdout).unwrap()) { + Ok(track) => Ok(track.into_iter().map(|t| { t.into()}).collect()), + Err(err) => { + log::error!("Failed to decode beets json: {:?}", err); + Err(()) + } } } else { log::error!("Unable to execute query!"); diff --git a/src/prediction.rs b/src/prediction.rs index 78ab636..a18d0fd 100644 --- a/src/prediction.rs +++ b/src/prediction.rs @@ -138,8 +138,15 @@ impl Session { async fn tool_artifact_query(&mut self, args: BeatsQueryArgs) -> ToolResults { let mut messages = vec![]; messages.push(ConversationEntry::ShipComputer(format!("Executing archive query {:?}", args))); + log::info!("Executing beets query {:?}", args); if let Ok(output) = args.execute() { - self.scenery.artifacts.push(output); + for track in &output { + if let Some(merge_target) = self.scenery.artifacts.iter_mut().find(|a| { *a == track }) { + merge_target.merge(track.clone()); + } else { + self.scenery.artifacts.push(track.clone()); + } + } } else { messages.push(ConversationEntry::ShipComputer("Unable to execute query!".into())); };