use async_trait::async_trait;
use awaken::contract::event::AgentEvent;
use awaken::contract::event_sink::EventSink;
use awaken::contract::message::Message;
use awaken::engine::GenaiExecutor;
use awaken::loop_runner::build_agent_env;
use awaken::registry::ResolvedAgent;
use awaken::stores::InMemoryStore;
use awaken::*;
use std::sync::Arc;
struct ConsoleSink;
#[async_trait]
impl EventSink for ConsoleSink {
async fn emit(&self, event: AgentEvent) {
if let AgentEvent::TextDelta { delta } = &event {
print!("{delta}");
}
}
}
struct SimpleResolver {
agent: ResolvedAgent,
}
impl AgentResolver for SimpleResolver {
fn resolve(&self, _agent_id: &str) -> Result<ResolvedAgent, awaken::RuntimeError> {
let mut agent = self.agent.clone();
agent.env = build_agent_env(&[], &agent)?;
Ok(agent)
}
}
fn build_llm_executor() -> GenaiExecutor {
if let (Ok(mut base_url), Ok(api_key)) =
(std::env::var("LLM_BASE_URL"), std::env::var("LLM_API_KEY"))
{
use genai::adapter::AdapterKind;
use genai::resolver::{AuthData, Endpoint};
use genai::{ModelIden, ServiceTarget};
if !base_url.ends_with('/') {
base_url.push('/');
}
let adapter = match std::env::var("LLM_ADAPTER").as_deref() {
Ok("anthropic") => AdapterKind::Anthropic,
_ => AdapterKind::OpenAI,
};
let client = genai::Client::builder()
.with_service_target_resolver_fn(move |st: ServiceTarget| {
Ok(ServiceTarget {
endpoint: Endpoint::from_owned(base_url.clone()),
auth: AuthData::from_single(api_key.clone()),
model: ModelIden::new(adapter, st.model.model_name),
})
})
.build();
GenaiExecutor::with_client(client)
} else {
GenaiExecutor::new()
}
}
#[tokio::main(flavor = "current_thread")]
async fn main() {
let model = std::env::var("LLM_MODEL")
.or_else(|_| std::env::var("OPENAI_MODEL"))
.unwrap_or_else(|_| "gpt-4o-mini".into());
let llm = Arc::new(build_llm_executor());
let agent = ResolvedAgent::new(
"chat",
&model,
"You are a helpful assistant. Be concise. Remember what the user tells you.",
llm,
);
let resolver = Arc::new(SimpleResolver {
agent: agent.clone(),
});
let store = Arc::new(InMemoryStore::new());
let runtime = AgentRuntime::new(resolver)
.with_commit_coordinator(awaken::stores::MemoryCommitCoordinator::wrap(store));
let thread_id = "conversation-1";
let turns = [
"My name is Alice. Remember it.",
"What is the capital of France?",
"What is my name?",
];
for (i, user_msg) in turns.iter().enumerate() {
print!(
"\n[Turn {}] User: {}\n[Turn {}] Assistant: ",
i + 1,
user_msg,
i + 1
);
let request =
RunActivation::new(thread_id, vec![Message::user(*user_msg)]).with_agent_id("chat");
match runtime.run(request, Arc::new(ConsoleSink)).await {
Ok(result) => {
print!(" [{:?}]", result.termination);
}
Err(e) => {
print!(" [ERROR: {e}]");
}
}
}
print!("\n\n=== Multi-turn test complete ===\n");
}