Skip to content

Commit a70f02b

Browse files
committed
fix(memory): fallback cortex synthesis prompts
1 parent 142b3b0 commit a70f02b

1 file changed

Lines changed: 55 additions & 24 deletions

File tree

src/agent/cortex.rs

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,26 @@ impl BulletinRefreshOutcome {
336336
}
337337

338338
const CORTEX_ONE_SHOT_MAX_TURNS: usize = 1;
339+
const CORTEX_INTRADAY_SYNTHESIS_SYSTEM_FALLBACK: &str = "You write concise working-memory summaries for the cortex.\n\nOutput one narrative summary paragraph and nothing else.";
340+
const CORTEX_DAILY_SUMMARY_SYSTEM_FALLBACK: &str = "You write daily activity summaries for the cortex.\n\nOutput the daily activity summary and nothing else.";
341+
342+
fn render_static_prompt_or_fallback(
343+
prompt_engine: &crate::prompts::engine::PromptEngine,
344+
template_name: &'static str,
345+
fallback: &'static str,
346+
) -> String {
347+
match prompt_engine.render_static(template_name) {
348+
Ok(prompt) => prompt,
349+
Err(error) => {
350+
tracing::warn!(
351+
%error,
352+
template_name,
353+
"failed to render static cortex prompt, using fallback"
354+
);
355+
fallback.to_string()
356+
}
357+
}
358+
}
339359

340360
fn maybe_spawn_synthesis_task(
341361
task: &mut Option<tokio::task::JoinHandle<anyhow::Result<bool>>>,
@@ -3223,13 +3243,11 @@ pub async fn maybe_synthesize_intraday_batch(
32233243

32243244
// Render the synthesis prompt.
32253245
let prompt_engine = deps.runtime_config.prompts.load();
3226-
let synthesis_preamble = match prompt_engine.render_static("cortex_intraday_synthesis_system") {
3227-
Ok(prompt) => prompt,
3228-
Err(error) => {
3229-
tracing::warn!(%error, "failed to render cortex_intraday_synthesis_system prompt");
3230-
return Err(error.into());
3231-
}
3232-
};
3246+
let synthesis_preamble = render_static_prompt_or_fallback(
3247+
&prompt_engine,
3248+
"cortex_intraday_synthesis_system",
3249+
CORTEX_INTRADAY_SYNTHESIS_SYSTEM_FALLBACK,
3250+
);
32333251
let prompt = prompt_engine.render_intraday_synthesis(
32343252
unsynthesized.len(),
32353253
&time_start_str,
@@ -3387,13 +3405,11 @@ pub async fn maybe_synthesize_daily_summary(
33873405

33883406
let wm_config = **deps.runtime_config.working_memory.load();
33893407
let prompt_engine = deps.runtime_config.prompts.load();
3390-
let synthesis_preamble = match prompt_engine.render_static("cortex_daily_summary_system") {
3391-
Ok(prompt) => prompt,
3392-
Err(error) => {
3393-
tracing::warn!(%error, "failed to render cortex_daily_summary_system prompt");
3394-
return Err(error.into());
3395-
}
3396-
};
3408+
let synthesis_preamble = render_static_prompt_or_fallback(
3409+
&prompt_engine,
3410+
"cortex_daily_summary_system",
3411+
CORTEX_DAILY_SUMMARY_SYSTEM_FALLBACK,
3412+
);
33973413
let prompt = prompt_engine.render_daily_summary(
33983414
&yesterday,
33993415
wm_config.daily_summary_max_words,
@@ -4614,22 +4630,24 @@ async fn fetch_memories_for_association(
46144630
mod tests {
46154631
use super::{
46164632
BULLETIN_REFRESH_CIRCUIT_OPEN_SECS, BULLETIN_REFRESH_CIRCUIT_OPEN_THRESHOLD, BranchTracker,
4617-
BulletinRefreshOutcome, CortexReceiverOutcome, GatheredSections, HealthRuntimeState,
4618-
MAINTENANCE_TASK_CANCEL_GRACE_SECS, MaintenanceTimeoutAction, ReceiverClosedBehavior,
4619-
Signal, SynthesisTaskBackoff, WorkerTracker, apply_cancelled_warmup_status,
4620-
build_kill_targets, claim_detached_completion, collect_synthesis_task,
4621-
detached_timeout_transition, handle_cortex_receiver_result, has_completed_initial_warmup,
4622-
is_cancelled_control_result, is_terminal_control_result, maintenance_task_timeout,
4623-
maintenance_timeout_action, mark_knowledge_synthesis_version_complete,
4624-
maybe_close_bulletin_refresh_circuit, maybe_generate_bulletin_under_lock,
4625-
maybe_spawn_synthesis_task, parse_structured_success_flag, push_signal_into_buffer,
4626-
record_bulletin_refresh_failure, should_execute_warmup,
4633+
BulletinRefreshOutcome, CORTEX_INTRADAY_SYNTHESIS_SYSTEM_FALLBACK, CortexReceiverOutcome,
4634+
GatheredSections, HealthRuntimeState, MAINTENANCE_TASK_CANCEL_GRACE_SECS,
4635+
MaintenanceTimeoutAction, ReceiverClosedBehavior, Signal, SynthesisTaskBackoff,
4636+
WorkerTracker, apply_cancelled_warmup_status, build_kill_targets,
4637+
claim_detached_completion, collect_synthesis_task, detached_timeout_transition,
4638+
handle_cortex_receiver_result, has_completed_initial_warmup, is_cancelled_control_result,
4639+
is_terminal_control_result, maintenance_task_timeout, maintenance_timeout_action,
4640+
mark_knowledge_synthesis_version_complete, maybe_close_bulletin_refresh_circuit,
4641+
maybe_generate_bulletin_under_lock, maybe_spawn_synthesis_task,
4642+
parse_structured_success_flag, push_signal_into_buffer, record_bulletin_refresh_failure,
4643+
render_static_prompt_or_fallback, should_execute_warmup,
46274644
should_generate_bulletin_from_bulletin_loop, signal_from_event, summarize_signal_text,
46284645
take_lagged_control_flag,
46294646
};
46304647
use crate::ProcessEvent;
46314648
use crate::agent::process_control::ControlActionResult;
46324649
use crate::memory::MemoryType;
4650+
use crate::prompts::engine::PromptEngine;
46334651
use crate::tasks::TaskStatus;
46344652
use crate::tasks::TaskStore;
46354653
use futures::FutureExt;
@@ -4660,6 +4678,19 @@ mod tests {
46604678
assert!(should_execute_warmup(warmup_config, true));
46614679
}
46624680

4681+
#[test]
4682+
fn static_cortex_prompt_fallback_keeps_synthesis_running_when_template_fails() {
4683+
let prompt_engine = PromptEngine::new("en").expect("prompt engine should build");
4684+
4685+
let prompt = render_static_prompt_or_fallback(
4686+
&prompt_engine,
4687+
"missing_cortex_synthesis_template",
4688+
CORTEX_INTRADAY_SYNTHESIS_SYSTEM_FALLBACK,
4689+
);
4690+
4691+
assert_eq!(prompt, CORTEX_INTRADAY_SYNTHESIS_SYSTEM_FALLBACK);
4692+
}
4693+
46634694
#[test]
46644695
fn run_warmup_once_semantics_enabled_runs_without_force() {
46654696
let warmup_config = crate::config::WarmupConfig {

0 commit comments

Comments
 (0)