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}