# Gemini SDK 开发提示词

## 项目概述

基于 `apps\desktop\src-tauri\src\infrastructure\gemini_service.rs` 的现有实现，创建一个独立的 Rust crate `gemini-sdk`，提供简洁易用的 Gemini AI 服务接口。

## 核心设计目标

1. **简化接口**: 提供统一的消息发送接口，支持文本+附件输入
2. **Agent 系统**: 支持多个 AI Agent，每个 Agent 有独立的 system prompt 和配置
3. **多轮对话**: 支持会话管理和历史记录
4. **类型安全**: 强类型设计，编译时错误检查
5. **易于集成**: 最小化外部依赖，易于在其他项目中使用

## 技术架构

### 依赖管理
```toml
[dependencies]
tokio = { version = "1.0", features = ["full"] }
reqwest = { version = "0.11", features = ["json", "multipart"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
anyhow = "1.0"
uuid = { version = "1.0", features = ["v4"] }
chrono = { version = "0.4", features = ["serde"] }
base64 = "0.22"
rusqlite = { version = "0.31", features = ["bundled", "chrono"] }
```

### 核心数据结构

```rust
// SDK 主体
pub struct GeminiSDK {
    service: GeminiService,
    conversation_repo: Option<Arc<ConversationRepository>>,
    agents: HashMap<String, Agent>,
}

// Agent 定义
pub struct Agent {
    pub id: String,
    pub name: String,
    pub system_prompt: String,
    pub config: AgentConfig,
    pub created_at: DateTime<Utc>,
}

pub struct AgentConfig {
    pub temperature: f32,
    pub max_tokens: u32,
    pub timeout: u64,
    pub enable_conversation: bool,
}

// 消息结构
pub struct MessageRequest {
    pub text: String,
    pub attachments: Vec<Attachment>,
    pub agent_id: Option<String>,
    pub session_id: Option<String>,
    pub config: Option<MessageConfig>,
}

pub struct MessageResponse {
    pub content: String,
    pub session_id: String,
    pub message_id: Option<String>,
    pub agent_id: Option<String>,
}

// 附件定义
pub struct Attachment {
    pub path: String,
    pub mime_type: Option<String>,
}

// 会话管理
pub struct ConversationSession {
    pub session_id: String,
    pub title: Option<String>,
    pub created_at: DateTime<Utc>,
}

pub struct HistoryMessage {
    pub role: MessageRole,
    pub content: String,
    pub timestamp: DateTime<Utc>,
    pub attachments: Vec<String>,
}
```

## 核心功能接口

### 1. SDK 初始化
```rust
impl GeminiSDK {
    // 基础初始化
    pub fn new() -> Result<Self>;
    
    // 支持多轮对话
    pub fn with_conversation_support(db_path: Option<String>) -> Result<Self>;
    
    // 自定义配置
    pub fn with_config(config: GeminiConfig) -> Result<Self>;
}
```

### 2. 核心消息接口
```rust
impl GeminiSDK {
    // 主要方法：发送消息+附件，获得回复
    pub async fn send_message(&mut self, request: MessageRequest) -> Result<MessageResponse>;
}
```

### 3. Agent 管理
```rust
impl GeminiSDK {
    // Agent CRUD
    pub fn create_agent(&mut self, name: String, system_prompt: String, config: Option<AgentConfig>) -> Result<Agent>;
    pub fn get_agent(&self, agent_id: &str) -> Option<&Agent>;
    pub fn list_agents(&self) -> Vec<&Agent>;
    pub fn update_agent(&mut self, agent_id: &str, name: Option<String>, system_prompt: Option<String>, config: Option<AgentConfig>) -> Result<()>;
    pub fn delete_agent(&mut self, agent_id: &str) -> Result<()>;
    
    // 预设 Agent
    pub fn create_outfit_advisor_agent(&mut self) -> Result<Agent>;
    pub fn create_video_analyst_agent(&mut self) -> Result<Agent>;
    pub fn create_general_assistant_agent(&mut self) -> Result<Agent>;
}
```

### 4. 会话管理
```rust
impl GeminiSDK {
    // 会话 CRUD
    pub async fn create_session(&self, title: Option<String>) -> Result<ConversationSession>;
    pub async fn get_session(&self, session_id: &str) -> Result<Option<ConversationSession>>;
    pub async fn list_sessions(&self) -> Result<Vec<ConversationSession>>;
    pub async fn delete_session(&self, session_id: &str) -> Result<()>;
    
    // 历史记录
    pub async fn get_conversation_history(&self, session_id: &str, limit: Option<u32>) -> Result<Vec<HistoryMessage>>;
    pub async fn clear_conversation_history(&self, session_id: &str) -> Result<()>;
}
```

### 5. 便捷构造函数
```rust
impl Attachment {
    pub fn new(path: impl Into<String>) -> Self;
    pub fn with_mime_type(path: impl Into<String>, mime_type: impl Into<String>) -> Self;
}

impl MessageRequest {
    pub fn text_only(text: impl Into<String>) -> Self;
    pub fn with_attachments(text: impl Into<String>, attachments: Vec<Attachment>) -> Self;
    pub fn with_agent(text: impl Into<String>, agent_id: impl Into<String>) -> Self;
}
```

## 实现要求

### 1. 文件结构
```
cargos/gemini-sdk/
├── Cargo.toml
├── src/
│   ├── lib.rs              # 主入口
│   ├── sdk.rs              # SDK 主体实现
│   ├── agent.rs            # Agent 相关
│   ├── conversation.rs     # 会话管理
│   ├── attachment.rs       # 附件处理
│   ├── error.rs            # 错误定义
│   └── presets/            # 预设 Agent
│       ├── mod.rs
│       ├── outfit_advisor.rs
│       ├── video_analyst.rs
│       └── general_assistant.rs
├── examples/
│   ├── basic_usage.rs
│   ├── agent_demo.rs
│   └── conversation_demo.rs
└── tests/
    ├── integration_tests.rs
    └── agent_tests.rs
```

### 2. 核心实现逻辑

#### 消息发送流程
1. 检查是否指定 Agent，获取对应配置和 system prompt
2. 处理附件：根据文件类型选择上传(视频)或编码(图片)
3. 构建 Gemini API 请求，包含 system prompt
4. 如果启用会话，使用多轮对话模式；否则使用单轮模式
5. 调用底层 GeminiService 方法
6. 返回格式化的响应

#### Agent 系统
1. 内存中维护 Agent 映射表
2. 每个 Agent 包含独立的 system prompt 和配置
3. 提供预设的专业 Agent（穿搭顾问、视频分析师等）
4. 支持动态创建和管理自定义 Agent

#### 会话管理
1. 可选的 SQLite 数据库支持
2. 自动会话创建和历史记录保存
3. 支持会话标题和元数据管理
4. 历史消息检索和清理

### 3. 错误处理
```rust
#[derive(Debug, thiserror::Error)]
pub enum SDKError {
    #[error("配置错误: {0}")]
    Config(String),
    
    #[error("Agent 不存在: {0}")]
    AgentNotFound(String),
    
    #[error("会话错误: {0}")]
    Session(String),
    
    #[error("附件处理错误: {0}")]
    Attachment(String),
    
    #[error("网络错误: {0}")]
    Network(#[from] reqwest::Error),
    
    #[error("数据库错误: {0}")]
    Database(#[from] rusqlite::Error),
    
    #[error("Gemini 服务错误: {0}")]
    GeminiService(#[from] anyhow::Error),
}
```

### 4. 使用示例
```rust
// 基础使用
let mut sdk = GeminiSDK::with_conversation_support(None)?;

// 创建穿搭顾问 Agent
let agent = sdk.create_outfit_advisor_agent()?;

// 发送消息
let request = MessageRequest {
    text: "分析这张穿搭图片".to_string(),
    attachments: vec![Attachment::new("./outfit.jpg")],
    agent_id: Some(agent.id),
    session_id: None,
    config: None,
};

let response = sdk.send_message(request).await?;
println!("回复: {}", response.content);
```

## 开发指导

### 1. 代码复用策略
- 直接复用 `gemini_service.rs` 中的核心逻辑
- 提取通用的配置、错误处理和网络请求代码
- 简化接口，隐藏内部复杂性

### 2. 测试策略
- 单元测试：各个组件的独立功能
- 集成测试：完整的消息发送流程
- 示例代码：展示各种使用场景

### 3. 文档要求
- 完整的 API 文档
- 使用示例和最佳实践
- 错误处理指南
- 性能优化建议

### 4. 性能考虑
- 连接池复用
- 合理的超时设置
- 内存使用优化
- 异步操作支持

## 交付标准

1. **功能完整性**: 所有设计的接口都能正常工作
2. **代码质量**: 遵循 Rust 最佳实践，通过 clippy 检查
3. **测试覆盖**: 核心功能有完整的测试覆盖
4. **文档完善**: 清晰的 API 文档和使用示例
5. **易用性**: 简洁的接口，最小化学习成本

## 详细实现指南

### 1. 从现有代码迁移的关键组件

#### 需要复用的核心结构
```rust
// 从 gemini_service.rs 复用
pub struct GeminiConfig { /* 保持原有字段 */ }
pub struct GenerateContentRequest { /* 保持原有结构 */ }
pub struct ContentPart { /* 保持原有结构 */ }
pub enum Part { /* 保持原有枚举 */ }
pub struct GenerationConfig { /* 保持原有结构 */ }
```

#### 需要复用的核心方法
- `get_access_token()` - 访问令牌管理
- `upload_video_file()` - 视频文件上传
- `generate_content_with_request()` - 内容生成
- `query_llm_with_grounding_multi_turn()` - 多轮对话
- `extract_json_from_response()` - JSON 解析

### 2. 简化的内部服务层

```rust
// 简化的内部服务，封装复杂逻辑
struct InternalGeminiService {
    config: GeminiConfig,
    client: reqwest::Client,
    access_token: Option<String>,
    token_expires_at: Option<u64>,
}

impl InternalGeminiService {
    // 复用原有的核心方法，但简化接口
    async fn send_request(&mut self, parts: Vec<Part>, config: GenerationConfig, system_prompt: Option<String>) -> Result<String>;
    async fn upload_file(&mut self, path: &str) -> Result<String>;
    async fn send_multipart_request(&mut self, parts: Vec<Part>, config: GenerationConfig, system_prompt: Option<String>, session_id: Option<String>) -> Result<String>;
}
```

### 4. 错误恢复和重试机制

```rust
impl GeminiSDK {
    async fn send_message_with_retry(&mut self, request: MessageRequest, max_retries: u32) -> Result<MessageResponse> {
        let mut last_error = None;

        for attempt in 0..max_retries {
            match self.send_message_internal(request.clone()).await {
                Ok(response) => return Ok(response),
                Err(e) => {
                    last_error = Some(e);
                    if attempt < max_retries - 1 {
                        let delay = std::time::Duration::from_secs(2_u64.pow(attempt));
                        tokio::time::sleep(delay).await;
                    }
                }
            }
        }

        Err(last_error.unwrap())
    }
}
```

### 5. 配置管理

```rust
impl GeminiSDK {
    pub fn from_env() -> Result<Self> {
        let config = GeminiConfig {
            base_url: std::env::var("GEMINI_BASE_URL").unwrap_or_else(|_| "https://bowongai-dev--bowong-ai-video-gemini-fastapi-webapp.modal.run".to_string()),
            bearer_token: std::env::var("GEMINI_BEARER_TOKEN").unwrap_or_else(|_| "bowong7777".to_string()),
            // ... 其他配置
        };

        Self::with_config(config)
    }
}
```

### 6. 完整的使用示例

```rust
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 初始化 SDK
    let mut sdk = GeminiSDK::with_conversation_support(None)?;


    // 3. 穿搭分析示例
    let outfit_request = MessageRequest {
        text: "请分析这张穿搭图片，给出专业的搭配建议".to_string(),
        attachments: vec![Attachment::new("./examples/outfit.jpg")],
        agent_id: Some(outfit_agent.id.clone()),
        session_id: None,
        config: None,
    };

    let outfit_response = sdk.send_message(outfit_request).await?;
    println!("穿搭顾问分析：\n{}", outfit_response.content);

    // 4. 视频分析示例
    let video_request = MessageRequest {
        text: "请分析这个视频的内容质量和改进建议".to_string(),
        attachments: vec![Attachment::new("./examples/video.mp4")],
        agent_id: Some(video_agent.id),
        session_id: None,
        config: Some(MessageConfig {
            temperature: Some(0.6),
            max_tokens: Some(12000),
            timeout: Some(180),
        }),
    };

    let video_response = sdk.send_message(video_request).await?;
    println!("视频分析报告：\n{}", video_response.content);

    // 5. 多轮对话示例
    let session = sdk.create_session(Some("穿搭咨询".to_string())).await?;

    let follow_up = MessageRequest {
        text: "基于刚才的分析，我想要更正式一些的搭配方案".to_string(),
        attachments: vec![],
        agent_id: Some(outfit_agent.id),
        session_id: Some(session.session_id.clone()),
        config: None,
    };

    let follow_response = sdk.send_message(follow_up).await?;
    println!("后续建议：\n{}", follow_response.content);

    // 6. 查看对话历史
    let history = sdk.get_conversation_history(&session.session_id, Some(10)).await?;
    for msg in history {
        println!("{}: {}", msg.role, msg.content);
    }

    Ok(())
}
```

## 质量保证要求

### 1. 代码规范
- 使用 `cargo fmt` 格式化代码
- 通过 `cargo clippy` 静态检查
- 添加适当的文档注释
- 遵循 Rust 命名约定

### 2. 测试要求
```rust
#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_basic_message_sending() {
        // 测试基础消息发送功能
    }

    #[tokio::test]
    async fn test_agent_management() {
        // 测试 Agent 创建和管理
    }

    #[tokio::test]
    async fn test_conversation_flow() {
        // 测试多轮对话流程
    }

    #[tokio::test]
    async fn test_attachment_processing() {
        // 测试附件处理
    }
}
```

### 3. 文档要求
- 每个公共接口都要有详细的文档注释
- 提供完整的使用示例
- 包含错误处理指南
- 性能和最佳实践说明

请基于这个详细的设计方案和实现指南，创建一个高质量、易用、功能完整的 Gemini SDK crate。
