feat: add internal ZCLAW kernel crates to git tracking
This commit is contained in:
106
crates/zclaw-runtime/src/loop_runner.rs
Normal file
106
crates/zclaw-runtime/src/loop_runner.rs
Normal file
@@ -0,0 +1,106 @@
|
||||
//! Agent loop implementation
|
||||
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::mpsc;
|
||||
use zclaw_types::{AgentId, SessionId, Message, Result};
|
||||
|
||||
use crate::driver::{LlmDriver, CompletionRequest};
|
||||
use crate::tool::ToolRegistry;
|
||||
use crate::loop_guard::LoopGuard;
|
||||
use zclaw_memory::MemoryStore;
|
||||
|
||||
/// Agent loop runner
|
||||
pub struct AgentLoop {
|
||||
agent_id: AgentId,
|
||||
driver: Arc<dyn LlmDriver>,
|
||||
tools: ToolRegistry,
|
||||
memory: Arc<MemoryStore>,
|
||||
loop_guard: LoopGuard,
|
||||
}
|
||||
|
||||
impl AgentLoop {
|
||||
pub fn new(
|
||||
agent_id: AgentId,
|
||||
driver: Arc<dyn LlmDriver>,
|
||||
tools: ToolRegistry,
|
||||
memory: Arc<MemoryStore>,
|
||||
) -> Self {
|
||||
Self {
|
||||
agent_id,
|
||||
driver,
|
||||
tools,
|
||||
memory,
|
||||
loop_guard: LoopGuard::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Run the agent loop with a single message
|
||||
pub async fn run(&self, session_id: SessionId, input: String) -> Result<AgentLoopResult> {
|
||||
// Add user message to session
|
||||
let user_message = Message::user(input);
|
||||
self.memory.append_message(&session_id, &user_message).await?;
|
||||
|
||||
// Get all messages for context
|
||||
let messages = self.memory.get_messages(&session_id).await?;
|
||||
|
||||
// Build completion request
|
||||
let request = CompletionRequest {
|
||||
model: "claude-sonnet-4-20250514".to_string(), // TODO: Get from agent config
|
||||
system: None, // TODO: Get from agent config
|
||||
messages,
|
||||
tools: self.tools.definitions(),
|
||||
max_tokens: Some(4096),
|
||||
temperature: Some(0.7),
|
||||
stop: Vec::new(),
|
||||
stream: false,
|
||||
};
|
||||
|
||||
// Call LLM
|
||||
let response = self.driver.complete(request).await?;
|
||||
|
||||
// Process response and handle tool calls
|
||||
let mut iterations = 0;
|
||||
let max_iterations = 10;
|
||||
|
||||
// TODO: Implement full loop with tool execution
|
||||
|
||||
Ok(AgentLoopResult {
|
||||
response: "Response placeholder".to_string(),
|
||||
input_tokens: response.input_tokens,
|
||||
output_tokens: response.output_tokens,
|
||||
iterations,
|
||||
})
|
||||
}
|
||||
|
||||
/// Run the agent loop with streaming
|
||||
pub async fn run_streaming(
|
||||
&self,
|
||||
session_id: SessionId,
|
||||
input: String,
|
||||
) -> Result<mpsc::Receiver<LoopEvent>> {
|
||||
let (tx, rx) = mpsc::channel(100);
|
||||
|
||||
// TODO: Implement streaming
|
||||
|
||||
Ok(rx)
|
||||
}
|
||||
}
|
||||
|
||||
/// Result of an agent loop execution
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AgentLoopResult {
|
||||
pub response: String,
|
||||
pub input_tokens: u32,
|
||||
pub output_tokens: u32,
|
||||
pub iterations: usize,
|
||||
}
|
||||
|
||||
/// Events emitted during streaming
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum LoopEvent {
|
||||
Delta(String),
|
||||
ToolStart { name: String, input: serde_json::Value },
|
||||
ToolEnd { name: String, output: serde_json::Value },
|
||||
Complete(AgentLoopResult),
|
||||
Error(String),
|
||||
}
|
||||
Reference in New Issue
Block a user