refactor(crates): kernel/generation module split + DeerFlow optimizations + middleware + dead code cleanup
- Split zclaw-kernel/kernel.rs (1486 lines) into 9 domain modules - Split zclaw-kernel/generation.rs (1080 lines) into 3 modules - Add DeerFlow-inspired middleware: DanglingTool, SubagentLimit, ToolError, ToolOutputGuard - Add PromptBuilder for structured system prompt assembly - Add FactStore (zclaw-memory) for persistent fact extraction - Add task builtin tool for agent task management - Driver improvements: Anthropic/OpenAI extended thinking, Gemini safety settings - Replace let _ = with proper log::warn! across SaaS handlers - Remove unused dependency (url) from zclaw-hands
This commit is contained in:
120
crates/zclaw-runtime/src/prompt/builder.rs
Normal file
120
crates/zclaw-runtime/src/prompt/builder.rs
Normal file
@@ -0,0 +1,120 @@
|
||||
use std::fmt::Write;
|
||||
|
||||
use crate::driver::ToolDefinition;
|
||||
|
||||
/// Runtime context that determines which prompt sections are included.
|
||||
pub struct PromptContext {
|
||||
/// Base system prompt from AgentConfig
|
||||
pub base_prompt: Option<String>,
|
||||
/// Custom agent personality (SOUL.md equivalent)
|
||||
pub soul: Option<String>,
|
||||
/// Whether thinking/extended reasoning is enabled
|
||||
pub thinking_enabled: bool,
|
||||
/// Whether plan mode is active
|
||||
pub plan_mode: bool,
|
||||
/// Tool definitions available for dynamic injection
|
||||
pub tool_definitions: Vec<ToolDefinition>,
|
||||
/// Agent name for personalization
|
||||
pub agent_name: Option<String>,
|
||||
}
|
||||
|
||||
/// A single section in the assembled prompt.
|
||||
pub struct PromptSection {
|
||||
pub name: &'static str,
|
||||
pub template: String,
|
||||
pub priority: u32,
|
||||
}
|
||||
|
||||
/// Builds structured system prompts from conditional sections.
|
||||
pub struct PromptBuilder {
|
||||
sections: Vec<PromptSection>,
|
||||
}
|
||||
|
||||
impl PromptBuilder {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
sections: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Add a section unconditionally.
|
||||
pub fn add_section(
|
||||
mut self,
|
||||
name: &'static str,
|
||||
template: impl Into<String>,
|
||||
priority: u32,
|
||||
) -> Self {
|
||||
self.sections.push(PromptSection {
|
||||
name,
|
||||
template: template.into(),
|
||||
priority,
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
/// Assemble the final system prompt based on runtime context.
|
||||
pub fn build(&self, ctx: &PromptContext) -> String {
|
||||
let mut sections: Vec<&PromptSection> = self.sections.iter().collect();
|
||||
sections.sort_by_key(|s| s.priority);
|
||||
|
||||
let mut result = String::with_capacity(4096);
|
||||
|
||||
// Base prompt (always included)
|
||||
if let Some(ref base) = ctx.base_prompt {
|
||||
result.push_str(base);
|
||||
} else {
|
||||
result.push_str("You are a helpful AI assistant.");
|
||||
}
|
||||
|
||||
// Soul/personality section
|
||||
if let Some(ref soul) = ctx.soul {
|
||||
result.push_str("\n\n## Agent Personality\n\n");
|
||||
result.push_str(soul);
|
||||
}
|
||||
|
||||
// Agent name personalization
|
||||
if let Some(ref name) = ctx.agent_name {
|
||||
let _ = write!(result, "\n\nYou are known as \"{name}\". Respond in character.");
|
||||
}
|
||||
|
||||
// Dynamic tool descriptions
|
||||
if !ctx.tool_definitions.is_empty() {
|
||||
result.push_str("\n\n## Available Tools\n\n");
|
||||
for tool in &ctx.tool_definitions {
|
||||
let _ = writeln!(result, "- **{}**: {}", tool.name, tool.description);
|
||||
}
|
||||
}
|
||||
|
||||
// Thinking style guidance
|
||||
if ctx.thinking_enabled {
|
||||
result.push_str("\n\n## Reasoning Mode\n\n");
|
||||
result.push_str(
|
||||
"Extended reasoning is enabled. Think step-by-step before responding. \
|
||||
Show your reasoning process, then provide the final answer.",
|
||||
);
|
||||
}
|
||||
|
||||
// Plan mode instructions
|
||||
if ctx.plan_mode {
|
||||
result.push_str("\n\n## Plan Mode\n\n");
|
||||
result.push_str(
|
||||
"You are in plan mode. Before executing any actions, create a detailed plan. \
|
||||
Present the plan to the user for approval before proceeding.",
|
||||
);
|
||||
}
|
||||
|
||||
// Additional registered sections
|
||||
for section in sections {
|
||||
result.push_str("\n\n");
|
||||
result.push_str(§ion.template);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for PromptBuilder {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
9
crates/zclaw-runtime/src/prompt/mod.rs
Normal file
9
crates/zclaw-runtime/src/prompt/mod.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
//! Dynamic prompt assembly module.
|
||||
//!
|
||||
//! Inspired by DeerFlow's conditional section-based prompt composition.
|
||||
//! The `PromptBuilder` assembles a structured system prompt from multiple
|
||||
//! conditional sections before the middleware chain further modifies it.
|
||||
|
||||
mod builder;
|
||||
|
||||
pub use builder::{PromptBuilder, PromptContext, PromptSection};
|
||||
Reference in New Issue
Block a user