style: Refactored some imports and LLM hints

This commit is contained in:
Dark-Alex-17 committed 2026-09-14 10:50:34 -06:00
1 parent ad3a5c6d49
commit b87367bb1b
4 files changed
+30 -30

No files matched your search

+3 -1
View File
@@ -127,7 +127,7 @@ async fn run(
}
/// Drives the retry loop, then extraction, then state updates. Extraction
/// stays outside the retry loop: by the time it runs the agent itself
/// stays outside the retry loop: by the time it runs, the agent itself
/// succeeded, so an extraction failure is never retried.
async fn attempt_and_extract(
node_id: &str,
@@ -249,6 +249,7 @@ async fn retry_transient(
parent_ctx.peer_registry = Some(Arc::clone(registry));
}
}
match run_attempt(parent_ctx).await {
Ok(out) => return Ok(out),
Err(e) if is_transient_error(&e) && attempt < node.max_attempts => {
@@ -260,6 +261,7 @@ async fn retry_transient(
Err(e) => return Err(e),
}
}
Err(last_err.unwrap_or_else(|| anyhow!("agent node exhausted retries")))
}
+12 -13
View File
@@ -16,6 +16,7 @@ pub mod types;
pub mod user_interaction;
pub mod validator;
use crate::client::ApiStatusError;
use anyhow::Error;
pub use dispatch::{
active_agent_graph_name, run_active_agent_graph, run_active_agent_graph_with_inputs,
@@ -45,10 +46,7 @@ pub(crate) fn is_transient_error(err: &Error) -> bool {
}) {
return true;
}
if let Some(api) = err
.chain()
.find_map(|c| c.downcast_ref::<crate::client::ApiStatusError>())
{
if let Some(api) = err.chain().find_map(|c| c.downcast_ref::<ApiStatusError>()) {
return is_transient_status(api.status);
}
let s = format!("{err:#}").to_lowercase();
@@ -67,8 +65,8 @@ pub(crate) fn is_transient_error(err: &Error) -> bool {
/// Transient HTTP statuses worth a from-scratch retry: 429 (rate limit),
/// 500/502/503/504 (upstream hiccups), 529 (Anthropic overloaded).
/// Deterministic statuses — 4xx other than 429 (including 408) and
/// 501/505-class capability errors — are excluded.
/// Deterministic statuses (4xx other than 429 (including 408) and
/// 501/505-class capability errors) are excluded.
fn is_transient_status(status: u16) -> bool {
matches!(status, 429 | 500 | 502 | 503 | 504 | 529)
}
@@ -89,6 +87,7 @@ pub(in crate::graph) fn type_name(value: &Value) -> &'static str {
#[cfg(test)]
mod tests {
use super::*;
use crate::client;
use anyhow::anyhow;
#[test]
@@ -151,7 +150,7 @@ mod tests {
"message": "Too many requests, please slow down"
}
});
let err = crate::client::catch_error(&data, 429)
let err = client::catch_error(&data, 429)
.unwrap_err()
.context("Failed to call chat-completions api")
.context("Agent 'domain-reviewer' failed");
@@ -166,7 +165,7 @@ mod tests {
#[test]
fn is_transient_error_typed_status_overrides_message_text() {
let err = crate::client::catch_error(
let err = client::catch_error(
&serde_json::json!({ "message": "rate limit reached — connection reset" }),
400,
)
@@ -176,7 +175,7 @@ mod tests {
"typed 400 must not be retried even when the body matches string anchors"
);
let err = crate::client::catch_error(&serde_json::json!({ "message": "x" }), 503)
let err = client::catch_error(&serde_json::json!({ "message": "x" }), 503)
.unwrap_err()
.context("Agent 'x' failed");
assert!(is_transient_error(&err));
@@ -186,14 +185,14 @@ mod tests {
fn is_transient_error_typed_status_table() {
let data = serde_json::json!({ "message": "x" });
for status in [429, 500, 502, 503, 504, 529] {
let err = crate::client::catch_error(&data, status).unwrap_err();
let err = client::catch_error(&data, status).unwrap_err();
assert!(
is_transient_error(&err),
"status {status} should be transient"
);
}
for status in [400, 401, 403, 404, 408, 422, 501, 505] {
let err = crate::client::catch_error(&data, status).unwrap_err();
let err = client::catch_error(&data, status).unwrap_err();
assert!(
!is_transient_error(&err),
"status {status} should not be transient"
@@ -261,7 +260,7 @@ mod tests {
.read_timeout(Duration::from_millis(50))
.build()
.unwrap();
let err = crate::client::sse_stream(client.get(format!("http://{addr}/")), |_| Ok(false))
let err = client::sse_stream(client.get(format!("http://{addr}/")), |_| Ok(false))
.await
.expect_err("a body that never arrives must trip the read timeout");
server.abort();
@@ -308,7 +307,7 @@ mod tests {
.build()
.unwrap();
let mut received = 0usize;
crate::client::sse_stream(client.get(format!("http://{addr}/")), |message| {
client::sse_stream(client.get(format!("http://{addr}/")), |message| {
if message.data == "[DONE]" {
return Ok(true);
}
+4 -4
View File
@@ -5,7 +5,7 @@ use crate::config;
use crate::config::{Agent, AppConfig, paths};
use crate::rag::{GraphRagConfig, RagData};
use anyhow::{Result, bail};
use std::collections::{BTreeMap, HashSet, VecDeque};
use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
use std::path::PathBuf;
use std::sync::Arc;
use tokio::sync::Semaphore;
@@ -451,7 +451,7 @@ impl GraphValidator {
format!(
"{kind} node's `output_schema` declares no (non-empty) object `properties`; \
the engine auto-merges ONLY keys declared under `properties` (a bare \
object schema merges nothing) — declare the keys under \
object schema merges nothing). Declare the keys under \
`properties` or lift them via `state_updates`"
),
));
@@ -1297,7 +1297,7 @@ fn primary_templated_fields(node: &Node) -> Vec<String> {
}
}
fn node_state_updates_map(node: &Node) -> Option<&std::collections::HashMap<String, String>> {
fn node_state_updates_map(node: &Node) -> Option<&HashMap<String, String>> {
match &node.node_type {
NodeType::Llm(n) => n.state_updates.as_ref(),
NodeType::Agent(n) => n.state_updates.as_ref(),
@@ -1310,7 +1310,7 @@ fn node_state_updates_map(node: &Node) -> Option<&std::collections::HashMap<Stri
}
}
fn lifts_via_state_updates(updates: &Option<std::collections::HashMap<String, String>>) -> bool {
fn lifts_via_state_updates(updates: &Option<HashMap<String, String>>) -> bool {
updates.as_ref().is_some_and(|m| !m.is_empty())
}