Skip to main content

lean_ctx/core/providers/
mod.rs

1pub mod cache;
2pub mod config;
3pub mod config_provider;
4pub mod github;
5pub mod gitlab;
6pub mod init;
7pub mod jira;
8pub mod jira_oauth;
9pub mod mcp_bridge;
10pub mod postgres;
11pub mod provider_trait;
12pub mod registry;
13
14pub use provider_trait::{ContextPacket, ContextProvider, ProviderParams};
15pub use registry::{global_registry, ProviderRegistry};
16
17use serde::{Deserialize, Serialize};
18
19use crate::core::evidence::Claim;
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct ProviderResult {
23    pub provider: String,
24    pub resource_type: String,
25    pub items: Vec<ProviderItem>,
26    pub total_count: Option<usize>,
27    pub truncated: bool,
28}
29
30#[derive(Debug, Clone, Default, Serialize, Deserialize)]
31pub struct ProviderItem {
32    pub id: String,
33    pub title: String,
34    pub state: Option<String>,
35    pub author: Option<String>,
36    pub created_at: Option<String>,
37    pub updated_at: Option<String>,
38    pub url: Option<String>,
39    pub labels: Vec<String>,
40    pub body: Option<String>,
41    /// Attributable evidence distilled from this item (confidence + source).
42    /// Empty for plain records; populated by research/extraction providers.
43    #[serde(default, skip_serializing_if = "Vec::is_empty")]
44    pub claims: Vec<Claim>,
45}
46
47impl ProviderResult {
48    pub fn format_compact(&self) -> String {
49        let mut out = format!(
50            "{} {} ({}{}):\n",
51            self.provider,
52            self.resource_type,
53            self.items.len(),
54            if self.truncated { "+" } else { "" }
55        );
56        for item in &self.items {
57            let state = item.state.as_deref().unwrap_or("");
58            let labels = if item.labels.is_empty() {
59                String::new()
60            } else {
61                format!(" [{}]", item.labels.join(","))
62            };
63            out.push_str(&format!(
64                "  #{} {} ({}){}\n",
65                item.id, item.title, state, labels
66            ));
67            for claim in &item.claims {
68                out.push_str("    ▸ ");
69                out.push_str(&claim.render());
70                out.push('\n');
71            }
72        }
73        out
74    }
75}