Skip to main content

sh_layer3/
types.rs

1//! # Layer 3 Core Types
2//!
3//! Layer 3 使用的核心类型定义。
4
5use serde::{Deserialize, Serialize};
6use std::fmt;
7use std::path::PathBuf;
8
9// ============================================================================
10// Tool 相关类型
11// ============================================================================
12
13/// 工具 ID
14#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
15pub struct ToolId(pub String);
16
17impl ToolId {
18    pub fn new(name: &str) -> Self {
19        Self(name.to_string())
20    }
21}
22
23impl fmt::Display for ToolId {
24    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25        write!(f, "{}", self.0)
26    }
27}
28
29impl From<&str> for ToolId {
30    fn from(s: &str) -> Self {
31        Self::new(s)
32    }
33}
34
35/// 工具调用请求
36#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct ToolRequest {
38    /// 工具调用 ID(由 LLM 生成)
39    pub call_id: String,
40    /// 工具名称
41    pub name: String,
42    /// JSON 格式的参数
43    pub arguments: serde_json::Value,
44}
45
46/// 工具执行结果
47#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct ToolResponse {
49    /// 对应的调用 ID
50    pub call_id: String,
51    /// 工具名称
52    pub name: String,
53    /// 执行结果内容
54    pub content: String,
55    /// 是否为错误
56    pub is_error: bool,
57    /// 执行耗时(毫秒)
58    pub duration_ms: u64,
59}
60
61impl ToolResponse {
62    pub fn success(
63        call_id: impl Into<String>,
64        name: impl Into<String>,
65        content: impl Into<String>,
66    ) -> Self {
67        Self {
68            call_id: call_id.into(),
69            name: name.into(),
70            content: content.into(),
71            is_error: false,
72            duration_ms: 0,
73        }
74    }
75
76    pub fn error(
77        call_id: impl Into<String>,
78        name: impl Into<String>,
79        error: impl Into<String>,
80    ) -> Self {
81        Self {
82            call_id: call_id.into(),
83            name: name.into(),
84            content: error.into(),
85            is_error: true,
86            duration_ms: 0,
87        }
88    }
89}
90
91/// 工具元数据(用于注册和发现)
92#[derive(Debug, Clone, Serialize, Deserialize)]
93pub struct ToolMeta {
94    /// 工具名称(唯一标识)
95    pub name: String,
96    /// 工具描述(供 LLM 理解用途)
97    pub description: String,
98    /// 参数 JSON Schema
99    pub parameters: serde_json::Value,
100    /// 是否需要用户确认
101    #[serde(default)]
102    pub requires_confirmation: bool,
103    /// 是否为危险操作
104    #[serde(default)]
105    pub is_dangerous: bool,
106    /// 工具分类
107    pub category: ToolCategory,
108}
109
110/// 工具分类
111#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
112#[serde(rename_all = "snake_case")]
113pub enum ToolCategory {
114    /// 文件操作(读、写、编辑)
115    FileOps,
116    /// 搜索(grep、文件搜索)
117    Search,
118    /// Shell 命令执行
119    Shell,
120    /// 网络请求
121    Network,
122    /// 代码分析(LSP、AST)
123    CodeAnalysis,
124    /// 记忆操作
125    Memory,
126    /// 工作流控制
127    Workflow,
128    /// 系统/进程管理
129    System,
130    /// 数据处理(JSON/YAML/CSV等)
131    DataProcessing,
132    /// 文本处理(统计、转换等)
133    TextProcessing,
134    /// 版本控制(Git等)
135    VersionControl,
136    /// 其他
137    Other,
138}
139
140// ============================================================================
141// Memory 相关类型
142// ============================================================================
143
144/// 记忆层级
145#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
146#[serde(rename_all = "snake_case")]
147pub enum MemoryTier {
148    /// 工作记忆:当前对话上下文
149    #[default]
150    Working,
151    /// 会话记忆:单次会话内的持久化
152    Session,
153    /// 项目记忆:项目级别的知识库
154    Project,
155    /// 长期记忆:跨项目的通用知识
156    LongTerm,
157}
158
159/// 记忆条目
160#[derive(Debug, Clone, Serialize, Deserialize)]
161pub struct MemoryEntry {
162    /// 条目 ID
163    pub id: String,
164    /// 记忆层级
165    pub tier: MemoryTier,
166    /// 内容
167    pub content: String,
168    /// 元数据(可选的额外信息)
169    #[serde(default)]
170    pub metadata: serde_json::Map<String, serde_json::Value>,
171    /// 创建时间
172    pub created_at: chrono::DateTime<chrono::Utc>,
173    /// 最后访问时间
174    pub last_accessed: chrono::DateTime<chrono::Utc>,
175    /// 访问次数
176    #[serde(default)]
177    pub access_count: u32,
178    /// 重要性分数 (0.0-1.0)
179    #[serde(default)]
180    pub importance: f32,
181}
182
183/// 记忆查询
184#[derive(Debug, Clone, Default)]
185pub struct MemoryQuery {
186    /// 查询文本
187    pub query: String,
188    /// 限制层级(可选)
189    pub tier: Option<MemoryTier>,
190    /// 限制数量
191    pub limit: Option<usize>,
192    /// 时间范围(可选)
193    pub time_range: Option<(chrono::DateTime<chrono::Utc>, chrono::DateTime<chrono::Utc>)>,
194}
195
196// ============================================================================
197// Query Engine 相关类型
198// ============================================================================
199
200/// 代码查询类型
201#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
202#[serde(rename_all = "snake_case")]
203pub enum QueryType {
204    /// 符号定义
205    Definition,
206    /// 符号引用
207    References,
208    /// 符号实现
209    Implementations,
210    /// 类型定义
211    TypeDefinition,
212    /// 文档符号
213    DocumentSymbols,
214    /// 工作区符号
215    WorkspaceSymbols,
216    /// 悬停信息
217    Hover,
218}
219
220/// 代码位置
221#[derive(Debug, Clone, Serialize, Deserialize)]
222pub struct CodeLocation {
223    /// 文件路径
224    pub file: PathBuf,
225    /// 行号(1-based)
226    pub line: u32,
227    /// 列号(1-based)
228    pub column: u32,
229}
230
231impl fmt::Display for CodeLocation {
232    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233        write!(f, "{}:{}:{}", self.file.display(), self.line, self.column)
234    }
235}
236
237/// 代码范围
238#[derive(Debug, Clone, Serialize, Deserialize)]
239pub struct CodeRange {
240    pub start: CodeLocation,
241    pub end: CodeLocation,
242}
243
244/// 查询结果
245#[derive(Debug, Clone, Serialize, Deserialize)]
246pub struct QueryResult {
247    /// 查询类型
248    pub query_type: QueryType,
249    /// 结果位置
250    pub location: CodeLocation,
251    /// 结果范围(可选)
252    pub range: Option<CodeRange>,
253    /// 显示文本
254    pub display_text: String,
255    /// 所在文件内容片段(可选)
256    pub snippet: Option<String>,
257}
258
259// ============================================================================
260// Process 相关类型
261// ============================================================================
262
263/// 进程状态
264#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
265#[serde(rename_all = "snake_case")]
266pub enum ProcessState {
267    Running,
268    Stopped,
269    Exited,
270    Killed,
271}
272
273/// 进程信息
274#[derive(Debug, Clone, Serialize, Deserialize)]
275pub struct ProcessInfo {
276    /// 进程 ID
277    pub pid: u32,
278    /// 进程名称
279    pub name: String,
280    /// 状态
281    pub state: ProcessState,
282    /// 启动时间
283    pub started_at: chrono::DateTime<chrono::Utc>,
284    /// 命令行
285    pub command: String,
286    /// 工作目录
287    pub working_dir: PathBuf,
288}
289
290// ============================================================================
291// Error 类型
292// ============================================================================
293
294/// Layer 3 统一错误类型
295#[derive(Debug, thiserror::Error)]
296pub enum Layer3Error {
297    #[error("Tool not found: {0}")]
298    ToolNotFound(String),
299
300    #[error("Tool execution failed: {0}")]
301    ToolExecutionFailed(String),
302
303    #[error("Tool validation failed: {0}")]
304    ToolValidationFailed(String),
305
306    #[error("Memory not found: {0}")]
307    MemoryNotFound(String),
308
309    #[error("Memory query failed: {0}")]
310    MemoryQueryFailed(String),
311
312    #[error("Query failed: {0}")]
313    QueryFailed(String),
314
315    #[error("Process error: {0}")]
316    ProcessError(String),
317
318    #[error("LSP error: {0}")]
319    LspError(String),
320
321    #[error("Sandbox error: {0}")]
322    SandboxError(String),
323
324    #[error("IO error: {0}")]
325    Io(#[from] std::io::Error),
326
327    #[error("Serialization error: {0}")]
328    Serialization(#[from] serde_json::Error),
329
330    #[error("Lock error: {0}")]
331    LockError(String),
332
333    #[error("Vector store error: {0}")]
334    VectorStoreError(String),
335
336    #[error("Vector dimension mismatch: expected {expected}, got {actual}")]
337    VectorDimensionMismatch { expected: usize, actual: usize },
338
339    #[error("Vector not found: {0}")]
340    VectorNotFound(String),
341
342    #[error("Vector operation failed: {operation} - {reason}")]
343    VectorOperationFailed { operation: String, reason: String },
344
345    #[error("Persistence error: {0}")]
346    PersistenceError(String),
347
348    #[error("Invalid vector: {0}")]
349    InvalidVector(String),
350
351    #[error("Index error: {0}")]
352    IndexError(String),
353
354    #[error("Configuration error: {0}")]
355    ConfigError(String),
356}
357
358/// Layer 3 Result 类型
359pub type Layer3Result<T> = anyhow::Result<T>;
360
361#[cfg(test)]
362mod tests {
363    use super::*;
364
365    #[test]
366    fn test_tool_response_creation() {
367        let resp = ToolResponse::success("call_1", "test_tool", "result");
368        assert!(!resp.is_error);
369        assert_eq!(resp.name, "test_tool");
370
371        let err_resp = ToolResponse::error("call_2", "test_tool", "error");
372        assert!(err_resp.is_error);
373    }
374
375    #[test]
376    fn test_memory_tier_default() {
377        let tier = MemoryTier::default();
378        assert_eq!(tier, MemoryTier::Working);
379    }
380
381    #[test]
382    fn test_code_location_display() {
383        let loc = CodeLocation {
384            file: PathBuf::from("src/main.rs"),
385            line: 10,
386            column: 5,
387        };
388        assert!(loc.to_string().contains("main.rs"));
389    }
390}