summaryrefslogtreecommitdiff
path: root/makima/src/orchestration/directive.rs
diff options
context:
space:
mode:
Diffstat (limited to 'makima/src/orchestration/directive.rs')
-rw-r--r--makima/src/orchestration/directive.rs85
1 files changed, 81 insertions, 4 deletions
diff --git a/makima/src/orchestration/directive.rs b/makima/src/orchestration/directive.rs
index 15cc7ed..cb3983a 100644
--- a/makima/src/orchestration/directive.rs
+++ b/makima/src/orchestration/directive.rs
@@ -9,7 +9,7 @@
use sqlx::PgPool;
use uuid::Uuid;
-use crate::db::models::{CreateTaskRequest, UpdateTaskRequest};
+use crate::db::models::{CreateTaskRequest, DirectiveMemory, UpdateTaskRequest};
use crate::db::repository;
use crate::server::state::{DaemonCommand, SharedState};
@@ -44,7 +44,24 @@ impl DirectiveOrchestrator {
"Directive needs planning — spawning planning task"
);
- let plan = build_planning_prompt(&directive, &[], 1);
+ // Load memories if memory is enabled for this directive
+ let memories = if directive.memory_enabled {
+ match repository::list_directive_memories(&self.pool, directive.id).await {
+ Ok(m) => m,
+ Err(e) => {
+ tracing::warn!(
+ directive_id = %directive.id,
+ error = %e,
+ "Failed to load directive memories for planning — continuing without"
+ );
+ vec![]
+ }
+ }
+ } else {
+ vec![]
+ };
+
+ let plan = build_planning_prompt(&directive, &[], 1, &memories);
if let Err(e) = self
.spawn_orchestrator_task(
@@ -86,17 +103,40 @@ impl DirectiveOrchestrator {
.as_deref()
.unwrap_or("Execute the step described below.");
+ // Load memories if memory is enabled for this directive
+ let memory_context = if step.memory_enabled {
+ match repository::list_directive_memories(&self.pool, step.directive_id).await {
+ Ok(memories) if !memories.is_empty() => {
+ format!("\n\nMEMORY CONTEXT (from previous planning/execution cycles):\n{}\n",
+ format_memories_for_prompt(&memories))
+ }
+ Ok(_) => String::new(),
+ Err(e) => {
+ tracing::warn!(
+ directive_id = %step.directive_id,
+ error = %e,
+ "Failed to load directive memories for execution — continuing without"
+ );
+ String::new()
+ }
+ }
+ } else {
+ String::new()
+ };
+
let plan = format!(
"You are executing a step in directive \"{directive_title}\".\n\n\
STEP: {step_name}\n\
DESCRIPTION: {description}\n\n\
- INSTRUCTIONS:\n{task_plan}\n\n\
+ INSTRUCTIONS:\n{task_plan}\n\
+ {memory_context}\
When done, the system will automatically mark this step as completed.\n\
If you cannot complete the task, report the failure clearly.",
directive_title = step.directive_title,
step_name = step.step_name,
description = step.step_description.as_deref().unwrap_or("(none)"),
task_plan = task_plan,
+ memory_context = memory_context,
);
match self
@@ -239,7 +279,24 @@ impl DirectiveOrchestrator {
let generation =
repository::get_directive_max_generation(&self.pool, directive.id).await? + 1;
- let plan = build_planning_prompt(&directive, &existing_steps, generation);
+ // Load memories if memory is enabled for this directive
+ let memories = if directive.memory_enabled {
+ match repository::list_directive_memories(&self.pool, directive.id).await {
+ Ok(m) => m,
+ Err(e) => {
+ tracing::warn!(
+ directive_id = %directive.id,
+ error = %e,
+ "Failed to load directive memories for re-planning — continuing without"
+ );
+ vec![]
+ }
+ }
+ } else {
+ vec![]
+ };
+
+ let plan = build_planning_prompt(&directive, &existing_steps, generation, &memories);
if let Err(e) = self
.spawn_orchestrator_task(
@@ -597,14 +654,34 @@ impl DirectiveOrchestrator {
}
}
+/// Format memory entries into a readable prompt section.
+fn format_memories_for_prompt(memories: &[DirectiveMemory]) -> String {
+ let mut out = String::new();
+ for memory in memories {
+ out.push_str(&format!(
+ "- [{}] ({}): {}\n",
+ memory.category, memory.source, memory.content
+ ));
+ }
+ out
+}
+
/// Build the planning prompt for a directive.
fn build_planning_prompt(
directive: &crate::db::models::Directive,
existing_steps: &[crate::db::models::DirectiveStep],
generation: i32,
+ memories: &[DirectiveMemory],
) -> String {
let mut prompt = String::new();
+ // Include memory context if available
+ if !memories.is_empty() {
+ prompt.push_str("MEMORY CONTEXT (insights and decisions from previous cycles):\n");
+ prompt.push_str(&format_memories_for_prompt(memories));
+ prompt.push_str("\nUse these memories to inform your planning. Avoid repeating past mistakes and build on prior insights.\n\n");
+ }
+
if !existing_steps.is_empty() {
prompt.push_str(&format!(
"EXISTING STEPS (generation {}):\n",