Skip to main content

nuro_core/
agent.rs

1use crate::{message::Message, Result};
2use async_trait::async_trait;
3use serde_json::Value;
4use std::collections::HashMap;
5
6#[derive(Debug, Clone)]
7pub enum AgentInput {
8    Text(String),
9    Messages(Vec<Message>),
10}
11
12impl AgentInput {
13    pub fn text(text: impl Into<String>) -> Self {
14        Self::Text(text.into())
15    }
16
17    pub fn messages(messages: Vec<Message>) -> Self {
18        Self::Messages(messages)
19    }
20}
21
22#[derive(Debug, Clone)]
23pub struct AgentOutput {
24    pub messages: Vec<Message>,
25}
26
27impl AgentOutput {
28    pub fn new(messages: Vec<Message>) -> Self {
29        Self { messages }
30    }
31
32    pub fn last_message(&self) -> Option<&Message> {
33        self.messages.last()
34    }
35
36    /// 一个便捷方法:优先返回最后一条消息的文本内容;若没有,则回退到最近的 ToolResult
37    pub fn text(&self) -> Option<String> {
38        if let Some(last) = self.last_message() {
39            if let Some(text) = last.text_content() {
40                return Some(text);
41            }
42        }
43
44        // 回退:找最近的非错误 ToolResult
45        for msg in self.messages.iter().rev() {
46            for block in &msg.content {
47                if let crate::message::ContentBlock::ToolResult { content, is_error, .. } = block
48                {
49                    if !is_error {
50                        return Some(content.to_string());
51                    }
52                }
53            }
54        }
55        None
56    }
57}
58
59#[derive(Debug)]
60pub struct AgentContext {
61    pub metadata: HashMap<String, Value>,
62}
63
64impl AgentContext {
65    pub fn new() -> Self {
66        Self {
67            metadata: HashMap::new(),
68        }
69    }
70}
71
72#[async_trait]
73pub trait Agent: Send + Sync {
74    async fn invoke(&self, input: AgentInput, ctx: &mut AgentContext) -> Result<AgentOutput>;
75}