From 3aeaea5fe494aafb950ce082e7fd341742751d23 Mon Sep 17 00:00:00 2001 From: oudecheng <13802883547@139.com> Date: Wed, 13 May 2026 09:51:02 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E6=9C=80=E5=A4=A7?= =?UTF-8?q?=E4=BB=A4=E7=89=8C=E6=95=B0=E8=87=B34000=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E5=86=85=E5=AD=98=E7=BB=B4=E6=8A=A4=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/gateway/memory_maintenance.rs | 82 +++++++++++++++++++------------ 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/src/gateway/memory_maintenance.rs b/src/gateway/memory_maintenance.rs index 5f0c8af..203542a 100644 --- a/src/gateway/memory_maintenance.rs +++ b/src/gateway/memory_maintenance.rs @@ -151,12 +151,11 @@ impl MemoryMaintenanceService { ), ], temperature: Some(0.0), - max_tokens: Some(1200), + max_tokens: Some(4000), tools: None, }; let mut last_error = None; - let mut response = None; for (attempt, delay_ms) in MEMORY_MAINTENANCE_RETRY_DELAYS_MS .iter() @@ -165,11 +164,8 @@ impl MemoryMaintenanceService { .chain(std::iter::once(None)) .enumerate() { - match provider.chat(request.clone()).await { - Ok(success) => { - response = Some(success); - break; - } + let response = match provider.chat(request.clone()).await { + Ok(success) => success, Err(err) => { let error_text = err.to_string(); let should_retry = @@ -194,34 +190,56 @@ impl MemoryMaintenanceService { error_text ))); } + }; + + let raw_content = strip_json_code_fence(&response.content); + let json_candidate = extract_json_object(raw_content).unwrap_or(raw_content); + + match serde_json::from_str::(json_candidate) { + Ok(parsed) => return Ok(parsed), + Err(err) => { + let error_msg = err.to_string(); + let is_truncated = error_msg.contains("EOF while parsing") + || error_msg.contains("expected"); + + let should_retry = delay_ms.is_some() && is_truncated; + last_error = Some(error_msg.clone()); + + if should_retry { + tracing::warn!( + scope_key = %scope_key, + attempt = attempt + 1, + retry_in_ms = delay_ms.unwrap_or_default(), + error = %error_msg, + raw_len = raw_content.len(), + "Memory organization JSON parse failed (possibly truncated), retrying" + ); + tokio::time::sleep(Duration::from_millis(delay_ms.unwrap_or_default())) + .await; + continue; + } + + tracing::error!( + scope_key = %scope_key, + error = %err, + raw_len = raw_content.len(), + raw_preview = %preview_text(raw_content, 400), + json_candidate_len = json_candidate.len(), + json_candidate_preview = %preview_text(json_candidate, 400), + "Memory maintenance JSON decode failed" + ); + return Err(AgentError::Other(format!( + "memory maintenance JSON decode error: {}", + err + ))); + } } } - let response = response.ok_or_else(|| { - AgentError::Other(format!( - "memory organization model error: {}", - last_error.unwrap_or_else(|| "unknown provider error".to_string()) - )) - })?; - - let raw_content = strip_json_code_fence(&response.content); - let json_candidate = extract_json_object(raw_content).unwrap_or(raw_content); - - let output: MemoryOrganizationOutput = - serde_json::from_str(json_candidate).map_err(|err| { - tracing::error!( - scope_key = %scope_key, - error = %err, - raw_len = raw_content.len(), - raw_preview = %preview_text(raw_content, 400), - json_candidate_len = json_candidate.len(), - json_candidate_preview = %preview_text(json_candidate, 400), - "Memory maintenance JSON decode failed" - ); - AgentError::Other(format!("memory maintenance JSON decode error: {}", err)) - })?; - - Ok(output) + Err(AgentError::Other(format!( + "memory organization failed after retries: {}", + last_error.unwrap_or_else(|| "unknown error".to_string()) + ))) } #[cfg_attr(not(test), allow(dead_code))]