Skip to main content

supercode_interchange/orchestration/
profile.rs

1//! The home and its profiles (§2.1): the root folder IS the `default`
2//! profile; `profiles/<name>/` are the named ones.
3
4use std::collections::BTreeMap;
5use std::path::PathBuf;
6
7use schemars::JsonSchema;
8use serde::{Deserialize, Serialize};
9use serde_json::Value;
10
11use super::{Access, ChannelConfig, Fire, Job, Obligation, Route, WebhookSubscription, WorkerSpec};
12use crate::ontology::Binding;
13
14/// The persona: `AGENTS.md` at the profile root, content hash first.
15#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
16pub struct PersonaRef {
17    /// Always `AGENTS.md` in our folder (`SOUL.md` in a Hermes home).
18    pub path: String,
19    /// The text, when loaded.
20    #[serde(default)]
21    pub text: Option<String>,
22    /// Hex sha256 of the text.
23    pub sha256: String,
24}
25
26/// What a profile carries that the model does not interpret.
27#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
28pub struct ProfileResidue {
29    /// `config.yaml` keys that are the source harness's, verbatim.
30    #[serde(default)]
31    pub config: BTreeMap<String, Value>,
32    /// Unmodeled files, by path relative to the profile dir; copied verbatim.
33    #[serde(default)]
34    pub files: Vec<String>,
35}
36
37/// One profile: a folder with `AGENTS.md` at its root.
38#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
39pub struct Profile {
40    /// `default` for the root, else the folder name.
41    pub name: String,
42    /// The folder.
43    pub dir: PathBuf,
44    /// O — which harness runs it.
45    #[serde(default)]
46    pub worker: Option<WorkerSpec>,
47    /// O — `AGENTS.md`.
48    #[serde(default)]
49    pub persona: Option<PersonaRef>,
50    /// H — `config.yaml` `platforms:` blocks.
51    #[serde(default)]
52    pub channels: BTreeMap<String, ChannelConfig>,
53    /// H — `gateway.profile_routes`.
54    #[serde(default)]
55    pub routes: Vec<Route>,
56    /// H — `cron/jobs.json`.
57    #[serde(default)]
58    pub jobs: BTreeMap<String, Job>,
59    /// H — `webhook_subscriptions.json`.
60    #[serde(default)]
61    pub subscriptions: BTreeMap<String, WebhookSubscription>,
62    /// H — allowlists and pairing.
63    #[serde(default)]
64    pub access: Access,
65    /// O — the conversations, keyed by their slot (the surface key string for
66    /// a live one, `<key>#<started_at>[#n]` for ended ones).
67    #[serde(default)]
68    pub bindings: BTreeMap<String, Binding>,
69    /// H — `cron/executions.db`.
70    #[serde(default)]
71    pub fires: Vec<Fire>,
72    /// H — `delivery_obligations`.
73    #[serde(default)]
74    pub obligations: Vec<Obligation>,
75    /// What the model does not interpret.
76    #[serde(default)]
77    pub residue: ProfileResidue,
78}
79
80/// The whole home: the persisted half of `OrchestratorState` (§2.1); the
81/// runtime half is never written and is not part of the wire.
82#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
83pub struct Orchestration {
84    /// The home folder.
85    pub root: PathBuf,
86    /// `default` is the root folder; the rest are `profiles/<name>/`.
87    pub profiles: BTreeMap<String, Profile>,
88}