#![allow(dead_code)]
use crate::models::SystemPrompt;
use crate::project_context::{ProjectContext, load_project_context_with_parents};
use crate::tui::app::AppMode;
use std::path::Path;
pub const BASE_PROMPT: &str = include_str!("prompts/base.txt");
#[allow(dead_code)]
pub const NORMAL_PROMPT: &str = include_str!("prompts/normal.txt");
pub const AGENT_PROMPT: &str = include_str!("prompts/agent.txt");
pub const YOLO_PROMPT: &str = include_str!("prompts/yolo.txt");
pub const PLAN_PROMPT: &str = include_str!("prompts/plan.txt");
fn mode_prompt(mode: AppMode) -> &'static str {
match mode {
AppMode::Agent => AGENT_PROMPT,
AppMode::Yolo => YOLO_PROMPT,
AppMode::Plan => PLAN_PROMPT,
}
}
fn compose_mode_prompt(mode: AppMode) -> String {
format!("{}\n\n{}", BASE_PROMPT.trim(), mode_prompt(mode).trim())
}
pub fn system_prompt_for_mode(mode: AppMode) -> SystemPrompt {
SystemPrompt::Text(compose_mode_prompt(mode))
}
pub fn system_prompt_for_mode_with_context(
mode: AppMode,
workspace: &Path,
working_set_summary: Option<&str>,
) -> SystemPrompt {
let mode_prompt = compose_mode_prompt(mode);
let project_context = load_project_context_with_parents(workspace);
let mut full_prompt = if let Some(project_block) = project_context.as_system_block() {
format!("{}\n\n{}", mode_prompt, project_block)
} else {
let summary = crate::utils::summarize_project(workspace);
let tree = crate::utils::project_tree(workspace, 2); format!(
"{}\n\n### Project Structure (Automatic Map)\n**Summary:** {}\n\n**Tree:**\n```\n{}\n```",
mode_prompt, summary, tree
)
};
if let Some(summary) = working_set_summary
&& !summary.trim().is_empty()
{
full_prompt = format!("{full_prompt}\n\n{summary}");
}
if matches!(mode, AppMode::Agent | AppMode::Yolo) {
full_prompt.push_str(
"\n\n## Context Management\n\n\
When the conversation gets long (you'll see a context usage indicator), you can:\n\
1. Use `/compact` to summarize earlier context and free up space\n\
2. The system will preserve important information (files you're working on, recent messages, tool results)\n\
3. After compaction, you'll see a summary of what was discussed and can continue seamlessly\n\n\
If you notice context is getting long (>80%), proactively suggest using `/compact` to the user."
);
}
SystemPrompt::Text(full_prompt)
}
pub fn build_system_prompt(base: &str, project_context: Option<&ProjectContext>) -> SystemPrompt {
let full_prompt =
match project_context.and_then(super::project_context::ProjectContext::as_system_block) {
Some(project_block) => format!("{}\n\n{}", base.trim(), project_block),
None => base.trim().to_string(),
};
SystemPrompt::Text(full_prompt)
}
pub fn base_system_prompt() -> SystemPrompt {
SystemPrompt::Text(BASE_PROMPT.trim().to_string())
}
pub fn normal_system_prompt() -> SystemPrompt {
system_prompt_for_mode(AppMode::Agent)
}
pub fn agent_system_prompt() -> SystemPrompt {
system_prompt_for_mode(AppMode::Agent)
}
pub fn yolo_system_prompt() -> SystemPrompt {
system_prompt_for_mode(AppMode::Yolo)
}
pub fn plan_system_prompt() -> SystemPrompt {
system_prompt_for_mode(AppMode::Plan)
}