Skip to main content

conversation_api/execution/
agent.rs

1//! Commands accepted by the transport-independent Runtime.
2
3use serde::{Deserialize, Serialize};
4
5use crate::execution::{InvocationContext, Message, MessageId, ModelMode, RunId, UseCase};
6
7/// Mutation policy for tools that can change application state.
8#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
9#[serde(rename_all = "snake_case")]
10pub enum AccessMode {
11    /// Operations requiring approval are denied without creating an interaction.
12    /// Operations requiring no approval remain available.
13    NoAccess,
14    /// Mutating tools pause after prepare and require a user decision.
15    #[default]
16    Interactive,
17    /// Mutating tools may be committed without a user interaction.
18    FullAccess,
19}
20
21/// Per-run policy supplied by a deployment rather than selected through conditional compilation.
22#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
23#[serde(deny_unknown_fields)]
24pub struct RunOptions {
25    /// Logical LLM route selected by the deployment.
26    pub use_case: UseCase,
27    /// Logical quality/cost mode resolved by the deployment without exposing a provider or model ID.
28    pub model_mode: ModelMode,
29    /// Tool mutation policy.
30    pub access_mode: AccessMode,
31    /// Whether this run may expose any tools to the model.
32    pub allow_tools: bool,
33    /// Maximum LLM/tool loop steps requested by the caller.
34    pub max_steps: u32,
35    /// Optional maximum normalized credits the run may consume.
36    pub credit_budget: Option<u64>,
37    /// Requests additional sanitized diagnostic observations when enabled.
38    pub debug: bool,
39}
40
41/// Decision for one prepared action in a pending interaction batch.
42#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
43#[serde(deny_unknown_fields)]
44pub struct InteractionDecision {
45    /// Prepared action identifier.
46    pub action_id: crate::execution::ActionId,
47    /// Whether Runtime should commit or reject the action.
48    pub proceed: bool,
49}
50
51/// User decisions submitted to a waiting run.
52#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
53#[serde(deny_unknown_fields)]
54pub struct Interaction {
55    /// Batch identifier emitted by `InteractionRequired`.
56    pub batch_id: MessageId,
57    /// One decision for every prepared action in the batch.
58    pub decisions: Vec<InteractionDecision>,
59}
60
61/// Durable request waiting to enter the Runtime execution loop.
62#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
63pub struct QueuedRun {
64    /// Invocation identity frozen when the request is accepted.
65    pub context: InvocationContext,
66    /// User-supplied multimodal message.
67    pub message: Message,
68    /// Runtime policy frozen when the request is accepted.
69    pub options: RunOptions,
70}
71
72impl QueuedRun {
73    /// Returns the stable run identifier used for queue idempotency.
74    #[must_use]
75    pub fn run_id(&self) -> &RunId {
76        &self.context.run_id
77    }
78}
79
80/// Semantic commands understood by the Runtime.
81#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
82#[serde(tag = "type", rename_all = "snake_case")]
83#[serde(deny_unknown_fields)]
84pub enum AgentCommand {
85    /// Enqueues a new user message.
86    Enqueue {
87        /// Invocation identity and ownership.
88        context: InvocationContext,
89        /// User-supplied multimodal message.
90        message: Message,
91        /// Runtime policy for this run.
92        options: RunOptions,
93    },
94    /// Supplies a response to a pending interaction.
95    SubmitInteraction {
96        /// Invocation identity and ownership.
97        context: InvocationContext,
98        /// Submitted interaction.
99        interaction: Interaction,
100    },
101    /// Requests cancellation of the current run.
102    Cancel {
103        /// Invocation identity and ownership.
104        context: InvocationContext,
105    },
106}