Skip to main content

llm_wiki/acp/
mod.rs

1mod graph;
2mod helpers;
3mod ingest;
4mod lint;
5mod research;
6mod server;
7
8use std::collections::HashMap;
9use std::sync::atomic::AtomicBool;
10use std::sync::{Arc, Mutex};
11
12use agent_client_protocol::schema::{ContentBlock, PromptRequest};
13
14pub use server::serve_acp;
15
16// ── Session ───────────────────────────────────────────────────────────────────
17
18/// An active ACP session tracking identity and execution state.
19pub struct AcpSession {
20    /// Unique session identifier assigned at creation.
21    pub id: String,
22    /// Optional human-readable label for the session.
23    pub label: Option<String>,
24    /// Wiki name associated with the session, if any.
25    pub wiki: Option<String>,
26    /// Unix timestamp (milliseconds) when the session was created.
27    pub created_at: u64,
28    /// ID of the currently executing tool run, if any.
29    pub active_run: Option<String>,
30    /// Cooperative cancellation flag. Set by cancel handler; polled by workflow steps.
31    pub cancelled: Arc<AtomicBool>,
32}
33
34/// Shared map of active ACP sessions, keyed by session ID.
35pub type Sessions = Arc<Mutex<HashMap<String, AcpSession>>>;
36
37// ── Dispatch ──────────────────────────────────────────────────────────────────
38
39/// Parse `llm-wiki:<workflow> <text>` or fall back to keyword matching.
40pub fn dispatch_workflow(prompt: &str) -> (&str, &str) {
41    if let Some(rest) = prompt.strip_prefix("llm-wiki:") {
42        let rest = rest.trim_start();
43        if let Some(pos) = rest.find(char::is_whitespace) {
44            let workflow = &rest[..pos];
45            let text = rest[pos..].trim_start();
46            return (workflow, text);
47        }
48        return (rest, "");
49    }
50    ("research", prompt)
51}
52
53fn extract_prompt_text(req: &PromptRequest) -> String {
54    req.prompt
55        .iter()
56        .filter_map(|block| match block {
57            ContentBlock::Text(t) => Some(t.text.as_str()),
58            _ => None,
59        })
60        .collect::<Vec<_>>()
61        .join(" ")
62}
63
64/// Convenience alias for ACP step return values.
65pub type StepResult<T = ()> = std::result::Result<T, agent_client_protocol::schema::Error>;
66
67/// Generate a unique tool-run ID from workflow name, step name, and current timestamp.
68pub fn make_tool_id(workflow: &str, step: &str) -> String {
69    format!(
70        "{workflow}-{step}-{}",
71        chrono::Utc::now().timestamp_millis()
72    )
73}