gemini_adk_rs/code_mode/
sandbox.rs1use async_trait::async_trait;
4use serde_json::{Map, Value};
5
6use super::CodeLimits;
7
8#[derive(Debug, Clone, PartialEq)]
11pub enum Suspension {
12 Call {
14 function: String,
16 positional: Vec<Value>,
18 keywords: Map<String, Value>,
20 },
21 Finished {
23 result: Result<Value, String>,
25 printed: String,
27 },
28}
29
30impl Suspension {
31 pub fn failed(error: impl Into<String>) -> Self {
33 Self::Finished {
34 result: Err(error.into()),
35 printed: String::new(),
36 }
37 }
38}
39
40#[async_trait]
42pub trait Execution: Send {
43 async fn resume(&mut self, answer: Result<Value, String>) -> Suspension;
47}
48
49#[async_trait]
51pub trait CodeSandbox: Send + Sync {
52 async fn start(
56 &self,
57 program: &str,
58 functions: &[String],
59 limits: &CodeLimits,
60 ) -> (Box<dyn Execution>, Suspension);
61}
62
63#[derive(Debug, Clone, Copy, Default)]
66pub struct Unavailable;
67
68struct Ended;
69
70pub(super) fn ended() -> Box<dyn Execution> {
72 Box::new(Ended)
73}
74
75#[async_trait]
76impl Execution for Ended {
77 async fn resume(&mut self, _answer: Result<Value, String>) -> Suspension {
78 Suspension::failed("the program has ended")
79 }
80}
81
82#[async_trait]
83impl CodeSandbox for Unavailable {
84 async fn start(
85 &self,
86 _program: &str,
87 _functions: &[String],
88 _limits: &CodeLimits,
89 ) -> (Box<dyn Execution>, Suspension) {
90 (
91 Box::new(Ended),
92 Suspension::failed(
93 "code mode is unavailable: this build has no sandbox (enable the \
94 `code-mode` feature)",
95 ),
96 )
97 }
98}