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)]
23pub struct RunOptions {
24    /// Logical LLM route selected by the deployment.
25    pub use_case: UseCase,
26    /// Logical quality/cost mode resolved by the deployment without exposing a provider or model ID.
27    pub model_mode: ModelMode,
28    /// Tool mutation policy.
29    pub access_mode: AccessMode,
30    /// Whether this run may expose any tools to the model.
31    pub allow_tools: bool,
32    /// Maximum LLM/tool loop steps requested by the caller.
33    pub max_steps: u32,
34    /// Optional maximum normalized credits the run may consume.
35    pub credit_budget: Option<u64>,
36    /// Requests additional sanitized diagnostic observations when enabled.
37    pub debug: bool,
38}
39
40/// Decision for one prepared action in a pending interaction batch.
41#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
42pub struct InteractionDecision {
43    /// Prepared action identifier.
44    pub action_id: crate::execution::ActionId,
45    /// Whether Runtime should commit or reject the action.
46    pub proceed: bool,
47}
48
49/// User decisions submitted to a waiting run.
50#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
51pub struct Interaction {
52    /// Batch identifier emitted by `InteractionRequired`.
53    pub batch_id: MessageId,
54    /// One decision for every prepared action in the batch.
55    pub decisions: Vec<InteractionDecision>,
56}
57
58/// Durable request waiting to enter the Runtime execution loop.
59#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
60pub struct QueuedRun {
61    /// Invocation identity frozen when the request is accepted.
62    pub context: InvocationContext,
63    /// User-supplied multimodal message.
64    pub message: Message,
65    /// Runtime policy frozen when the request is accepted.
66    pub options: RunOptions,
67}
68
69impl QueuedRun {
70    /// Returns the stable run identifier used for queue idempotency.
71    #[must_use]
72    pub fn run_id(&self) -> &RunId {
73        &self.context.run_id
74    }
75}
76
77/// Semantic commands understood by the Runtime.
78#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
79#[serde(tag = "type", rename_all = "snake_case")]
80pub enum AgentCommand {
81    /// Enqueues a new user message.
82    Enqueue {
83        /// Invocation identity and ownership.
84        context: InvocationContext,
85        /// User-supplied multimodal message.
86        message: Message,
87        /// Runtime policy for this run.
88        options: RunOptions,
89    },
90    /// Supplies a response to a pending interaction.
91    SubmitInteraction {
92        /// Invocation identity and ownership.
93        context: InvocationContext,
94        /// Submitted interaction.
95        interaction: Interaction,
96    },
97    /// Requests cancellation of the current run.
98    Cancel {
99        /// Invocation identity and ownership.
100        context: InvocationContext,
101    },
102}