Skip to main content

codetether_agent/tui/app/autochat/
mod.rs

1//! Autochat relay integration for the TUI event loop.
2
3pub mod events;
4pub mod handler;
5pub mod notify;
6pub mod request;
7pub mod run;
8pub mod state;
9pub mod summary;
10pub mod worker;
11
12pub use handler::handle_autochat_event;
13
14// ─────────────────────────────────────────────────────────────────
15// Persona chain for the multi-step relay.
16//
17// Kept inline so the module tree stays visible to rust-analyzer
18// even when it hasn't picked up newly created sibling files yet.
19// ─────────────────────────────────────────────────────────────────
20pub mod persona {
21    /// A single persona step in the relay.
22    #[derive(Debug, Clone)]
23    pub struct Persona {
24        pub name: &'static str,
25        pub instructions: &'static str,
26    }
27
28    /// Default relay chain used by `/autochat` when no OKR is attached.
29    pub fn default_chain() -> &'static [Persona] {
30        &[
31            Persona {
32                name: "architect",
33                instructions: "You are the architect. Produce a concrete, numbered plan to execute the task. Keep it under 12 steps and call out risks and concrete files/systems involved.",
34            },
35            Persona {
36                name: "implementer",
37                instructions: "You are the implementer. Take the architect's plan and turn it into specific implementation actions: code changes, commands, API calls, or config edits. Be concrete. Cite exact identifiers where possible.",
38            },
39            Persona {
40                name: "reviewer",
41                instructions: "You are the reviewer. Evaluate the architect's plan and the implementer's steps for gaps, risks, and missing verification. Produce a final action list with explicit verification checks.",
42            },
43        ]
44    }
45}
46
47// ─────────────────────────────────────────────────────────────────
48// Provider request builder for a single relay step.
49// ─────────────────────────────────────────────────────────────────
50pub mod step_request {
51    use crate::provider::{CompletionRequest, ContentPart, Message, Role};
52
53    use super::persona::Persona;
54
55    /// Build the request for one persona turn.
56    ///
57    /// The relay feeds the running baton (previous output) forward as
58    /// extra user-message context so each persona can build on it.
59    pub fn build_step_request(
60        model: String,
61        persona: &Persona,
62        task: &str,
63        baton: &str,
64    ) -> CompletionRequest {
65        CompletionRequest {
66            model,
67            messages: vec![system_message(persona), user_message(task, baton)],
68            tools: Vec::new(),
69            temperature: Some(0.9),
70            top_p: Some(0.9),
71            max_tokens: Some(1000),
72            stop: Vec::new(),
73        }
74    }
75
76    fn system_message(persona: &Persona) -> Message {
77        Message {
78            role: Role::System,
79            content: vec![ContentPart::Text {
80                text: persona.instructions.to_string(),
81            }],
82        }
83    }
84
85    fn user_message(task: &str, baton: &str) -> Message {
86        let mut text = format!("Task:\n{task}\n");
87        if !baton.trim().is_empty() {
88            text.push_str("\nPrevious relay output:\n");
89            text.push_str(baton);
90        }
91        Message {
92            role: Role::User,
93            content: vec![ContentPart::Text { text }],
94        }
95    }
96}