supercode_interchange/orchestration/
worker.rs1use std::collections::BTreeMap;
4
5use schemars::JsonSchema;
6use serde::{Deserialize, Serialize};
7
8use crate::ontology::{HarnessId, SecretRef};
9
10#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
12#[serde(untagged)]
13pub enum EnvValue {
14 Literal(String),
16 Secret(SecretRef),
18}
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Default)]
22#[serde(rename_all = "snake_case")]
23pub enum PermissionDefault {
24 #[default]
26 Deny,
27 Allow,
29}
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Default)]
34#[serde(rename_all = "snake_case")]
35pub enum PermissionUnattended {
36 #[default]
38 Deny,
39 Approve,
41}
42
43impl PermissionUnattended {
44 fn is_deny(&self) -> bool {
45 *self == Self::Deny
46 }
47}
48
49#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
51pub struct PermissionPolicy {
52 #[serde(default = "default_permission_timeout")]
54 pub timeout_seconds: u32,
55 #[serde(default)]
57 pub default: PermissionDefault,
58 #[serde(default, skip_serializing_if = "PermissionUnattended::is_deny")]
60 pub unattended: PermissionUnattended,
61}
62
63fn default_permission_timeout() -> u32 {
64 300
65}
66
67impl Default for PermissionPolicy {
68 fn default() -> Self {
69 Self {
70 timeout_seconds: 300,
71 default: PermissionDefault::Deny,
72 unattended: PermissionUnattended::Deny,
73 }
74 }
75}
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Default)]
79#[serde(rename_all = "snake_case")]
80pub enum WorkerHome {
81 #[default]
83 Profile,
84 User,
87}
88
89impl WorkerHome {
90 fn is_profile(&self) -> bool {
91 matches!(self, Self::Profile)
92 }
93}
94
95#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Default)]
97#[serde(rename_all = "snake_case")]
98pub enum WorkerSurface {
99 #[default]
101 Headless,
102 Pane,
106}
107
108impl WorkerSurface {
109 fn is_headless(&self) -> bool {
110 matches!(self, Self::Headless)
111 }
112}
113
114#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
116pub struct WorkerSpec {
117 pub harness: HarnessId,
119 #[serde(default)]
121 pub model: Option<String>,
122 #[serde(default)]
124 pub preset: Option<String>,
125 #[serde(default = "default_cwd")]
127 pub cwd: String,
128 #[serde(default)]
130 pub env: BTreeMap<String, EnvValue>,
131 #[serde(default)]
133 pub permission: PermissionPolicy,
134 #[serde(default, skip_serializing_if = "WorkerHome::is_profile")]
136 pub home: WorkerHome,
137 #[serde(default, skip_serializing_if = "WorkerSurface::is_headless")]
139 pub surface: WorkerSurface,
140 #[serde(default, skip_serializing_if = "Option::is_none")]
142 pub capacity: Option<u32>,
143}
144
145fn default_cwd() -> String {
146 ".".to_string()
147}