From 1cd47d3905196c1fa349f68cd819f1915aa254dd Mon Sep 17 00:00:00 2001 From: jaberjaber23 Date: Sat, 28 Feb 2026 04:52:49 +0300 Subject: [PATCH] fix bugs --- Cargo.lock | 28 +++++++++++----------- Cargo.toml | 2 +- crates/openfang-api/src/middleware.rs | 18 ++++++++++++++ crates/openfang-api/static/index_body.html | 10 ++++---- crates/openfang-api/static/js/app.js | 2 +- crates/openfang-cli/src/main.rs | 10 ++++++-- crates/openfang-kernel/src/cron.rs | 24 ++++++++++++------- crates/openfang-kernel/src/kernel.rs | 2 ++ 8 files changed, 66 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 80b2f939..417f8ec7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3866,7 +3866,7 @@ dependencies = [ [[package]] name = "openfang-api" -version = "0.1.7" +version = "0.1.8" dependencies = [ "async-trait", "axum", @@ -3902,7 +3902,7 @@ dependencies = [ [[package]] name = "openfang-channels" -version = "0.1.7" +version = "0.1.8" dependencies = [ "async-trait", "axum", @@ -3933,7 +3933,7 @@ dependencies = [ [[package]] name = "openfang-cli" -version = "0.1.7" +version = "0.1.8" dependencies = [ "clap", "clap_complete", @@ -3960,7 +3960,7 @@ dependencies = [ [[package]] name = "openfang-desktop" -version = "0.1.7" +version = "0.1.8" dependencies = [ "axum", "open", @@ -3986,7 +3986,7 @@ dependencies = [ [[package]] name = "openfang-extensions" -version = "0.1.7" +version = "0.1.8" dependencies = [ "aes-gcm", "argon2", @@ -4014,7 +4014,7 @@ dependencies = [ [[package]] name = "openfang-hands" -version = "0.1.7" +version = "0.1.8" dependencies = [ "chrono", "dashmap", @@ -4031,7 +4031,7 @@ dependencies = [ [[package]] name = "openfang-kernel" -version = "0.1.7" +version = "0.1.8" dependencies = [ "async-trait", "chrono", @@ -4067,7 +4067,7 @@ dependencies = [ [[package]] name = "openfang-memory" -version = "0.1.7" +version = "0.1.8" dependencies = [ "async-trait", "chrono", @@ -4086,7 +4086,7 @@ dependencies = [ [[package]] name = "openfang-migrate" -version = "0.1.7" +version = "0.1.8" dependencies = [ "chrono", "dirs 6.0.0", @@ -4105,7 +4105,7 @@ dependencies = [ [[package]] name = "openfang-runtime" -version = "0.1.7" +version = "0.1.8" dependencies = [ "anyhow", "async-trait", @@ -4136,7 +4136,7 @@ dependencies = [ [[package]] name = "openfang-skills" -version = "0.1.7" +version = "0.1.8" dependencies = [ "chrono", "hex", @@ -4158,7 +4158,7 @@ dependencies = [ [[package]] name = "openfang-types" -version = "0.1.7" +version = "0.1.8" dependencies = [ "async-trait", "chrono", @@ -4177,7 +4177,7 @@ dependencies = [ [[package]] name = "openfang-wire" -version = "0.1.7" +version = "0.1.8" dependencies = [ "async-trait", "chrono", @@ -8789,7 +8789,7 @@ checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" [[package]] name = "xtask" -version = "0.1.7" +version = "0.1.8" [[package]] name = "yoke" diff --git a/Cargo.toml b/Cargo.toml index 97be5143..02dba8cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ members = [ ] [workspace.package] -version = "0.1.8" +version = "0.1.9" edition = "2021" license = "Apache-2.0 OR MIT" repository = "https://github.com/RightNow-AI/openfang" diff --git a/crates/openfang-api/src/middleware.rs b/crates/openfang-api/src/middleware.rs index 37285e22..a386771e 100644 --- a/crates/openfang-api/src/middleware.rs +++ b/crates/openfang-api/src/middleware.rs @@ -90,6 +90,24 @@ pub async fn auth( || path == "/api/profiles" || path == "/api/config" || path.starts_with("/api/uploads/") + // Dashboard read endpoints — allow unauthenticated so the SPA can + // render before the user enters their API key. + || path == "/api/models" + || path == "/api/models/aliases" + || path == "/api/providers" + || path == "/api/budget" + || path == "/api/budget/agents" + || path.starts_with("/api/budget/agents/") + || path == "/api/network/status" + || path == "/api/a2a/agents" + || path == "/api/approvals" + || path == "/api/channels" + || path == "/api/skills" + || path == "/api/sessions" + || path == "/api/integrations" + || path == "/api/integrations/available" + || path == "/api/integrations/health" + || path.starts_with("/api/cron/") { return next.run(request).await; } diff --git a/crates/openfang-api/static/index_body.html b/crates/openfang-api/static/index_body.html index 18721fa1..90f8e426 100644 --- a/crates/openfang-api/static/index_body.html +++ b/crates/openfang-api/static/index_body.html @@ -1102,10 +1102,12 @@
Agent: ·
-
- - -
+ diff --git a/crates/openfang-api/static/js/app.js b/crates/openfang-api/static/js/app.js index 5c5d87c5..987c13eb 100644 --- a/crates/openfang-api/static/js/app.js +++ b/crates/openfang-api/static/js/app.js @@ -158,7 +158,7 @@ document.addEventListener('alpine:init', function() { await OpenFangAPI.get('/api/providers'); this.showAuthPrompt = false; } catch(e) { - if (e.message && e.message.indexOf('401') >= 0) { + if (e.message && (e.message.indexOf('Not authorized') >= 0 || e.message.indexOf('401') >= 0 || e.message.indexOf('Missing Authorization') >= 0)) { this.showAuthPrompt = true; } } diff --git a/crates/openfang-cli/src/main.rs b/crates/openfang-cli/src/main.rs index 5d908ff4..df8f7cbb 100644 --- a/crates/openfang-cli/src/main.rs +++ b/crates/openfang-cli/src/main.rs @@ -953,14 +953,20 @@ pub(crate) fn restrict_dir_permissions(_path: &std::path::Path) {} pub(crate) fn find_daemon() -> Option { let home_dir = dirs::home_dir()?.join(".openfang"); let info = read_daemon_info(&home_dir)?; - let url = format!("http://{}/api/health", info.listen_addr); + + // Normalize listen address: replace 0.0.0.0 with 127.0.0.1 to avoid + // DNS/connectivity issues on macOS where 0.0.0.0 can hang. + let addr = info.listen_addr.replace("0.0.0.0", "127.0.0.1"); + let url = format!("http://{addr}/api/health"); + let client = reqwest::blocking::Client::builder() + .connect_timeout(std::time::Duration::from_secs(1)) .timeout(std::time::Duration::from_secs(2)) .build() .ok()?; let resp = client.get(&url).send().ok()?; if resp.status().is_success() { - Some(format!("http://{}", info.listen_addr)) + Some(format!("http://{addr}")) } else { None } diff --git a/crates/openfang-kernel/src/cron.rs b/crates/openfang-kernel/src/cron.rs index c1c33852..a7d7cd4d 100644 --- a/crates/openfang-kernel/src/cron.rs +++ b/crates/openfang-kernel/src/cron.rs @@ -222,16 +222,24 @@ impl CronScheduler { } /// Return jobs whose `next_run` is at or before `now` and are enabled. + /// + /// **Important**: This also pre-advances each due job's `next_run` to the + /// next scheduled time. This prevents the same job from being returned as + /// "due" on subsequent tick iterations while it's still executing. pub fn due_jobs(&self) -> Vec { let now = Utc::now(); - self.jobs - .iter() - .filter(|r| { - let meta = r.value(); - meta.job.enabled && meta.job.next_run.map(|t| t <= now).unwrap_or(false) - }) - .map(|r| r.value().job.clone()) - .collect() + let mut due = Vec::new(); + for mut entry in self.jobs.iter_mut() { + let meta = entry.value_mut(); + if meta.job.enabled && meta.job.next_run.map(|t| t <= now).unwrap_or(false) { + due.push(meta.job.clone()); + // Pre-advance next_run so the job won't fire again on the next + // tick while it's still executing. record_success/record_failure + // will recompute it again after execution completes. + meta.job.next_run = Some(compute_next_run(&meta.job.schedule)); + } + } + due } // -- Outcome recording -------------------------------------------------- diff --git a/crates/openfang-kernel/src/kernel.rs b/crates/openfang-kernel/src/kernel.rs index 2c4b858c..3d3e34f9 100644 --- a/crates/openfang-kernel/src/kernel.rs +++ b/crates/openfang-kernel/src/kernel.rs @@ -3095,6 +3095,8 @@ impl OpenFangKernel { let kernel = Arc::clone(self); tokio::spawn(async move { let mut interval = tokio::time::interval(std::time::Duration::from_secs(15)); + // Use Skip to avoid burst-firing after a long job blocks the loop. + interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip); let mut persist_counter = 0u32; interval.tick().await; // Skip first immediate tick loop {