gestura_core_foundation/
context.rs

1//! Context data types shared across domain crates.
2//!
3//! These are pure data structures used by the pipeline, context management,
4//! and other subsystems. They live in foundation so that domain crates
5//! (`gestura-core-pipeline`, `gestura-core-tools`, etc.) can reference them
6//! without depending on the full `gestura-core` facade.
7
8use serde::{Deserialize, Serialize};
9use std::collections::HashSet;
10
11/// Categories of context that might be needed for a request
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
13#[serde(rename_all = "snake_case")]
14pub enum ContextCategory {
15    /// File system operations (read, write, edit files)
16    FileSystem,
17    /// Shell command execution
18    Shell,
19    /// Git operations
20    Git,
21    /// Code analysis (symbols, references)
22    Code,
23    /// Web fetching and search
24    Web,
25    /// Voice and audio processing
26    Voice,
27    /// Configuration management
28    Config,
29    /// Session and history
30    Session,
31    /// Tool introspection
32    Tools,
33    /// Agent orchestration
34    Agent,
35    /// MCP protocol operations
36    Mcp,
37    /// A2A protocol operations
38    A2a,
39    /// Task management for current session
40    Task,
41    /// Screen capture and recording (screenshot, screen_record)
42    Screen,
43    /// General conversation (no specific tools)
44    General,
45}
46
47/// Request analysis result - determines what context is needed
48#[derive(Debug, Clone, Default, Serialize, Deserialize)]
49pub struct RequestAnalysis {
50    /// Original request text
51    pub request: String,
52    /// Detected categories needed
53    pub categories: HashSet<ContextCategory>,
54    /// Specific tools that might be needed
55    pub suggested_tools: Vec<String>,
56    /// Whether this looks like a tool-related request
57    pub needs_tools: bool,
58    /// Whether this looks like a follow-up question
59    pub is_followup: bool,
60    /// Extracted entities (file paths, URLs, etc.)
61    pub entities: Vec<ExtractedEntity>,
62    /// Confidence score (0.0-1.0)
63    pub confidence: f32,
64}
65
66/// An entity extracted from the request
67#[derive(Debug, Clone, Serialize, Deserialize)]
68pub struct ExtractedEntity {
69    /// Type of entity
70    pub entity_type: EntityType,
71    /// The extracted value
72    pub value: String,
73    /// Start position in the original text
74    pub start: usize,
75    /// End position in the original text
76    pub end: usize,
77}
78
79/// Types of entities that can be extracted
80#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
81#[serde(rename_all = "snake_case")]
82pub enum EntityType {
83    FilePath,
84    DirectoryPath,
85    Url,
86    GitBranch,
87    GitCommit,
88    Command,
89    Symbol,
90    Language,
91    ErrorMessage,
92}
93
94/// Context that has been resolved and cached
95#[derive(Debug, Clone, Default, Serialize, Deserialize)]
96pub struct ResolvedContext {
97    /// Categories included in this context
98    pub categories: HashSet<ContextCategory>,
99    /// Tool definitions (reduced if not needed)
100    pub tools: Vec<ToolContext>,
101    /// File contents if loaded
102    pub files: Vec<FileContext>,
103    /// Retrieved memory sections (short-term and long-term) relevant to the request.
104    #[serde(default)]
105    pub memory_sections: Vec<String>,
106    /// Session history (potentially summarized)
107    pub history_summary: Option<String>,
108    /// Knowledge items activated
109    pub knowledge: Vec<String>,
110    /// Total estimated tokens
111    pub estimated_tokens: usize,
112}
113
114/// Minimal tool context for when tools are needed
115#[derive(Debug, Clone, Serialize, Deserialize)]
116pub struct ToolContext {
117    /// Tool name
118    pub name: String,
119    /// Brief description
120    pub description: String,
121    /// Whether full schema is included
122    pub has_full_schema: bool,
123}
124
125impl RequestAnalysis {
126    /// Create a new empty analysis
127    pub fn new(request: impl Into<String>) -> Self {
128        Self {
129            request: request.into(),
130            categories: HashSet::new(),
131            suggested_tools: Vec::new(),
132            needs_tools: false,
133            is_followup: false,
134            entities: Vec::new(),
135            confidence: 0.0,
136        }
137    }
138
139    /// Add a detected category
140    pub fn with_category(mut self, category: ContextCategory) -> Self {
141        self.categories.insert(category);
142        self
143    }
144
145    /// Add a suggested tool
146    pub fn with_tool(mut self, tool: impl Into<String>) -> Self {
147        self.suggested_tools.push(tool.into());
148        self.needs_tools = true;
149        self
150    }
151
152    /// Add an extracted entity
153    pub fn with_entity(mut self, entity: ExtractedEntity) -> Self {
154        self.entities.push(entity);
155        self
156    }
157}
158
159/// File context loaded for the request
160#[derive(Debug, Clone, Serialize, Deserialize)]
161pub struct FileContext {
162    /// File path
163    pub path: String,
164    /// Content (potentially truncated)
165    pub content: String,
166    /// Whether content was truncated
167    pub truncated: bool,
168    /// Total lines in file
169    pub total_lines: usize,
170}