feat(agent): implement agent execution engine and turn handling with background processing
This commit is contained in:
@@ -68,10 +68,73 @@ async fn handle_socket(mut socket: WebSocket, state: Arc<WsState>) {
|
||||
while let Some(Ok(msg)) = receiver.next().await {
|
||||
match msg {
|
||||
Message::Text(text) => {
|
||||
// Convert Utf8Bytes -> String for JSON serialisation
|
||||
let text_str = text.to_string();
|
||||
info!("Received WS message: {text_str}");
|
||||
// Echo back for now
|
||||
|
||||
if let Ok(val) = serde_json::from_str::<serde_json::Value>(&text_str) {
|
||||
if val.get("type").and_then(|v| v.as_str()) == Some("prompt") {
|
||||
if let Some(prompt) = val.get("message").and_then(|v| v.as_str()) {
|
||||
let session_dir = std::env::current_dir().unwrap_or_default();
|
||||
let workspace_roots = vec![session_dir.clone()];
|
||||
let turn_events = Arc::new(std::sync::Mutex::new(std::collections::VecDeque::new()));
|
||||
let in_flight = Arc::new(std::sync::atomic::AtomicBool::new(false));
|
||||
let abort = Arc::new(std::sync::atomic::AtomicBool::new(false));
|
||||
let api_key = std::env::var("OPENAI_API_KEY").unwrap_or_default();
|
||||
let model = val.get("model").and_then(|v| v.as_str()).unwrap_or("gpt-4o").to_string();
|
||||
|
||||
let params = zesdex_infrastructure::agent::AgentTurnParams {
|
||||
messages: vec![zesdex_domain::core::ChatMessage::user(prompt)],
|
||||
session_dir,
|
||||
workspace_roots,
|
||||
turn_events: turn_events.clone(),
|
||||
in_flight,
|
||||
abort,
|
||||
api_key,
|
||||
model,
|
||||
api_base: None,
|
||||
};
|
||||
|
||||
zesdex_infrastructure::agent::spawn_agent_turn(params);
|
||||
|
||||
let tx_clone = tx.clone();
|
||||
tokio::spawn(async move {
|
||||
let mut done = false;
|
||||
while !done {
|
||||
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
|
||||
let events: Vec<_> = {
|
||||
if let Ok(mut q) = turn_events.lock() {
|
||||
q.drain(..).collect()
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
};
|
||||
for ev in events {
|
||||
match ev {
|
||||
zesdex_infrastructure::TurnEvent::StreamToken(tok) => {
|
||||
let json = serde_json::json!({ "type": "token", "content": tok });
|
||||
let _ = tx_clone.send(json.to_string());
|
||||
}
|
||||
zesdex_infrastructure::TurnEvent::Done => {
|
||||
let json = serde_json::json!({ "type": "done" });
|
||||
let _ = tx_clone.send(json.to_string());
|
||||
done = true;
|
||||
}
|
||||
zesdex_infrastructure::TurnEvent::Error(err) => {
|
||||
let json = serde_json::json!({ "type": "error", "message": err });
|
||||
let _ = tx_clone.send(json.to_string());
|
||||
done = true;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback echo
|
||||
let response = serde_json::json!({
|
||||
"type": "echo",
|
||||
"data": text_str
|
||||
|
||||
Reference in New Issue
Block a user