1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//! Session-local operating-mode selection for `/mode auto`.
//!
//! The core loop knows nothing about the TUI's concrete mode enum. It receives
//! this narrow collaborator only when the human has selected `auto`, and the
//! model may use it to request one of the bounded working styles for a future
//! turn. The collaborator cannot change the current turn's disposition or
//! caveats, and the schema deliberately excludes `full-auto`.
/// Model-facing seam behind `select_operating_mode`.
///
/// Implementations own the session state and validate the requested name.
/// Selection applies to a later turn; callers must never reinterpret the
/// result as authority for the tool round already in flight.
pub trait OperatingModeControl: Send + Sync {
/// Select a bounded working style for a future turn.
fn select_operating_mode(&self, mode: &str) -> Result<String, String>;
}
/// Tool definition advertised only when an [`OperatingModeControl`] is
/// injected (the interactive session is configured with `/mode auto`).
pub fn select_operating_mode_tool_definition() -> serde_json::Value {
serde_json::json!({
"type": "function",
"function": {
"name": "select_operating_mode",
"description": "In /mode auto, select the working style for the next \
action-shaped turn. This changes no permissions and \
never changes the authority or disposition of the \
current turn. Choose chat, dev, admin, plan, or \
diagnose; full-auto is human-only.",
"parameters": {
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": ["chat", "dev", "admin", "plan", "diagnose"],
"description": "The bounded working style to use next."
}
},
"required": ["mode"],
"additionalProperties": false
}
}
})
}
#[cfg(test)]
mod tests {
use super::select_operating_mode_tool_definition;
#[test]
fn schema_excludes_human_only_modes() {
let definition = select_operating_mode_tool_definition();
let modes = definition["function"]["parameters"]["properties"]["mode"]["enum"]
.as_array()
.unwrap();
assert!(modes.iter().any(|mode| mode == "dev"));
assert!(!modes.iter().any(|mode| mode == "auto"));
assert!(!modes.iter().any(|mode| mode == "full-auto"));
}
}