Skip to repository content139 lines · 4.6 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T03:40:56.537Z Public web read
NIP-34 coordinate
30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omegaMaintainersHidden in public view
References2 branches · 1 tag
Read-only clone
git clone https://openagents.com/git/tenant.openagents/omega.gitBrowse files
full_auto.rs
1use chrono::{DateTime, Utc};
2use serde_json::Value;
3
4const ACTIVE_STATES: &[&str] = &["running", "pausing", "paused", "retrying", "stalled"];
5
6#[derive(Clone, Debug, PartialEq, Eq)]
7pub struct WorkroomFullAutoRun {
8 pub run_ref: String,
9 pub objective: String,
10 pub lane: String,
11 pub state: String,
12 pub exact_unattended_duration: String,
13 pub terminal_reason: Option<String>,
14 pub latest_turn: Option<String>,
15}
16
17impl WorkroomFullAutoRun {
18 pub fn from_value(value: &Value, now: DateTime<Utc>) -> Option<Self> {
19 let run_ref = public_text(value, "runRef")?;
20 let objective = public_text(value, "objective")?;
21 let state = public_text(value, "state")?;
22 let lane = public_text(value, "lane").unwrap_or_else(|| "unassigned".into());
23 let started_at = value
24 .get("startedAt")
25 .or_else(|| value.get("createdAt"))
26 .and_then(Value::as_str)
27 .and_then(|value| DateTime::parse_from_rfc3339(value).ok())
28 .map(|value| value.with_timezone(&Utc));
29 let exact_unattended_duration = started_at
30 .map(|started_at| format_duration((now - started_at).num_seconds().max(0)))
31 .unwrap_or_else(|| "unavailable (record has no start time)".into());
32 let terminal_reason = if ACTIVE_STATES.contains(&state.as_str()) {
33 None
34 } else {
35 public_text(value, "terminalReason")
36 .or_else(|| public_text(value, "stallCause"))
37 .or_else(|| Some("record did not supply a terminal reason".into()))
38 };
39 let latest_turn = value
40 .get("turns")
41 .and_then(Value::as_array)
42 .and_then(|turns| turns.last())
43 .and_then(|turn| {
44 let lane = public_text(turn, "lane")?;
45 let summary = public_text(turn, "summary")?;
46 Some(format!("{lane}: {summary}"))
47 });
48
49 Some(Self {
50 run_ref,
51 objective,
52 lane,
53 state,
54 exact_unattended_duration,
55 terminal_reason,
56 latest_turn,
57 })
58 }
59}
60
61fn public_text(value: &Value, field: &str) -> Option<String> {
62 let text = value.get(field)?.as_str()?.trim();
63 if text.is_empty() || text.len() > 512 || text.contains("Bearer ") || text.contains("/Users/") {
64 return None;
65 }
66 Some(text.to_string())
67}
68
69fn format_duration(total_seconds: i64) -> String {
70 let hours = total_seconds / 3_600;
71 let minutes = (total_seconds % 3_600) / 60;
72 let seconds = total_seconds % 60;
73 format!("{hours:02}:{minutes:02}:{seconds:02}")
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79 use chrono::TimeZone as _;
80 use serde_json::json;
81
82 #[test]
83 fn projects_exact_record_bound_duration_and_live_turn() {
84 let now = Utc.with_ymd_and_hms(2026, 7, 24, 12, 1, 2).unwrap();
85 let run = WorkroomFullAutoRun::from_value(
86 &json!({
87 "runRef": "run.fa.1",
88 "objective": "Ship the verified change",
89 "lane": "codex-local",
90 "state": "running",
91 "startedAt": "2026-07-24T10:00:00Z",
92 "turns": [{"lane": "codex-local", "summary": "Tests are running"}],
93 }),
94 now,
95 )
96 .unwrap();
97
98 assert_eq!(run.exact_unattended_duration, "02:01:02");
99 assert_eq!(
100 run.latest_turn.as_deref(),
101 Some("codex-local: Tests are running")
102 );
103 assert_eq!(run.terminal_reason, None);
104 }
105
106 #[test]
107 fn terminal_state_never_turns_silence_into_completion() {
108 let run = WorkroomFullAutoRun::from_value(
109 &json!({
110 "runRef": "run.fa.2",
111 "objective": "Verify",
112 "lane": "claude-local",
113 "state": "failed",
114 "createdAt": "2026-07-24T10:00:00Z"
115 }),
116 Utc.with_ymd_and_hms(2026, 7, 24, 10, 0, 1).unwrap(),
117 )
118 .unwrap();
119
120 assert_eq!(
121 run.terminal_reason.as_deref(),
122 Some("record did not supply a terminal reason")
123 );
124 assert_ne!(run.state, "completed");
125 }
126
127 #[test]
128 fn drops_private_or_unbounded_projection_text() {
129 let now = Utc::now();
130 assert!(
131 WorkroomFullAutoRun::from_value(
132 &json!({"runRef":"run.1","objective":"/Users/owner/secret","state":"running"}),
133 now,
134 )
135 .is_none()
136 );
137 }
138}
139