use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
pub(crate) const MAX_BATCH_HISTORY_BYTES: usize = 8 * 1024 * 1024;
pub(crate) const MAX_NESTED_SESSION_BYTES: usize = crate::context::REPLAY_JSONL_MAX_BYTES / 2;
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
#[serde(default, deny_unknown_fields)]
pub struct CodeModeLimits {
pub max_source_bytes: usize,
pub max_inner_calls: usize,
pub max_runtime_ms: u64,
pub max_memory_bytes: usize,
pub max_inner_result_bytes: usize,
pub max_total_result_bytes: usize,
pub max_return_bytes: usize,
}
impl Default for CodeModeLimits {
fn default() -> Self {
Self {
max_source_bytes: 64 * 1024,
max_inner_calls: 200,
max_runtime_ms: 60_000,
max_memory_bytes: 32 * 1024 * 1024,
max_inner_result_bytes: 1024 * 1024,
max_total_result_bytes: 8 * 1024 * 1024,
max_return_bytes: 256 * 1024,
}
}
}
impl CodeModeLimits {
pub(crate) fn validate(&self) -> anyhow::Result<()> {
for (name, value, minimum, maximum) in [
(
"max_source_bytes",
self.max_source_bytes as u64,
1,
1024 * 1024,
),
("max_inner_calls", self.max_inner_calls as u64, 1, 1000),
("max_runtime_ms", self.max_runtime_ms, 1, 3_600_000),
(
"max_memory_bytes",
self.max_memory_bytes as u64,
1024 * 1024,
256 * 1024 * 1024,
),
(
"max_inner_result_bytes",
self.max_inner_result_bytes as u64,
1,
16 * 1024 * 1024,
),
(
"max_total_result_bytes",
self.max_total_result_bytes as u64,
1,
64 * 1024 * 1024,
),
(
"max_return_bytes",
self.max_return_bytes as u64,
1,
4 * 1024 * 1024,
),
] {
anyhow::ensure!(
(minimum..=maximum).contains(&value),
"capabilities.tools.code_mode.limits.{name} must be between {minimum} and {maximum}"
);
}
Ok(())
}
}
pub(crate) fn budget_snapshot(used: u64, limit: u64) -> serde_json::Value {
serde_json::json!({"used": used, "limit": limit, "remaining": limit.saturating_sub(used)})
}