supercode-interchange 0.4.18

Canonical, provider-neutral session interchange primitives for Supercode
Documentation
//! The worker: which harness runs a profile's conversations, and how (§2.2).

use std::collections::BTreeMap;

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use crate::ontology::{HarnessId, SecretRef};

/// A worker environment value: a literal, or a secret by reference.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(untagged)]
pub enum EnvValue {
    /// A plain, non-secret value.
    Literal(String),
    /// A secret, named and never held.
    Secret(SecretRef),
}

/// What happens to a worker's permission prompt when no human answers.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Default)]
#[serde(rename_all = "snake_case")]
pub enum PermissionDefault {
    /// Refuse after the timeout.
    #[default]
    Deny,
    /// Allow after the timeout.
    Allow,
}

/// How prompts are answered when no human is reachable (§4.6).
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct PermissionPolicy {
    /// Seconds a relayed prompt waits for an answer.
    #[serde(default = "default_permission_timeout")]
    pub timeout_seconds: u32,
    /// The answer given when nobody replies in time.
    #[serde(default)]
    pub default: PermissionDefault,
}

fn default_permission_timeout() -> u32 {
    300
}

impl Default for PermissionPolicy {
    fn default() -> Self {
        Self {
            timeout_seconds: 300,
            default: PermissionDefault::Deny,
        }
    }
}

/// The worker specification (O-record; Hermes has no worker choice).
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct WorkerSpec {
    /// Any registry id whose runtime can start a session.
    pub harness: HarnessId,
    /// Model, where the harness's door accepts one.
    #[serde(default)]
    pub model: Option<String>,
    /// supercode preset name.
    #[serde(default)]
    pub preset: Option<String>,
    /// Relative to the profile dir; `.` by default.
    #[serde(default = "default_cwd")]
    pub cwd: String,
    /// Extra environment for the worker process; secrets by reference.
    #[serde(default)]
    pub env: BTreeMap<String, EnvValue>,
    /// Permission prompt policy.
    #[serde(default)]
    pub permission: PermissionPolicy,
}

fn default_cwd() -> String {
    ".".to_string()
}