Add agent-specific language prompt injection
When running in agent mode (e.g., --agent carmack) in a workspace with detected languages, inject agent+language-specific prompts from prompts/langs/<agent>.<lang>.md at the end of the system prompt. Changes: - Add AGENT_LANGUAGE_PROMPTS static array for compile-time embedding - Add get_agent_language_prompt() to look up specific agent+lang combos - Add get_agent_language_prompts_for_workspace_with_langs() that returns both content and matched languages for display - Update agent_mode.rs to inject prompts and show which languages loaded - Display format: '✓ carmack: racket language guidance' - Add tests for new functionality Uses the same detect_languages() mechanism as regular language prompts to avoid code-path aliasing.
This commit is contained in:
@@ -18,6 +18,13 @@ static LANGUAGE_PROMPTS: &[(&str, &[&str], &str)] = &[
|
||||
),
|
||||
];
|
||||
|
||||
/// Embedded agent-specific language prompts.
|
||||
/// Format: (agent_name, language_name, prompt_content)
|
||||
static AGENT_LANGUAGE_PROMPTS: &[(&str, &str, &str)] = &[
|
||||
// (agent_name, language_name, prompt_content)
|
||||
("carmack", "racket", include_str!("../../../prompts/langs/carmack.racket.md")),
|
||||
];
|
||||
|
||||
/// Detect languages present in the workspace by scanning for file extensions.
|
||||
/// Returns a list of detected language names.
|
||||
pub fn detect_languages(workspace_dir: &Path) -> Vec<&'static str> {
|
||||
@@ -118,6 +125,46 @@ pub fn list_available_languages() -> Vec<&'static str> {
|
||||
LANGUAGE_PROMPTS.iter().map(|(name, _, _)| *name).collect()
|
||||
}
|
||||
|
||||
/// Get agent-specific language prompt for a specific agent and language.
|
||||
pub fn get_agent_language_prompt(agent_name: &str, lang: &str) -> Option<&'static str> {
|
||||
AGENT_LANGUAGE_PROMPTS
|
||||
.iter()
|
||||
.find(|(agent, language, _)| *agent == agent_name && *language == lang)
|
||||
.map(|(_, _, content)| *content)
|
||||
}
|
||||
|
||||
/// Get agent-specific language prompts for detected languages in the workspace.
|
||||
/// Returns formatted content ready for injection into the agent's system prompt.
|
||||
#[allow(dead_code)]
|
||||
pub fn get_agent_language_prompts_for_workspace(
|
||||
workspace_dir: &Path,
|
||||
agent_name: &str,
|
||||
) -> Option<String> {
|
||||
let (content, _) = get_agent_language_prompts_for_workspace_with_langs(workspace_dir, agent_name);
|
||||
content
|
||||
}
|
||||
|
||||
/// Get agent-specific language prompts for detected languages in the workspace.
|
||||
/// Returns both the formatted content and the list of languages that had matching prompts.
|
||||
pub fn get_agent_language_prompts_for_workspace_with_langs(
|
||||
workspace_dir: &Path,
|
||||
agent_name: &str,
|
||||
) -> (Option<String>, Vec<&'static str>) {
|
||||
let detected = detect_languages(workspace_dir);
|
||||
let mut prompts = Vec::new();
|
||||
let mut matched_langs = Vec::new();
|
||||
|
||||
for lang in detected {
|
||||
if let Some(content) = get_agent_language_prompt(agent_name, lang) {
|
||||
prompts.push(content.to_string());
|
||||
matched_langs.push(lang);
|
||||
}
|
||||
}
|
||||
|
||||
let content = if prompts.is_empty() { None } else { Some(prompts.join("\n\n---\n\n")) };
|
||||
(content, matched_langs)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -166,4 +213,29 @@ mod tests {
|
||||
assert!(content.contains("🔧 Language-Specific Guidance"));
|
||||
assert!(content.contains("raco"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_carmack_racket_prompt_embedded() {
|
||||
let prompt = get_agent_language_prompt("carmack", "racket");
|
||||
assert!(prompt.is_some());
|
||||
assert!(prompt.unwrap().contains("RACKET-SPECIFIC GUIDANCE"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_agent_language_prompt_not_found() {
|
||||
let prompt = get_agent_language_prompt("nonexistent", "racket");
|
||||
assert!(prompt.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_agent_prompts_for_workspace() {
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let rkt_file = temp_dir.path().join("main.rkt");
|
||||
fs::write(&rkt_file, "#lang racket\n").unwrap();
|
||||
|
||||
let prompts = get_agent_language_prompts_for_workspace(temp_dir.path(), "carmack");
|
||||
assert!(prompts.is_some());
|
||||
let content = prompts.unwrap();
|
||||
assert!(content.contains("RACKET-SPECIFIC GUIDANCE"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user