diff --git a/Cargo.lock b/Cargo.lock index 3b36a3d1..042eae08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3866,7 +3866,7 @@ dependencies = [ [[package]] name = "openfang-api" -version = "0.3.13" +version = "0.3.14" dependencies = [ "async-trait", "axum", @@ -3902,7 +3902,7 @@ dependencies = [ [[package]] name = "openfang-channels" -version = "0.3.13" +version = "0.3.14" dependencies = [ "async-trait", "axum", @@ -3933,7 +3933,7 @@ dependencies = [ [[package]] name = "openfang-cli" -version = "0.3.13" +version = "0.3.14" dependencies = [ "clap", "clap_complete", @@ -3960,7 +3960,7 @@ dependencies = [ [[package]] name = "openfang-desktop" -version = "0.3.13" +version = "0.3.14" dependencies = [ "axum", "open", @@ -3986,7 +3986,7 @@ dependencies = [ [[package]] name = "openfang-extensions" -version = "0.3.13" +version = "0.3.14" dependencies = [ "aes-gcm", "argon2", @@ -4014,7 +4014,7 @@ dependencies = [ [[package]] name = "openfang-hands" -version = "0.3.13" +version = "0.3.14" dependencies = [ "chrono", "dashmap", @@ -4031,7 +4031,7 @@ dependencies = [ [[package]] name = "openfang-kernel" -version = "0.3.13" +version = "0.3.14" dependencies = [ "async-trait", "chrono", @@ -4067,7 +4067,7 @@ dependencies = [ [[package]] name = "openfang-memory" -version = "0.3.13" +version = "0.3.14" dependencies = [ "async-trait", "chrono", @@ -4086,7 +4086,7 @@ dependencies = [ [[package]] name = "openfang-migrate" -version = "0.3.13" +version = "0.3.14" dependencies = [ "chrono", "dirs 6.0.0", @@ -4105,7 +4105,7 @@ dependencies = [ [[package]] name = "openfang-runtime" -version = "0.3.13" +version = "0.3.14" dependencies = [ "anyhow", "async-trait", @@ -4137,7 +4137,7 @@ dependencies = [ [[package]] name = "openfang-skills" -version = "0.3.13" +version = "0.3.14" dependencies = [ "chrono", "hex", @@ -4160,7 +4160,7 @@ dependencies = [ [[package]] name = "openfang-types" -version = "0.3.13" +version = "0.3.14" dependencies = [ "async-trait", "chrono", @@ -4179,7 +4179,7 @@ dependencies = [ [[package]] name = "openfang-wire" -version = "0.3.13" +version = "0.3.14" dependencies = [ "async-trait", "chrono", @@ -8791,7 +8791,7 @@ checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" [[package]] name = "xtask" -version = "0.3.13" +version = "0.3.14" [[package]] name = "yoke" diff --git a/Cargo.toml b/Cargo.toml index 219b5955..49950086 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ members = [ ] [workspace.package] -version = "0.3.14" +version = "0.3.15" edition = "2021" license = "Apache-2.0 OR MIT" repository = "https://github.com/RightNow-AI/openfang" diff --git a/crates/openfang-api/src/openai_compat.rs b/crates/openfang-api/src/openai_compat.rs index b24609c4..884add98 100644 --- a/crates/openfang-api/src/openai_compat.rs +++ b/crates/openfang-api/src/openai_compat.rs @@ -179,9 +179,8 @@ fn resolve_agent(state: &AppState, model: &str) -> Option<(AgentId, String)> { return Some((entry.id, entry.name.clone())); } - // 4. Fallback → first registered agent - let agents = state.kernel.registry.list(); - agents.first().map(|e| (e.id, e.name.clone())) + // No match — return None so the caller returns a proper 404 + None } // ── Message conversion ────────────────────────────────────────────────────── diff --git a/crates/openfang-api/src/routes.rs b/crates/openfang-api/src/routes.rs index e8f2b5e2..ac886faf 100644 --- a/crates/openfang-api/src/routes.rs +++ b/crates/openfang-api/src/routes.rs @@ -298,6 +298,14 @@ pub async fn send_message( ); } + // Check agent exists before processing + if state.kernel.registry.get(agent_id).is_none() { + return ( + StatusCode::NOT_FOUND, + Json(serde_json::json!({"error": "Agent not found"})), + ); + } + // Resolve file attachments into image content blocks if !req.attachments.is_empty() { let image_blocks = resolve_attachments(&req.attachments); @@ -337,8 +345,15 @@ pub async fn send_message( } Err(e) => { tracing::warn!("send_message failed for agent {id}: {e}"); + let status = if format!("{e}").contains("Agent not found") { + StatusCode::NOT_FOUND + } else if format!("{e}").contains("quota") || format!("{e}").contains("Quota") { + StatusCode::TOO_MANY_REQUESTS + } else { + StatusCode::INTERNAL_SERVER_ERROR + }; ( - StatusCode::INTERNAL_SERVER_ERROR, + status, Json(serde_json::json!({"error": format!("Message delivery failed: {e}")})), ) }