1use crate::{AttachmentRef, ToolCallRecord};
2
3#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
4pub struct ExecImage {
5 pub mime: String,
6 #[serde(default, skip_serializing_if = "Option::is_none")]
7 pub reference: Option<AttachmentRef>,
8 #[serde(default, skip_serializing_if = "Vec::is_empty")]
9 pub data: Vec<u8>,
10 pub label: String,
11 #[serde(default, skip_serializing_if = "Option::is_none")]
12 pub width: Option<u32>,
13 #[serde(default, skip_serializing_if = "Option::is_none")]
14 pub height: Option<u32>,
15}
16
17#[derive(Clone, Debug, Default, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
18pub struct TextProjectionMetadata {
19 pub truncated: bool,
20 pub original_chars: usize,
21 pub projected_chars: usize,
22 pub original_lines: usize,
23 pub projected_lines: usize,
24 pub limit: usize,
25 pub limit_mode: String,
26 pub max_lines: usize,
27}
28
29#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
30pub struct ExecResponse {
31 pub observations: Vec<String>,
32 pub observation_truncation: Vec<TextProjectionMetadata>,
33 pub tool_calls: Vec<ToolCallRecord>,
34 pub images: Vec<ExecImage>,
35 pub printed_images: Vec<AttachmentRef>,
36 pub error: Option<String>,
37 pub duration_ms: u64,
38 pub terminal_finish: Option<serde_json::Value>,
43}
44
45#[derive(Clone, Debug, Default, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
47pub struct PromptUsage {
48 pub prompt_context_tokens: usize,
49 pub input_tokens: usize,
50 pub cache_read_input_tokens: usize,
51 pub cache_write_input_tokens: usize,
52 pub context_budget_tokens: usize,
53}