loopsmith_core/config/
constraints.rs1use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5use std::collections::BTreeMap;
6
7#[derive(Debug, Clone, Serialize, Deserialize, Default, JsonSchema)]
8#[serde(deny_unknown_fields)]
9pub struct Constraints {
10 #[serde(default)]
12 pub global: ConstraintSet,
13 #[serde(default)]
15 pub per_node: BTreeMap<String, ConstraintSet>,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize, Default, JsonSchema)]
19#[serde(deny_unknown_fields)]
20pub struct ConstraintSet {
21 #[serde(default)]
23 pub rules: Vec<String>,
24 #[serde(default)]
25 pub forbidden_paths: Vec<String>,
26 #[serde(default)]
27 pub forbidden_commands: Vec<String>,
28 #[serde(default)]
29 pub max_tokens: Option<u64>,
30 #[serde(default)]
31 pub max_seconds: Option<u64>,
32 #[serde(default)]
35 pub human_checkpoint: Vec<String>,
36}
37
38impl ConstraintSet {
39 pub fn frozen_git_rules() -> Vec<String> {
42 vec![
43 "Never git stash. Never git reset.".into(),
44 "No git command except committing a specific file.".into(),
45 "No slow commands before the test phase.".into(),
46 ]
47 }
48
49 pub fn merged(global: &ConstraintSet, node: Option<&ConstraintSet>) -> ConstraintSet {
52 let mut out = global.clone();
53 if let Some(n) = node {
54 out.rules.extend(n.rules.iter().cloned());
55 out.forbidden_paths.extend(n.forbidden_paths.iter().cloned());
56 out.forbidden_commands
57 .extend(n.forbidden_commands.iter().cloned());
58 out.human_checkpoint
59 .extend(n.human_checkpoint.iter().cloned());
60 if n.max_tokens.is_some() {
61 out.max_tokens = n.max_tokens;
62 }
63 if n.max_seconds.is_some() {
64 out.max_seconds = n.max_seconds;
65 }
66 }
67 out
68 }
69}