use alloc::{collections::BTreeMap, string::String, vec::Vec};
use crate::{AllowList, NetworkPolicy, SecretRequirement};
#[cfg(feature = "schemars")]
use schemars::JsonSchema;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[non_exhaustive]
#[derive(Clone, Debug, Default, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
pub struct Capabilities {
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub http: Option<HttpCaps>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub secrets: Option<SecretsCaps>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub kv: Option<KvCaps>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub fs: Option<FsCaps>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub net: Option<NetCaps>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub tools: Option<ToolsCaps>,
}
impl Capabilities {
pub fn new() -> Self {
Self::default()
}
pub fn is_empty(&self) -> bool {
self.http.is_none()
&& self.secrets.is_none()
&& self.kv.is_none()
&& self.fs.is_none()
&& self.net.is_none()
&& self.tools.is_none()
}
}
#[non_exhaustive]
#[derive(Clone, Debug, Default, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
pub struct HttpCaps {
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub allow_list: Option<AllowList>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub max_body_bytes: Option<u64>,
}
impl HttpCaps {
pub fn new() -> Self {
Self::default()
}
}
#[non_exhaustive]
#[derive(Clone, Debug, Default, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
pub struct SecretsCaps {
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Vec::is_empty")
)]
pub required: Vec<SecretRequirement>,
}
impl SecretsCaps {
pub fn new() -> Self {
Self::default()
}
}
#[non_exhaustive]
#[derive(Clone, Debug, Default, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
pub struct KvCaps {
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Vec::is_empty")
)]
pub namespaces: Vec<String>,
}
impl KvCaps {
pub fn new() -> Self {
Self::default()
}
}
#[non_exhaustive]
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
pub struct FsCaps {
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Vec::is_empty")
)]
pub paths: Vec<String>,
#[cfg_attr(feature = "serde", serde(default = "FsCaps::default_read_only"))]
pub read_only: bool,
}
impl Default for FsCaps {
fn default() -> Self {
Self {
paths: Vec::new(),
read_only: true,
}
}
}
impl FsCaps {
const fn default_read_only() -> bool {
true
}
pub fn new() -> Self {
Self::default()
}
}
#[non_exhaustive]
#[derive(Clone, Debug, Default, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
pub struct NetCaps {
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub policy: Option<NetworkPolicy>,
}
impl NetCaps {
pub fn new() -> Self {
Self::default()
}
}
#[non_exhaustive]
#[derive(Clone, Debug, Default, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
pub struct ToolsCaps {
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Vec::is_empty")
)]
pub allowed: Vec<String>,
}
impl ToolsCaps {
pub fn new() -> Self {
Self::default()
}
}
#[non_exhaustive]
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
pub struct Limits {
pub memory_mb: u32,
pub wall_time_ms: u64,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub fuel: Option<u64>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub files: Option<u32>,
}
impl Limits {
pub fn new(memory_mb: u32, wall_time_ms: u64) -> Self {
Self {
memory_mb,
wall_time_ms,
fuel: None,
files: None,
}
}
}
impl Default for Limits {
fn default() -> Self {
Self::new(0, 0)
}
}
#[non_exhaustive]
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
pub struct TelemetrySpec {
pub span_prefix: String,
#[cfg_attr(feature = "serde", serde(default))]
pub attributes: BTreeMap<String, String>,
pub emit_node_spans: bool,
}
impl TelemetrySpec {
pub fn new(span_prefix: impl Into<String>) -> Self {
Self {
span_prefix: span_prefix.into(),
attributes: BTreeMap::new(),
emit_node_spans: false,
}
}
}
impl Default for TelemetrySpec {
fn default() -> Self {
Self::new("greentic")
}
}