agents_core/
agent.rs

1use async_trait::async_trait;
2use serde::{Deserialize, Serialize};
3use std::sync::Arc;
4
5use crate::command::Command;
6use crate::messaging::{AgentMessage, ToolInvocation};
7use crate::state::AgentStateSnapshot;
8
9/// Describes a tool that can be invoked by an agent at runtime.
10#[async_trait]
11pub trait ToolHandle: Send + Sync {
12    /// Returns the unique, stable name for this tool.
13    fn name(&self) -> &str;
14
15    /// Executes the tool given the invocation payload.
16    async fn invoke(&self, invocation: ToolInvocation) -> anyhow::Result<ToolResponse>;
17}
18
19/// Planner interface responsible for deciding which actions to take.
20#[async_trait]
21pub trait PlannerHandle: Send + Sync {
22    async fn plan(
23        &self,
24        context: PlannerContext,
25        state: Arc<AgentStateSnapshot>,
26    ) -> anyhow::Result<PlannerDecision>;
27}
28
29/// Minimal metadata about an agent instance.
30#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct AgentDescriptor {
32    pub name: String,
33    pub version: String,
34    pub description: Option<String>,
35}
36
37/// Message that returns the planner's decision for the next step.
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct PlannerDecision {
40    pub next_action: PlannerAction,
41}
42
43/// High-level actions a planner can request from the runtime.
44#[derive(Debug, Clone, Serialize, Deserialize)]
45pub enum PlannerAction {
46    CallTool {
47        tool_name: String,
48        payload: serde_json::Value,
49    },
50    Respond {
51        message: AgentMessage,
52    },
53    Terminate,
54}
55
56/// Context passed to planners containing the latest exchange history.
57#[derive(Debug, Clone, Serialize, Deserialize)]
58pub struct PlannerContext {
59    pub history: Vec<AgentMessage>,
60    pub system_prompt: String,
61}
62
63/// Abstraction for hosting a fully configured agent (planner + tools + prompts).
64#[async_trait]
65pub trait AgentHandle: Send + Sync {
66    async fn describe(&self) -> AgentDescriptor;
67
68    async fn handle_message(
69        &self,
70        input: AgentMessage,
71        state: Arc<AgentStateSnapshot>,
72    ) -> anyhow::Result<AgentMessage>;
73}
74
75#[derive(Debug, Clone)]
76pub enum ToolResponse {
77    Message(AgentMessage),
78    Command(Command),
79}