# Changelog

All notable changes to this project will be documented in this file.

## [0.5.4] - 2025-01-22

### 🔧 Bug Fixes

#### Streaming Tool Calls Fix
- **Fixed**: Incremental accumulation and deduplication logic for streaming tool_calls
  - Modified `ToolCall` and `FunctionCall` data structures to support incremental parsing
  - Implemented `merge_delta()` method for merging incremental data
  - Added accumulation state management in `sse_to_streaming_response`
  - Only send complete tool_calls to prevent duplicate execution
- **Improved**: Support for OpenAI streaming API's incremental tool_calls format
  - Added `index` field to identify tool_calls
  - Implemented `is_complete()` method to check completeness
  - Accumulate each tool_call's incremental data by `index`
- **Guaranteed**: Each tool_call is sent only once, preventing duplicate execution
- **Compatible**: Fully backward compatible, no impact on existing code
- **Tests**: Added comprehensive test suite to verify accumulation logic
  - `test_streaming_tool_calls_accumulation` - Verify accumulation logic
  - `test_streaming_tool_calls_parsing` - Verify incremental parsing
- **Documentation**:
  - Added `docs/STREAMING_TOOL_CALLS.md` - Technical documentation
  - Added `docs/STREAMING_TOOL_CALLS_FIX.md` - Fix summary
  - Updated `README.md` with Function Calling section

### 📚 Documentation

#### Documentation Cleanup
- **Cleanup**: Moved outdated temporary documents to archive
  - `DOCS_CLEANUP_SUMMARY.md` → `docs/archive/reports/`
  - `RELEASE_v0.5.3_SUMMARY.md` → `docs/archive/releases/`
  - `SENSITIVE_INFO_OBFUSCATION.md` → `docs/archive/reports/`
- **Updated**: `docs/README.md` with new documentation index
- **Simplified**: README.md changelog section, pointing to CHANGELOG.md
- **Removed**: Outdated references to non-existent examples (`test_keys_yaml`, `debug_deepseek`, `fetch_models_simple`)
- **Updated**: Examples section to reflect actual available examples
- **Improved**: Troubleshooting section with practical solutions
- **Reorganized**: README.md structure for better user experience
  - Moved "Supported Providers" overview right after Quick Start
  - Moved "Function Calling / Tools" and "Streaming" sections earlier
  - Moved architecture details ("Unified Output Format") to later sections
  - Removed duplicate sections
  - New flow: Introduction → Features → Quick Start → Providers → Key Features → Architecture → Advanced Topics

#### Language Standardization
- **Converted**: All Chinese text to English for international accessibility
  - README.md Function Calling section
  - CHANGELOG.md v0.5.4 section
  - Test files and example files
  - All comments and user-facing messages
  - Removed Chinese characters from provider names (Tencent Hunyuan, Volcengine, Moonshot)
  - `docs/README.md` - Converted entire documentation index to English
  - `docs/REASONING_MODELS_SUPPORT.md` - Completely rewritten in English
- **Simplified**: Removed excessive emoji usage from README.md
  - Kept minimal, professional formatting
  - Replaced emoji bullets with standard markdown bullets
  - Removed decorative emojis from section headers
- **Archived**: Moved original Chinese version of REASONING_MODELS_SUPPORT.md to `docs/archive/reports/`
- **Documentation**:
  - Added `docs/CHINESE_TO_ENGLISH_CONVERSION.md` for conversion summary
  - Added `docs/EMOJI_AND_CHINESE_CLEANUP.md` for cleanup summary

## [0.5.3] - 2025-01-15

### 🎉 New Features

#### Universal Reasoning Models Support 🧠
- **Added**: Universal support for reasoning models across all providers
- **Supported Models**:
  - ✅ Volcengine Doubao-Seed-Code (`reasoning_content`)
  - ✅ DeepSeek R1 (`reasoning_content` / `reasoning`)
  - ✅ OpenAI o1 series (`thought` / `reasoning_content`)
  - ✅ Qwen reasoning models (`reasoning`)
  - ✅ Anthropic Claude extended thinking (`thinking`)
- **Key Benefits**:
  - Zero configuration - automatic field detection
  - Unified interface - same code for all reasoning models
  - Backward compatible - standard models work as before
  - Priority-based extraction - standard `content` field takes precedence
- **Documentation**: Added `docs/REASONING_MODELS_SUPPORT.md`

### 📚 Documentation

#### Documentation Structure Cleanup
- **Reorganized**: Cleaned up docs directory from 52 to 30 files (-42%)
- **New Structure**:
  - Core documents (6): Architecture, migration guides, reasoning models support
  - Provider guides (7): Dedicated guide for each provider in `docs/guides/`
  - Archive (17): Historical releases and reports in `docs/archive/`
- **New Provider Guides**:
  - `docs/guides/ALIYUN_GUIDE.md` - Aliyun DashScope usage guide
  - `docs/guides/ANTHROPIC_GUIDE.md` - Anthropic Claude usage guide
  - `docs/guides/ZHIPU_GUIDE.md` - Zhipu GLM usage guide
  - Updated existing guides for DeepSeek, Moonshot, Tencent, Volcengine
- **Improvements**:
  - Clear documentation index in `docs/README.md`
  - Removed duplicate and outdated content
  - Better organization and discoverability

#### Security
- **Obfuscated**: All sensitive information in documentation and examples
  - API keys replaced with placeholders
  - Endpoint IDs replaced with example values
  - Created `keys.yaml.example` for configuration reference
- **Documentation**: Added `docs/SENSITIVE_INFO_OBFUSCATION.md`

### 🐛 Bug Fixes

#### Volcengine Streaming Support
- **Fixed**: Volcengine streaming now correctly extracts content from reasoning models (Doubao-Seed-Code)
- **Issue**: `StreamingResponse.get_content()` returned `None` for Doubao-Seed-Code model responses
- **Root Cause**: Reasoning models output content in `delta.reasoning_content` field instead of `delta.content`
- **Solution**: Enhanced SSE parser to check multiple content fields in priority order:
  1. `delta.content` (standard OpenAI format, non-empty)
  2. `delta.reasoning_content` (Volcengine Doubao-Seed-Code, DeepSeek R1)
  3. `delta.reasoning` (Qwen, DeepSeek)
  4. `delta.thought` (OpenAI o1)
  5. `delta.thinking` (Anthropic)
- **Impact**: Benefits all reasoning models across different providers
- **Files Changed**: `src/sse.rs`
- **Tests Added**:
  - Unit test: `test_streaming_response_content_population`
  - Integration test: `examples/volcengine_streaming.rs`
  - Automation script: `scripts/test_volcengine_streaming.sh`
- **Documentation**:
  - `docs/VOLCENGINE_STREAMING_FIX.md` - Detailed fix documentation
  - `docs/VOLCENGINE_STREAMING_SUMMARY.md` - Fix summary
  - `docs/VOLCENGINE_STREAMING_FINAL_REPORT.md` - Final report
  - `docs/REASONING_MODELS_SUPPORT.md` - Universal reasoning models guide
- **Test Results**:
  - ✅ 221 tests passed
  - ✅ Volcengine streaming: 101 chunks, 477 chars extracted
  - ✅ All existing functionality preserved

## [0.5.1] - 2025-01-21

### 🔧 Improvements

#### Code Quality
- Fixed all compilation errors and warnings discovered by rust-analyzer
- Fixed unused variable warnings by using underscore prefix
- Cleaned up 69% of example files (39 → 12)
- Cleaned up 56% of test files (18 → 8)
- Removed 36 duplicate, debug, and outdated files

#### Documentation
- Added `docs/RUST_CODING_RULES.md` - Rust coding standards
- Added `docs/MIGRATION_GUIDE_v0.5.0.md` - Complete migration guide
- Added `docs/RELEASE_v0.5.0.md` - Release notes
- Updated `examples/README.md` with cleaner structure
- Updated all examples to use new API

#### Examples Cleanup
- Removed duplicate examples (test_aliyun_basic.rs, test_deepseek.rs, etc.)
- Removed debug files (debug_aliyun_response.rs, debug_longcat_stream.rs, etc.)
- Removed verification files (verify_aliyun_choices.rs, verify_reasoning_content.rs, etc.)
- Removed shell test scripts (9 files)
- Renamed test_aliyun_enable_thinking.rs → aliyun_thinking.rs

#### Bug Fixes
- Fixed Message construction in all examples
- Fixed content access using content_as_text()
- Fixed streaming examples with proper feature gates
- Fixed tencent_basic.rs API usage
- Fixed all integration tests

### 📊 Statistics

- **Tests**: 221 passed; 0 failed (100% pass rate)
- **Compilation**: 0 errors, 0 warnings
- **Code reduction**: 74% fewer lines in examples/tests

## [0.5.0] - 2025-01-21

### 🎉 Major Features - Multi-modal Content Support

**⚠️ BREAKING CHANGE**: `Message.content` changed from `String` to `Vec<MessageBlock>`

This is a major architectural improvement that enables native multi-modal content support (text + images).

#### New Types

- **`MessageBlock`** - Enum for different content types
  - `Text { text: String }` - Text content
  - `Image { source: ImageSource }` - Image (Anthropic format)
  - `ImageUrl { image_url: ImageUrl }` - Image URL (OpenAI format)
- **`ImageSource`** - Image source (Base64 or URL)
- **`ImageUrl`** - Image URL with optional detail level

#### Migration Guide

```rust
// Old (0.4.x)
let message = Message {
    role: Role::User,
    content: "Hello".to_string(),
    ..Default::default()
};

// New (0.5.0) - Option 1: Use text() constructor (recommended)
let message = Message::text(Role::User, "Hello");

// New (0.5.0) - Option 2: Use new() with MessageBlock
let message = Message::new(
    Role::User,
    vec![MessageBlock::text("Hello")],
);

// New (0.5.0) - Multi-modal example
let message = Message::new(
    Role::User,
    vec![
        MessageBlock::text("What's in this image?"),
        MessageBlock::image_url("https://example.com/image.jpg"),
    ],
);
```

#### New Methods

**Message**:
- `Message::text(role, text)` - Create text-only message
- `Message::new(role, blocks)` - Create multi-modal message
- `Message::content_as_text()` - Extract all text content
- `Message::is_text_only()` - Check if message contains only text
- `Message::has_images()` - Check if message contains images

**MessageBlock**:
- `MessageBlock::text(text)` - Create text block
- `MessageBlock::image_base64(media_type, data)` - Create Base64 image
- `MessageBlock::image_url(url)` - Create image URL block
- `MessageBlock::image_url_with_detail(url, detail)` - Create image URL with detail
- `MessageBlock::as_text()` - Get text content if it's a text block
- `MessageBlock::is_text()` - Check if it's a text block
- `MessageBlock::is_image()` - Check if it's an image block

#### Updated Protocols

- ✅ **OpenAI** - Supports both string and array formats
- ✅ **Anthropic** - Always uses array format
- ✅ **Aliyun** - Converts to text format
- ✅ **Zhipu** - Converts to text format
- ✅ **Ollama** - Converts to text format

#### Examples

- `examples/multimodal_basic.rs` - Comprehensive multi-modal examples

#### Tests

- Added 8 new unit tests for `MessageBlock`
- All 64 tests passing

#### Documentation

- `docs/MULTIMODAL_CONTENT_DESIGN.md` - Design comparison
- `docs/MULTIMODAL_NATIVE_DESIGN.md` - Native design approach
- `docs/MULTIMODAL_MIGRATION_PLAN.md` - Migration plan

---

## [Unreleased]

### Added
- **Moonshot (月之暗面) Provider**
  - OpenAI-compatible API
  - `LlmClient::moonshot(api_key)`
  - Models: moonshot-v1-8k, moonshot-v1-32k, moonshot-v1-128k
  - Long context support (up to 128k tokens)
  - Full streaming support

- **DeepSeek Provider**
  - OpenAI-compatible API
  - `LlmClient::deepseek(api_key)`
  - Models: deepseek-chat, deepseek-reasoner
  - Reasoning model support with thinking process
  - Automatic extraction of reasoning content
  - Full streaming support for both chat and reasoning models

## [0.4.20] - 2025-10-21

### 🎯 Major Update: Unified Output Format & Configuration-Driven Architecture

#### ✨ Unified Output Format

**All providers now output the same unified `StreamingResponse` format**, regardless of their native API format.

```
Different Input Formats → Protocol Conversion → Unified StreamingResponse
```

**Benefits**:
- ✅ Consistent API across all providers
- ✅ Easy provider switching without changing business logic
- ✅ Type-safe compile-time guarantees
- ✅ Lower learning curve - learn once, use everywhere

**Example**:
```rust
// Same code works with ANY provider
let mut stream = client.chat_stream(&request).await?;
while let Some(chunk) = stream.next().await {
    let chunk = chunk?;  // Always StreamingResponse
    if let Some(content) = chunk.get_content() {
        print!("{}", content);
    }
}
```

#### 🏗️ Configuration-Driven Architecture

**New Core Modules**:

1. **ProviderBuilder** (`src/core/builder.rs`)
   - Unified builder pattern for all providers
   - Chain-able API: `.timeout()` / `.proxy()` / `.header()`
   - Eliminates repetitive `xxx_with_config` boilerplate
   - Reduces code by ~50%

2. **ConfigurableProtocol** (`src/core/configurable.rs`)
   - Configuration-driven protocol adapter
   - `ProtocolConfig` - Static configuration (name, endpoints, auth)
   - `EndpointConfig` - Endpoint templates with `{base_url}` variable
   - `AuthConfig` - Flexible authentication (Bearer/ApiKeyHeader/None/Custom)
   - New providers only need configuration, not code

**Code Reduction**:
- Tencent: 169 lines → 122 lines (-28%)
- Volcengine: 169 lines → 145 lines (-14%)
- LongCat: 169 lines → 145 lines (-14%)
- **Average: -19% code reduction**

#### 🆕 New Providers

1. **Tencent Hunyuan (腾讯混元)**
   - OpenAI-compatible API
   - `LlmClient::tencent(api_key)`
   - Models: hunyuan-lite, hunyuan-standard, hunyuan-pro, hunyuan-turbo

2. **LongCat API**
   - Dual format support
   - `LlmClient::longcat_openai(api_key)` - OpenAI format
   - `LlmClient::longcat_anthropic(api_key)` - Anthropic format with Bearer auth

#### 🔧 Anthropic Streaming Fix

**Problem**: LongCat Anthropic streaming failed with "missing field `id`" error

**Solution**: Implemented custom `parse_stream_response` for Anthropic protocol
- Correctly handles Anthropic's multi-event streaming format:
  - `message_start` - Extract message ID
  - `content_block_delta` - Extract text increments
  - `message_delta` - Extract usage and stop_reason
- Converts to unified `StreamingResponse` format
- **Now works perfectly with LongCat Anthropic!**

**Test Results**:
```
✅ LongCat Anthropic non-streaming: Working
✅ LongCat Anthropic streaming: Working (fixed!)
   - Total chunks: 20
   - Content chunks: 19
   - finish_reason: end_turn
   - usage: prompt_tokens: 15, completion_tokens: 30
```

#### 🧹 Code Cleanup

- Removed deprecated v1 architecture code (5641 lines)
- Removed `v1-legacy` feature flag
- Cleaner codebase with focused abstractions

#### 📚 Documentation

**New Documents**:
- `docs/REFACTORING_SUMMARY.md` - Complete refactoring documentation
- `docs/POST_REFACTORING_TEST_REPORT.md` - Comprehensive test report (90% pass rate)
- `docs/ANTHROPIC_STREAMING_FIX.md` - Anthropic streaming fix details

**Updated**:
- README.md - Added unified output format explanation
- README.md - Added new providers (Tencent, LongCat)

#### ✅ Testing

**Comprehensive Testing**:
- ✅ All providers tested: 10/10 tests passed
- ✅ Non-streaming: 100% pass rate (5/5)
- ✅ Streaming: 100% pass rate (5/5)
- ✅ 46 unit tests passing
- ✅ Full backward compatibility verified

**Tested Providers**:
- Tencent (refactored) - ✅ Non-streaming + Streaming
- LongCat OpenAI (unchanged) - ✅ Non-streaming + Streaming
- LongCat Anthropic (refactored) - ✅ Non-streaming + Streaming (fixed!)
- Zhipu (unchanged) - ✅ Non-streaming + Streaming
- Aliyun (unchanged) - ✅ Non-streaming + Streaming

#### 📈 Performance & Metrics

- Code reduction: -19% in refactored providers
- New provider cost: -70% (170 lines → 50 lines)
- Maintenance cost: -50% (centralized logic)
- Test pass rate: 100% (10/10)

#### 🔄 Migration Guide

**No breaking changes!** All existing APIs continue to work.

**Before (still works)**:
```rust
let client = LlmClient::openai_compatible(
    "sk-...",
    "https://api.hunyuan.cloud.tencent.com",
    "tencent"
)?;
```

**After (recommended)**:
```rust
let client = LlmClient::tencent("sk-...")?;
```

---

## [0.4.19] - 2025-10-18

### ✨ New Features

#### **添加火山引擎（Volcengine）专用 Provider**

**火山引擎简介**:
- 火山引擎是字节跳动旗下的云服务平台
- 提供大模型服务（火山方舟）
- 使用 OpenAI 兼容的 API 格式，但端点路径不同

**新增功能**:

1. **创建 VolcengineProtocol 适配器**
   - 包装 OpenAI protocol，但使用火山引擎的端点路径
   - 端点: `/api/v3/chat/completions` (而不是 `/v1/chat/completions`)
   - 完全兼容 OpenAI 请求/响应格式

2. **添加专用 API 方法**
   - `LlmClient::volcengine()` - 创建火山引擎客户端
   - `LlmClient::volcengine_with_config()` - 带自定义配置的客户端

3. **支持推理模型特性**
   - 支持 `reasoning_content` 字段（思考过程）
   - 流式响应中先返回思考过程，再返回实际回答
   - 类似 OpenAI o1 的推理模型

**使用示例**:

```rust
// 创建客户端
let client = LlmClient::volcengine("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")?;

// 创建请求（使用端点 ID）
let request = ChatRequest {
    model: "ep-20250118155555-xxxxx".to_string(),  // 端点 ID
    messages: vec![Message {
        role: Role::User,
        content: "你好".to_string(),
        ..Default::default()
    }],
    max_tokens: Some(1000),
    ..Default::default()
};

// 非流式
let response = client.chat(&request).await?;

// 流式
#[cfg(feature = "streaming")]
{
    let mut stream = client.chat_stream(&request).await?;
    while let Some(chunk) = stream.next().await {
        // 处理流式响应
    }
}
```

**测试结果**:

| 功能 | 状态 | 详情 |
|------|------|------|
| 非流式响应 | ✅ | 完全可用 |
| 流式响应 | ✅ | 完全可用 |
| reasoning_content | ✅ | 支持推理过程 |
| llm-connector 兼容性 | ✅ | 完全兼容 |

**新增文件**:
- `src/providers/volcengine.rs` - 火山引擎专用 Provider
- `examples/test_volcengine.rs` - 测试示例
- `tests/test_volcengine_raw.sh` - 原始 API 测试
- `tests/test_volcengine_streaming_raw.sh` - 流式响应测试
- `docs/VOLCENGINE_GUIDE.md` - 完整使用指南

**重要说明**:
- 火山引擎使用端点 ID（`ep-xxxxxx`）而不是模型名称
- 端点 ID 需要在火山引擎控制台创建和获取
- API Key 格式为 UUID 而不是 `sk-` 格式

---

## [0.4.18] - 2025-10-18

### ✨ New Features

#### **添加 LongCat API 支持**

**LongCat 简介**:
- LongCat 是一个 AI 服务平台，提供高性能的对话模型
- 支持 OpenAI 和 Anthropic 两种 API 格式
- 每日免费额度: 500,000 Tokens

**新增功能**:

1. **LongCat OpenAI 格式支持** - ✅ 完全可用
   - 使用 `LlmClient::openai_compatible()` 方法
   - 端点: `https://api.longcat.chat/openai`
   - 支持非流式和流式响应
   - 完全兼容 llm-connector

2. **LongCat Anthropic 格式支持** - ✅ 非流式可用
   - 创建 `LongCatAnthropicProtocol` 适配器
   - 使用 `Authorization: Bearer` 认证（而不是标准 Anthropic 的 `x-api-key`）
   - 添加 `LlmClient::longcat_anthropic()` 方法
   - 添加 `LlmClient::longcat_anthropic_with_config()` 方法
   - 支持非流式响应
   - ⚠️ 流式响应暂不支持（Anthropic 事件格式需要专门解析器）

**使用示例**:

```rust
// 方式 1: OpenAI 格式（推荐，流式和非流式都可用）
let client = LlmClient::openai_compatible(
    "ak_...",
    "https://api.longcat.chat/openai",
    "longcat"
)?;

// 方式 2: Anthropic 格式（仅非流式）
let client = LlmClient::longcat_anthropic("ak_...")?;
```

**测试结果**:

| 测试项 | OpenAI 格式 | Anthropic 格式 |
|--------|------------|---------------|
| 非流式响应 | ✅ 成功 | ✅ 成功 |
| 流式响应 | ✅ 成功 | ⚠️ 暂不支持 |
| llm-connector 兼容性 | ✅ 完全兼容 | ✅ 非流式兼容 |

**新增文件**:
- `src/providers/longcat.rs` - LongCat Anthropic 适配器
- `examples/test_longcat_openai.rs` - OpenAI 格式测试
- `examples/test_longcat_anthropic.rs` - Anthropic 格式测试
- `tests/test_longcat_anthropic_raw.sh` - Anthropic 原始 API 测试
- `tests/test_longcat_anthropic_streaming_raw.sh` - 流式响应格式测试
- `docs/LONGCAT_TESTING_REPORT.md` - 完整测试报告

**推荐使用方式**:
- 流式: `LlmClient::openai_compatible("ak_...", "https://api.longcat.chat/openai", "longcat")`
- 非流式: `LlmClient::longcat_anthropic("ak_...")` 或 OpenAI 格式

### 🐛 Bug Fixes

#### **修复 AliyunProviderImpl 缺失方法**

**问题**: 测试代码调用 `provider.protocol()` 和 `provider.client()` 方法，但这些方法不存在

**修复**:
- 添加 `protocol()` 方法返回协议实例引用
- 添加 `client()` 方法返回 HTTP 客户端引用
- 修复 `models()` 错误信息以匹配测试期望
- 修复 `as_ollama()` doctest 中不存在的方法调用

### 📝 Documentation

- 添加 `docs/LONGCAT_TESTING_REPORT.md` - LongCat API 完整测试报告
- 更新 `src/client.rs` - 添加 LongCat 使用示例

---

## [0.4.17] - 2025-10-18

### 🐛 Bug Fixes

#### **修复 Aliyun 响应解析和流式响应问题**

**问题 1: ChatResponse 结构不一致**

**问题描述**:
- ❌ Aliyun 的 `choices` 数组为空
- ❌ `content` 字段有数据，但不是从 `choices[0]` 提取的
- ❌ 缺少 `usage` 信息
- ❌ 与 OpenAI 实现不一致，违反设计意图

**根本原因**:
- 使用 `..Default::default()` 导致 `choices` 为空数组
- 直接设置 `content` 字段，而不是从 `choices[0].message.content` 提取
- 没有提取 `usage` 和 `finish_reason` 信息

**修复内容**:

1. **更新响应数据结构** (`src/providers/aliyun.rs`)
   - 添加 `AliyunUsage` 结构体
   - 添加 `usage` 和 `request_id` 字段到 `AliyunResponse`
   - 添加 `finish_reason` 字段到 `AliyunChoice`

2. **修复 parse_response 方法**
   - 构建完整的 `choices` 数组，包含 `Choice` 对象
   - 从 `choices[0].message.content` 提取 `content` 作为便利字段
   - 提取 `usage` 信息（`input_tokens`, `output_tokens`, `total_tokens`）
   - 提取 `request_id` 到 `response.id`
   - 提取 `finish_reason`

**问题 2: 流式响应无法工作**

**问题描述**:
- ❌ 流式请求没有收到任何内容 chunks
- ❌ 只收到最后一个空的 final chunk
- ❌ 流式功能完全无法使用

**根本原因**:
- 缺少 `X-DashScope-SSE: enable` 头部
- 缺少 `incremental_output: true` 参数
- 使用默认的 SSE 解析，无法正确处理 Aliyun 的特殊格式

**修复内容**:

1. **添加流式参数**
   - 添加 `incremental_output` 字段到 `AliyunParameters`
   - 在 `build_request` 中根据 `stream` 参数设置 `incremental_output`

2. **创建自定义 Provider 实现**
   - 创建 `AliyunProviderImpl` 结构体
   - 实现 `Provider` trait，包含 `chat`, `chat_stream`, `models` 方法
   - 在 `chat_stream` 中添加 `X-DashScope-SSE: enable` 头部

3. **实现自定义流式解析**
   - 实现 `parse_stream_response` 方法
   - 解析 Aliyun SSE 格式（`id:`, `event:`, `data:` 行）
   - 处理 `finish_reason: "null"` (字符串) vs `"stop"`
   - 转换为 `StreamingResponse` 格式

**验证结果**:

非流式响应:
- ✅ `choices` 数组长度: 1
- ✅ `choices[0].message.content == content`
- ✅ 包含 `usage` 信息
- ✅ 包含 `finish_reason`
- ✅ 符合 OpenAI 标准格式

流式响应:
- ✅ 总流式块数: 10
- ✅ 包含内容的块数: 9
- ✅ 完整内容正常接收
- ✅ 流式响应正常工作

**影响范围**:
- ✅ 完全向后兼容（`content` 字段继续工作）
- ✅ 增强功能（现在可以访问 `choices` 数组和 `usage` 信息）
- ✅ 修复流式响应（从完全不工作到正常工作）

### 🧪 Testing

**新增测试**:
1. `examples/test_aliyun_streaming.rs` - 流式响应测试
2. `examples/verify_aliyun_choices.rs` - choices 数组验证
3. `tests/test_aliyun_streaming_format.sh` - API 原始响应测试

### 📝 Documentation

- 添加 `docs/ALIYUN_FIXES_SUMMARY.md` - Aliyun 修复总结
- 添加 `docs/CHATRESPONSE_DESIGN_ANALYSIS.md` - ChatResponse 设计分析
- 添加 `docs/ALIYUN_RESPONSE_VERIFICATION.md` - Aliyun 响应验证报告

---

## [0.4.16] - 2025-10-18

### 🐛 Bug Fixes

#### **修复重复 Content-Type 头部导致 Aliyun 等 Provider 无法使用**

**问题描述**:
- ❌ Aliyun Provider 完全无法使用
- ❌ 错误信息: `Content-Type/Accept application/json,application/json is not supported`
- ❌ 原因: `auth_headers()` 和 `HttpClient::post().json()` 都设置了 `Content-Type`
- ❌ 导致 HTTP 头部重复: `Content-Type: application/json, application/json`

**根本原因**:
1. `Protocol::auth_headers()` 返回 `Content-Type: application/json`
2. `HttpClient::post()` 使用 `.json(body)` 也会自动设置 `Content-Type: application/json`
3. 两个头部值被合并，导致重复
4. 阿里云 API（以及其他严格的 API）不接受重复的头部值

**修复内容**:

1. **Aliyun Provider** (`src/providers/aliyun.rs`)
   - 从 `auth_headers()` 中移除 `Content-Type` 设置
   - 添加注释说明 `.json()` 已自动设置

2. **Zhipu Provider** (`src/providers/zhipu.rs`)
   - 从 `auth_headers()` 中移除 `Content-Type` 设置
   - 避免潜在的重复头部问题

3. **Anthropic Provider** (`src/providers/anthropic.rs`)
   - Vertex AI: 移除 `.with_header("Content-Type", ...)`
   - Bedrock: 移除 `.with_header("Content-Type", ...)`

4. **Ollama Provider** (`src/providers/ollama.rs`)
   - `new()`: 移除 `.with_header("Content-Type", ...)`
   - `with_config()`: 移除 `.with_header("Content-Type", ...)`

5. **OpenAI Provider** (`src/providers/openai.rs`)
   - Azure OpenAI: 移除 `.with_header("Content-Type", ...)`
   - OpenAI Compatible: 移除 `.with_header("Content-Type", ...)`

**影响的 Provider**:
- ✅ **Aliyun (DashScope)** - 修复无法使用的问题
- ✅ **Zhipu (GLM)** - 修复潜在问题
- ✅ **Anthropic (Vertex AI, Bedrock)** - 修复潜在问题
- ✅ **Ollama** - 修复潜在问题
- ✅ **OpenAI (Azure, Compatible)** - 修复潜在问题

**测试验证**:
- ✅ 编译成功
- ✅ 添加 `examples/test_aliyun_basic.rs` 验证修复
- ✅ 所有 Provider 不再重复设置 Content-Type

**修复统计**:
- 修复的文件: 5 个
- 修复的 Provider: 6 个
- 删除的重复设置: 9 处
- 添加的注释: 9 处

**影响范围**:
- ✅ 修复 Aliyun Provider 完全无法使用的严重问题
- ✅ 修复其他 Provider 的潜在兼容性问题
- ✅ 提升 HTTP 头部设置的规范性
- ✅ 完全向后兼容，无需用户修改代码

### 🧪 Testing

#### **添加智谱流式 tool_calls 验证测试**

**新增测试**:
1. `tests/test_zhipu_streaming_direct.sh` - 直接测试智谱 API 原始响应
2. `examples/test_zhipu_flash_streaming_tool_calls.rs` - 测试 llm-connector 解析
3. `examples/debug_zhipu_streaming_tool_calls.rs` - 详细调试示例

**验证结果**:
- ✅ 智谱 API 在流式模式下返回 tool_calls
- ✅ llm-connector 可以正确解析 tool_calls
- ✅ 证明 llm-connector 0.4.15 没有 bug，功能正常

### 📝 Documentation

- 添加 `docs/FIX_DUPLICATE_CONTENT_TYPE_HEADER.md` - 重复头部问题修复文档
- 添加 `docs/ZHIPU_STREAMING_TOOL_CALLS_VERIFICATION.md` - 智谱流式验证报告

---

## [0.4.15] - 2025-10-18

### 🐛 Bug Fixes

#### **修复示例代码编译错误和警告**

**修复内容**:
1. **移除不存在的方法调用** (`examples/test_openai_tool_streaming.rs`)
   - 移除了对不存在的 `LlmClient::openrouter()` 方法的调用
   - 改为使用 `LlmClient::openai()`

2. **修复类型错误** (`examples/test_openai_tool_streaming.rs`)
   - 修复 tool_calls 引用类型问题
   - 将 `&tool_calls_buffer[0]` 改为 `tool_calls_buffer[0].clone()`

3. **消除未使用导入警告** (7 个示例文件)
   - 将 streaming 相关的导入移到 `#[cfg(feature = "streaming")]` 内
   - 避免在非 streaming 模式下产生未使用导入警告
   - 影响文件：
     - `test_zhipu_tool_messages_detailed.rs`
     - `test_deepseek_tools.rs`
     - `test_openai_tool_streaming.rs`
     - `test_zhipu_tool_streaming_issue.rs`
     - `test_glm_models_tool_streaming.rs`
     - `zhipu_tools_streaming.rs`
     - `test_all_providers_tool_streaming.rs`

4. **消除未使用字段警告** (`examples/test_all_providers_tool_streaming.rs`)
   - 添加 `#[allow(dead_code)]` 到 `TestResult` 结构体

5. **修复 clippy 警告**
   - 修复 doc comments 空行警告
   - 修复长度比较警告（`len() > 0` → `!is_empty()`）

### 📝 Documentation

- 添加 `docs/EXAMPLES_AND_TESTS_REVIEW.md` - Examples 和 Tests 审查报告
- 添加 `docs/RELEASE_v0.4.14.md` - v0.4.14 发布总结

**测试验证**:
- ✅ 所有示例都能正常编译
- ✅ 所有测试都能通过
- ✅ 无编译错误
- ✅ 大幅减少编译警告

**影响范围**:
- 修复示例代码的编译问题
- 提升代码质量
- 完全向后兼容

---

## [0.4.14] - 2025-10-18

### 🐛 Bug Fixes

#### **修复 OpenAI 协议工具调用支持 + 移除智谱 GLM 流式强制切换**

**问题 1: OpenAI 协议缺少工具调用支持**

**问题描述**:
- ❌ `OpenAIRequest` 缺少 `tools` 和 `tool_choice` 字段，无法传递工具定义
- ❌ `OpenAIMessage` 缺少 `tool_calls`, `tool_call_id`, `name` 字段
- ❌ `OpenAIResponseMessage` 缺少 `tool_calls` 字段，无法解析工具调用响应
- ❌ 导致所有使用 OpenAI 协议的服务（DeepSeek, Moonshot 等）完全无法使用工具调用

**修复内容**:
1. **OpenAIRequest 添加工具字段** (`src/protocols/openai.rs`)
   ```rust
   pub struct OpenAIRequest {
       // ... 其他字段
       pub tools: Option<Vec<serde_json::Value>>,      // ✅ 新增
       pub tool_choice: Option<serde_json::Value>,     // ✅ 新增
   }
   ```

2. **OpenAIMessage 添加工具字段** (`src/protocols/openai.rs`)
   ```rust
   pub struct OpenAIMessage {
       pub role: String,
       pub content: String,
       pub tool_calls: Option<Vec<serde_json::Value>>,  // ✅ 新增
       pub tool_call_id: Option<String>,                // ✅ 新增
       pub name: Option<String>,                        // ✅ 新增
   }
   ```

3. **OpenAIResponseMessage 添加工具字段** (`src/protocols/openai.rs`)
   ```rust
   pub struct OpenAIResponseMessage {
       pub content: Option<String>,                     // ✅ 改为 Option
       pub tool_calls: Option<Vec<serde_json::Value>>,  // ✅ 新增
   }
   ```

4. **build_request 完整映射工具调用** (`src/protocols/openai.rs:48-106`)
   - 正确映射 `tools` 字段
   - 正确映射 `tool_choice` 字段
   - 正确映射消息中的 `tool_calls`, `tool_call_id`, `name` 字段

5. **parse_response 正确解析工具调用** (`src/protocols/openai.rs:116-149`)
   - 从响应中提取 `tool_calls`
   - 转换为统一的 `ToolCall` 类型

**问题 2: 智谱 GLM 流式响应被强制切换**

**问题描述**:
- ❌ `src/core/traits.rs` 中存在硬编码逻辑，检测到 `Role::Tool` 消息时强制切换为非流式
- ❌ GLM-4.5 正常可返回 91 个流式块，但包含工具结果时被强制切换为 1 个块
- ❌ 这是一个临时修复（workaround），现在已不再需要

**修复内容**:
- **移除硬编码修复逻辑** (`src/core/traits.rs:155-173`)
  - 删除了检测 `Role::Tool` 和 `zhipu` 的特殊处理
  - 智谱 GLM 现在可以在包含工具调用结果时正常使用流式响应

**测试验证**:
- ✅ OpenAI 协议完整支持工具调用（tools, tool_choice, tool_calls）
- ✅ DeepSeek 现在可以正常使用工具调用
- ✅ 所有 OpenAI 兼容服务（Moonshot, Together AI 等）都可以使用工具调用
- ✅ 智谱 GLM 在包含 Role::Tool 时可以使用流式响应
- ✅ 所有核心库测试通过（27 个测试）

**新增示例**:
- `examples/verify_tool_fix.rs` - 验证工具调用修复效果

**影响范围**:
- 修复所有使用 OpenAI 协议的服务的工具调用功能
- 移除智谱 GLM 的流式响应限制
- 完全向后兼容

---

## [0.4.13] - 2025-10-18

### 🐛 Bug Fixes

#### **修复智谱 GLM 多轮工具调用支持**

**问题描述**:
- ❌ `ZhipuMessage` 缺少 `tool_call_id` 字段，无法在 Tool 消息中关联工具调用
- ❌ `ZhipuMessage` 缺少 `name` 字段，无法传递工具名称
- ❌ 导致多轮 Function Calling 对话失败（第二轮无法正确传递工具执行结果）

**修复内容**:
1. **ZhipuMessage 结构完善** (`src/providers/zhipu.rs:272-282`)
   ```rust
   pub struct ZhipuMessage {
       pub role: String,
       pub content: String,
       pub tool_calls: Option<Vec<serde_json::Value>>,
       pub tool_call_id: Option<String>,  // ✅ 新增
       pub name: Option<String>,          // ✅ 新增
   }
   ```

2. **build_request 映射补充** (`src/providers/zhipu.rs:77-96`)
   - 正确映射 `tool_call_id` 字段
   - 正确映射 `name` 字段

**测试验证**:
- ✅ 单轮工具调用：User 提问 → LLM 返回 tool_calls
- ✅ 多轮工具调用：Tool 结果 → LLM 返回文本响应
- ✅ 三轮对话：User 追问 → LLM 正确触发新的 tool_calls
- ✅ Tool 消息序列化：`role="tool"`, `tool_call_id`, `name` 全部正确

**新增示例**:
- `examples/zhipu_multiround_tools.rs` - 多轮工具调用演示
- `examples/zhipu_tools_edge_cases.rs` - 边缘情况测试
- `examples/verify_tool_message_serialization.rs` - 序列化验证

**影响范围**:
- 修复智谱 GLM 的多轮工具调用功能
- 完全符合 OpenAI Function Calling 规范
- 完全向后兼容

---

## [0.4.12] - 2025-10-18

### 🐛 Bug Fixes

#### **修复智谱 GLM 流式响应和工具调用支持**

**流式响应问题**:
- ❌ 问题：智谱 API 使用单换行分隔 SSE（`data: {...}\n`），导致默认解析器失败
- ❌ 问题：`StreamingResponse.content` 字段未填充，`get_content()` 返回空字符串
- ❌ 问题：`ZhipuRequest` 缺少 `stream` 参数，API 不知道要返回流式响应

**工具调用问题**:
- ❌ 问题：`ZhipuRequest` 缺少 `tools` 和 `tool_choice` 字段
- ❌ 问题：`ZhipuMessage` 不支持 `tool_calls` 响应
- ❌ 问题：流式和非流式请求都无法传递工具参数

**修复内容**:
1. **流式解析器** (`src/providers/zhipu.rs:126-201`)
   - 实现智谱专用 `parse_stream_response()`
   - 支持单换行分隔的 SSE 格式
   - 自动填充 `content` 字段（从 `delta.content` 复制）
   
2. **请求参数** (`src/providers/zhipu.rs:216-234`)
   - 添加 `stream: Option<bool>` 字段
   - 添加 `tools: Option<Vec<Tool>>` 字段
   - 添加 `tool_choice: Option<ToolChoice>` 字段
   
3. **响应解析** (`src/providers/zhipu.rs:240-264`)
   - `ZhipuMessage.content` 使用 `#[serde(default)]`（工具调用时可为空）
   - `ZhipuMessage.tool_calls` 支持工具调用响应
   - `ZhipuResponse` 包含完整元数据（id, created, usage）
   - `ZhipuChoice` 支持 `finish_reason`（识别 `tool_calls` 结束）

**测试验证**:
- ✅ 流式响应：124 个数据块，642 字符输出
- ✅ 非流式工具调用：`finish_reason: "tool_calls"`，正确解析参数
- ✅ 流式工具调用：`finish_reason: "tool_calls"`，正确解析参数

**影响范围**:
- 仅影响智谱 GLM provider
- 完全向后兼容
- 修复后与 OpenAI 协议对齐

**新增示例**:
- `examples/zhipu_tools.rs` - 工具调用（非流式）
- `examples/zhipu_tools_streaming.rs` - 工具调用（流式）

---

## [0.4.11] - 2025-10-17

### 🐛 Bug Fixes

**修复智谱流式响应解析问题（初步修复）**
- 实现 `ZhipuProtocol::parse_stream_response()` 专用流式解析器
- 支持单换行分隔的 SSE 格式
- 正确处理 `data:` 前缀（带或不带空格）

---

## [Unreleased]

### 🐛 **BUGFIX: 修复智谱流式响应解析问题**

#### **问题描述**
智谱 API 使用单换行分隔 SSE 事件（`data: {...}\n`），而不是标准的双换行（`data: {...}\n\n`），导致默认 SSE 解析器无法正确解析流式响应，产生 0 个数据块。

#### **修复内容**
- **新增**: `ZhipuProtocol::parse_stream_response()` 专用流式解析器
  - 支持单换行分隔的 SSE 格式
  - 正确处理 `data:` 前缀（带或不带空格）
  - 跳过 `[DONE]` 标记和空 payload
  - 提供详细的错误信息（包含原始 JSON）

#### **测试改进**
- 更新 `examples/zhipu_streaming.rs`
  - 添加数据块计数器
  - 显示解析器类型提示
  - 使用 `glm-4-flash` 模型（更快响应）
  - 添加零数据块警告

#### **影响**
- ✅ **修复**: 智谱流式 API 现在可以正常工作
- ✅ **兼容性**: 不影响其他 Provider 的流式功能
- ✅ **调试性**: 解析失败时显示原始 JSON

---

### ✨ **FEAT: API Naming Standardization**

#### **Changed**
- **Unified Constructor Naming**
  - `ollama_with_url()` → `ollama_with_base_url()` (kept old name as deprecated)
  - Removed redundant `zhipu_default()` (use `zhipu()` directly)
  - All providers now follow consistent `{provider}_with_base_url()` pattern

#### **Added**
- **Type-Safe Provider Conversions**
  - `LlmClient::as_ollama()` → `Option<&OllamaProvider>`
  - `LlmClient::as_openai()` → `Option<&OpenAIProvider>`
  - `LlmClient::as_aliyun()` → `Option<&AliyunProvider>`
  - `LlmClient::as_anthropic()` → `Option<&AnthropicProvider>`
  - `LlmClient::as_zhipu()` → `Option<&ZhipuProvider>`
  
- **API Key Validation Functions**
  - `validate_openai_key()`
  - `validate_aliyun_key()`
  - `validate_anthropic_key()` (already existed)
  - `validate_zhipu_key()` (already existed)

- **Advanced Configuration Methods**
  - All `{provider}_with_config()` methods now exposed in `LlmClient`
  - All `{provider}_with_timeout()` methods now exposed in `LlmClient`
  - Cloud-specific methods: `anthropic_vertex()`, `anthropic_bedrock()`, `aliyun_international()`, etc.

#### **Documentation**
- **NEW**: `docs/NAMING_CONVENTIONS.md` - Comprehensive naming standards guide
- **NEW**: `.augment/rules/naming.md` - Qoder auto-check rules
- Updated all examples to use new naming conventions

#### **Deprecated**
- `LlmClient::ollama_with_url()` → Use `ollama_with_base_url()`
- `providers::zhipu_default()` → Use `zhipu()` directly
- `LlmClient::ollama()` (the method, not constructor) → Use `as_ollama()`

#### **Impact**
- ✅ **Consistency**: All providers follow same naming pattern
- ✅ **Type Safety**: No more manual `downcast_ref` needed
- ✅ **Completeness**: All provider variants exposed in `LlmClient`
- ✅ **Documentation**: Clear naming rules for contributors

---

## [0.4.9] - 2025-10-16

### 📚 **DOCS: Fix API Documentation and Examples**

#### **Fixed**
- **README API Examples** - Updated streaming API examples to reflect current V2 architecture
  - Replaced deprecated `chat_stream_universal()`, `chat_stream_sse()`, `chat_stream_ndjson()` with current `chat_stream()`
  - Updated streaming examples to use `StreamingResponse` and `get_content()` method
  - Added clear distinction between V2 (current) and V1 (legacy) APIs in changelog
  - Fixed 29 documentation tests that used incorrect import paths

#### **Added**
- **New Example**: `streaming_v2_demo.rs` - Demonstrates current V2 streaming API
- **API Clarification**: Clear documentation of current streaming interface
- **Migration Guide**: Explains differences between V1 and V2 streaming APIs

#### **Impact**
- ✅ **Documentation**: All examples now reflect current API
- ✅ **Tests**: All 93 tests pass (including 50 documentation tests)
- ✅ **Clarity**: Clear separation between current and legacy APIs
- ✅ **Examples**: Working examples for current streaming interface

## [0.4.8] - 2025-10-16

### 🔧 **REFACTOR: Simplify Configuration Module Structure**

#### **Simplified**
- **Configuration Module** - Simplified `src/config/` directory to single `src/config.rs` file
  - Eliminated confusion between `src/config/provider.rs` and `src/providers/` directory
  - Consolidated all configuration types into single, clear module
  - Maintained all existing functionality and API compatibility
  - All 28 unit tests pass

#### **Structure Changes**
- **Before**: `src/config/mod.rs` + `src/config/provider.rs` (confusing)
- **After**: `src/config.rs` (clear and simple)
- **Benefits**: No naming confusion, easier to find configuration code, simpler maintenance

#### **Impact**
- ✅ **Clarity**: Eliminated naming confusion with providers
- ✅ **Simplicity**: Single file for all configuration needs
- ✅ **Maintainability**: Easier to locate and modify configuration code
- ✅ **Compatibility**: No breaking changes to public API

## [0.4.7] - 2025-10-16

### 🏗️ **ARCHITECTURE: Correct Protocol vs Provider Separation**

#### **Refactored**
- **Protocol/Provider Architecture** - Implemented correct separation of public vs private protocols
  - **Public Protocols** (`src/protocols/`): Only industry-standard protocols (OpenAI, Anthropic)
  - **Private Protocols** (`src/providers/`): Provider-specific protocols inline with implementations
  - Moved `AliyunProtocol` and `ZhipuProtocol` from `protocols/` to `providers/` as private protocols
  - Updated exports: Standard protocols from `protocols`, private protocols from `providers`
  - All 78 unit and integration tests pass

#### **Design Principles**
- **Public Protocols**: Industry-recognized standards that multiple providers might implement
- **Private Protocols**: Provider-specific APIs that are tightly coupled to their implementations
- **Clean Separation**: Protocols define API formats, providers implement service logic
- **Maintainability**: Private protocols are co-located with their implementations

#### **Impact**
- ✅ **Architecture**: Clean separation of public vs private protocols
- ✅ **Maintainability**: Private protocols are easier to maintain alongside providers
- ✅ **Extensibility**: Clear guidelines for adding new protocols vs providers
- ✅ **Tests**: All functionality tests pass (78/78)

## [0.4.6] - 2025-10-16

### 🔧 **HOTFIX: Streaming Integration Test Errors**

#### **Fixed**
- **Streaming integration test compilation errors** - Fixed all compilation errors in streaming tests
  - Fixed `tests/streaming_integration_tests.rs`: Added missing `Role` import
  - Updated all `Message::user()` calls to use proper `Message` construction with `Role::User`
  - Fixed all client creation calls: `.unwrap()` → `?` for V2 architecture
  - Fixed error handling test to properly detect authentication errors
  - All streaming integration tests now pass (4/4 passed, 4 ignored for API keys)

#### **Impact**
- ✅ **Streaming Tests**: All streaming integration tests compile and pass
- ✅ **Test Coverage**: Complete test coverage for streaming functionality
- ✅ **V2 Architecture**: All tests use correct V2 architecture APIs

## [0.4.5] - 2025-10-16

### 🔧 **HOTFIX: Test Compilation Errors**

#### **Fixed**
- **Test compilation errors** - Fixed compilation errors in test files
  - Fixed `tests/client_tests.rs`: Updated `protocol_name()` → `provider_name()` method calls
  - Fixed main documentation tests in `src/lib.rs` and `src/client.rs`
  - Updated import statements to use correct V2 architecture paths
  - All unit tests and integration tests now pass successfully

#### **Impact**
- ✅ **Tests**: All unit and integration tests compile and pass (78/78)
- ✅ **Documentation**: Main documentation examples work correctly
- ✅ **CI/CD**: Test suite runs successfully for automated builds

## [0.4.4] - 2025-10-16

### 🔧 **HOTFIX: Examples Compilation Errors**

#### **Fixed**
- **Examples compilation errors** - Fixed all compilation errors and warnings in example files
  - Updated `examples/zhipu_basic.rs`: Fixed API calls and imports for V2 architecture
  - Updated `examples/zhipu_streaming.rs`: Fixed Message construction and client creation
  - Updated `examples/streaming_basic.rs`: Fixed imports and Result handling
  - Updated `examples/ollama_model_management.rs`: Fixed Ollama provider interface usage
  - Updated `examples/v1_vs_v2_comparison.rs`: Removed deprecated feature flags
  - All examples now use V2 architecture APIs correctly

#### **Impact**
- ✅ **Examples**: All examples compile and run successfully
- ✅ **Documentation**: Examples serve as accurate V2 architecture documentation
- ✅ **User Experience**: Users can run examples without compilation errors

## [0.4.3] - 2025-10-16

### 🔧 **HOTFIX: Module Privacy Error**

#### **Fixed**
- **Critical module privacy error** - Fixed private module access in streaming functionality
  - Fixed import path: `crate::types::streaming::ChatStream` → `crate::types::ChatStream`
  - Fixed import path: `crate::types::streaming::StreamingResponse` → `crate::types::StreamingResponse`
  - The `streaming` module is conditionally exported and should be accessed through `types` module
  - Affected file: `src/sse.rs`

#### **Impact**
- ✅ **Compilation**: Now compiles successfully without privacy errors
- ✅ **Streaming**: All streaming features work correctly
- ✅ **Functionality**: No breaking changes to public API

## [0.4.2] - 2025-10-16

### 🔧 **HOTFIX: Type Mismatch Error**

#### **Fixed**
- **Critical type mismatch error** - Fixed streaming response type conversion
  - Added `sse_to_streaming_response()` function to convert `String` stream to `StreamingResponse` stream
  - Fixed type mismatch: expected `StreamingResponse` but found `String` in streaming methods
  - Affected files: `src/sse.rs`, `src/core/traits.rs`, `src/protocols/zhipu.rs`, `src/providers/ollama.rs`
  - All streaming functionality now works correctly with proper type conversion

#### **Impact**
- ✅ **Compilation**: Now compiles successfully without type errors
- ✅ **Streaming**: All streaming features work with correct types
- ✅ **Functionality**: No breaking changes to public API

## [0.4.1] - 2025-10-16

### 🔧 **HOTFIX: Compilation Error**

#### **Fixed**
- **Critical compilation error** - Fixed unresolved import `crate::sse::SseStream`
  - Replaced incorrect `SseStream::new(response)` calls with `crate::sse::sse_events(response)`
  - Affected files: `src/core/traits.rs`, `src/protocols/zhipu.rs`, `src/providers/ollama.rs`
  - All streaming functionality now works correctly

#### **Impact**
- ✅ **Compilation**: Now compiles successfully without errors
- ✅ **Streaming**: All streaming features work as expected
- ✅ **Functionality**: No breaking changes to public API

## [0.4.0] - 2025-10-16

### 🚀 **MAJOR RELEASE: V2 Architecture**

This is a major release that introduces the new V2 architecture as the default, providing significant performance improvements and a cleaner API design.

#### ⚡ **Performance Improvements**
- **7,000x+ faster client creation** - From ~53ms to ~7µs
- **Minimal memory footprint** - Only 16 bytes per client instance
- **Zero-cost cloning** - Arc-based sharing for efficient cloning

#### 🏗️ **New Architecture**
- **Clear Protocol/Provider separation** - Protocols define API specs, Providers implement services
- **Unified trait system** - `Protocol` and `Provider` traits for maximum extensibility
- **Type-safe HTTP client** - Compile-time guarantees for correctness
- **Generic provider implementation** - `GenericProvider<Protocol>` for most use cases

#### 🔄 **API Changes (Breaking)**

##### **Client Creation**
```rust
// V1 (Legacy)
let client = LlmClient::openai("sk-...", None);
let client = LlmClient::ollama(None);

// V2 (New Default)
let client = LlmClient::openai("sk-...")?;  // Returns Result
let client = LlmClient::ollama()?;          // Returns Result
```

##### **Method Renames**
```rust
// V1 → V2
client.fetch_models()  → client.models()
client.protocol_name() → client.provider_name()
```

##### **Parameter Changes**
- **OpenAI**: Removed optional second parameter, use dedicated methods
  - `openai(key, Some(url))` → `openai_with_base_url(key, url)?`
- **Ollama**: Removed optional parameter
  - `ollama(Some(url))` → `ollama_with_url(url)?`

#### 🆕 **New Features**

##### **Additional Client Creation Methods**
```rust
// Azure OpenAI support
LlmClient::azure_openai("key", "endpoint", "version")?

// OpenAI-compatible services
LlmClient::openai_compatible("key", "url", "name")?

// Zhipu GLM OpenAI-compatible mode
LlmClient::zhipu_openai_compatible("key")?

// Enhanced configuration options
LlmClient::openai_with_config("key", url, timeout, proxy)?
```

##### **Enhanced Ollama Support**
```rust
// Direct access to Ollama-specific features
if let Some(ollama) = client.as_ollama() {
    ollama.pull_model("llama2").await?;
    let models = ollama.models().await?;
}
```

#### 📦 **Protocol Support**
- **OpenAI Protocol** - Complete OpenAI API specification
- **Anthropic Protocol** - Full Claude API support with Vertex AI and Bedrock
- **Aliyun Protocol** - DashScope API with regional support
- **Zhipu Protocol** - Native and OpenAI-compatible formats
- **Ollama Provider** - Custom implementation with model management

#### 🔄 **Migration Guide**

##### **Option 1: Backward Compatibility**
```toml
# Cargo.toml
[features]
v1-legacy = []
```

```rust
// Use V1 API
#[cfg(feature = "v1-legacy")]
use llm_connector::v1::LlmClient;

// Use V2 API (default)
#[cfg(not(feature = "v1-legacy"))]
use llm_connector::LlmClient;
```

##### **Option 2: Direct Migration**
1. Add `?` to handle `Result` return types
2. Update method names: `fetch_models()` → `models()`, `protocol_name()` → `provider_name()`
3. Replace parameter patterns with dedicated methods
4. Update imports if using internal traits

#### 🏛️ **Architecture Benefits**
- **Extensibility** - Easy to add new protocols and providers
- **Type Safety** - Compile-time guarantees for all operations
- **Performance** - Optimized for speed and memory efficiency
- **Clarity** - Clear separation of concerns between protocols and providers
- **Maintainability** - Reduced code duplication and cleaner abstractions

## [0.3.6] - 2025-10-14

### ✨ Added

#### Ollama Streaming Support
- Implemented line-delimited JSON streaming for Ollama protocol
  - Added non-SSE parser for JSON lines stream
  - Integrated into core streaming pipeline with protocol switch
  - Normalized to `StreamingResponse` with `get_content()` for output
- Added `examples/ollama_streaming.rs` demonstrating `chat_stream()` usage

### 📝 Updated
- README and examples already standardized to use `get_content()` for streaming output

## [0.2.3] - 2025-01-06

### ✨ Added

#### Improved Error Messages
- **Cleaned up authentication error messages** for OpenAI-compatible providers
  - Removes OpenAI-specific URLs (like "platform.openai.com") from error messages
  - Adds helpful context: "Please verify your API key is correct and has the necessary permissions"
  - Makes errors more generic and applicable to all OpenAI-compatible providers (DeepSeek, Zhipu, Moonshot, etc.)

#### New Debug Tools
- **Added `debug_deepseek.rs` example** for troubleshooting authentication issues
  - Validates API key format
  - Tests model fetching and chat requests
  - Provides specific troubleshooting guidance based on error type
  - Can accept API key from command line or environment variable

#### Documentation
- **Added `TROUBLESHOOTING.md`** - Comprehensive troubleshooting guide
  - Authentication errors and solutions
  - Connection errors and debugging steps
  - Rate limit handling
  - Model not found errors
  - Provider-specific instructions for DeepSeek, OpenAI, Zhipu, Moonshot
  - Example code for common scenarios

### 🔧 Changed

#### Simplified API - Removed `supported_models()`
- **Removed `supported_models()` method** from all traits and implementations
  - Removed from `Provider` trait
  - Removed from `ProviderAdapter` trait
  - Removed from `LlmClient`
  - Removed from all protocol implementations (OpenAI, Anthropic, Aliyun, Ollama)
- **Removed `supports_model()` method** from `Provider` trait (was dependent on `supported_models()`)
- **Removed hardcoded model lists** from protocol structs
  - Removed `supported_models` field from `AnthropicProtocol`
  - Removed `supported_models` field from `AliyunProtocol`
  - Removed `supported_models` field from `OllamaProtocol`

#### Rationale
- `supported_models()` returned empty `[]` for most protocols (OpenAI, Anthropic, Aliyun)
- Only Ollama had hardcoded models, which were outdated
- Users should use `fetch_models()` for real-time model discovery
- Simplifies the API by removing confusion between two similar methods

#### Migration Guide

**Before:**
```rust
let client = LlmClient::openai("sk-...");
let models = client.supported_models(); // Returns []
```

**After:**
```rust
let client = LlmClient::openai("sk-...");
let models = client.fetch_models().await?; // Returns actual models from API
```

For protocols that don't support `fetch_models()` (Anthropic, Aliyun, Ollama), you can use any model name directly in your requests.

### 📝 Updated

- Updated tests to remove `supported_models()` usage
- Updated examples to demonstrate only `fetch_models()`
- Updated README.md to remove references to `supported_models()`
- Simplified documentation and examples

## [0.2.2] - 2025-01-06

Same as 0.2.1 - version bump for crates.io publication.

## [0.2.1] - 2025-01-06

### ✨ Added

#### Online Model Discovery
- **New `fetch_models()` method** for retrieving available models from API
  - Added to `Provider` trait, `LlmClient`, and `GenericProvider`
  - Makes GET request to `/v1/models` endpoint for OpenAI-compatible providers
  - Returns `Vec<String>` of available model IDs
  - Returns `UnsupportedOperation` error for protocols without model listing support

#### HTTP Transport Enhancement
- Added `get()` method to `HttpTransport` for GET requests
- Supports custom headers and authentication

#### Error Handling
- Added `UnsupportedOperation` error variant for unsupported operations
- Returns HTTP 501 status code for unsupported operations

#### Examples
- `examples/test_fetch_models.rs` - Comprehensive test with all providers
- `examples/fetch_models_simple.rs` - Simple comparison example
- `examples/test_with_keys.rs` - Test with keys.yaml configuration

#### Documentation
- `FETCH_MODELS_FEATURE.md` - Complete feature documentation
- `TEST_RESULTS.md` - Test results and verification
- Updated README.md with model discovery section
- Added comparison table for `supported_models()` vs `fetch_models()`

### 🔧 Changed

#### OpenAI Protocol
- **Removed hardcoded model lists** from `OpenAIProtocol`
- `supported_models()` now returns empty `[]` instead of hardcoded models
- Users can now use **any model name** without restrictions
- Implemented `models_endpoint_url()` to support `/v1/models` endpoint

#### Documentation Cleanup
- Removed references to third-party providers (DeepSeek, Zhipu, Moonshot, etc.) from OpenAI protocol docs
- Updated examples to focus on OpenAI instead of third-party providers
- Simplified documentation to emphasize protocol-first approach

#### Provider Type Aliases
- Removed provider-specific type aliases:
  - `DeepSeekProvider`
  - `ZhipuProvider`
  - `MoonshotProvider`
  - `VolcEngineProvider`
  - `TencentProvider`
  - `MiniMaxProvider`
  - `StepFunProvider`

### 🐛 Fixed

#### Configuration
- Fixed `keys.yaml` model names:
  - Removed invalid `qwen3-turbo` model
  - Updated to valid Aliyun models: `qwen-turbo`, `qwen-plus`, `qwen-max`
  - Updated Qwen2 models to Qwen2.5 versions

#### Dependencies
- Added `serde_yaml` to `[dev-dependencies]` for examples
- Fixed `serde_yaml` resolution in test examples

#### Code Quality
- Removed unused imports (`HttpTransport`, `LlmConnectorError` from openai.rs)
- Fixed struct field issues (removed incorrect `transport` field)

### 📊 Test Results

#### Successfully Tested Providers (Online Model Fetching)

| Provider | Status | Models Found | Example Models |
|----------|--------|--------------|----------------|
| DeepSeek | ✅ | 2 | `deepseek-chat`, `deepseek-reasoner` |
| Zhipu (GLM) | ✅ | 3 | `glm-4.5`, `glm-4.5-air`, `glm-4.6` |
| Moonshot | ✅ | 12 | `moonshot-v1-32k`, `kimi-latest`, `kimi-thinking-preview` |
| LongCat | ❌ | - | `/models` endpoint not available |
| VolcEngine | ❌ | - | `/models` endpoint not available |
| Aliyun | ℹ️ | - | Protocol doesn't support model listing |
| Anthropic | ℹ️ | - | Protocol doesn't support model listing |

### 📝 Migration Guide

#### For Users Relying on Hardcoded Models

**Before (v0.2.0):**
```rust
let client = LlmClient::openai("sk-...");
let models = client.supported_models();
// Returns: ["gpt-4", "gpt-3.5-turbo", "gpt-4-turbo"]
```

**After (v0.2.1):**
```rust
let client = LlmClient::openai("sk-...");

// Option 1: Use any model name directly (recommended)
let request = ChatRequest {
    model: "gpt-4o".to_string(), // Any model name works
    // ...
};

// Option 2: Fetch models online
let models = client.fetch_models().await?;
// Returns: actual models from OpenAI API
```

#### For OpenAI-Compatible Providers

**Before:**
```rust
// Had to check hardcoded list
let models = client.supported_models();
```

**After:**
```rust
// Fetch real-time models from provider
let client = LlmClient::openai_compatible(
    "sk-...",
    "https://api.deepseek.com/v1"
);
let models = client.fetch_models().await?;
// Returns: ["deepseek-chat", "deepseek-reasoner"]
```

### 🎯 Benefits

1. **No Model Restrictions**: Use any model name without being limited by hardcoded lists
2. **Always Up-to-Date**: Get the latest models directly from the API
3. **Backward Compatible**: Existing code continues to work
4. **Flexible**: Providers can opt-in to model listing support
5. **Clear Errors**: Explicit error messages when operations aren't supported

### 🔗 Related Issues

- Fixed errors in `src/protocols/openai.rs`
- Removed hardcoded `supported_models`
- Implemented online model fetching (Option 3)
- Updated documentation to reflect changes

### 📚 Documentation

- README.md: Added "Key Features" section
- README.md: Added "Model Discovery" section with comparison table
- README.md: Added "Recent Changes" section
- README.md: Updated error handling examples
- README.md: Updated examples section

### 🧪 Testing

All tests passing:
```bash
cargo check --lib                    # ✅ Success
cargo run --example test_openai_only # ✅ All tests passed
cargo run --example test_with_keys   # ✅ 6/6 providers tested
cargo run --example test_fetch_models # ✅ Online fetching works
```

---

## [0.2.0] - Previous Release

Initial release with 4 protocol support and basic functionality.

---

## Future Enhancements

Potential improvements for future releases:

1. **Model Caching**: Cache fetched models to reduce API calls
2. **Model Metadata**: Return full model objects with capabilities, not just IDs
3. **Model Filtering**: Add parameters to filter models by capability
4. **Extended Protocol Support**: Implement model listing for other protocols if available
5. **Pagination Support**: Handle paginated model responses
## [0.3.3] - 2025-10-14

### ✨ Added
- README: Added “Reasoning Synonyms” section with normalized keys and usage examples (`reasoning_any()`), covering non-streaming and streaming.

### 🔧 Changed
- Examples: Removed outdated examples using deprecated `openai_compatible` (`examples/test_fetch_models.rs`, `examples/test_with_keys.rs`).
- Examples: Updated DeepSeek and fetch models example to use `LlmClient::openai(api_key, Some(base_url))`.
- Docs: Fixed doctests across `lib.rs`, `protocols/core.rs`, `protocols/openai.rs`, `protocols/aliyun.rs`, `protocols/anthropic.rs` to match current API.
- Docs: Replaced obsolete imports like `protocols::aliyun::qwen` and `protocols::anthropic::claude` with `LlmClient::aliyun(...)` and `LlmClient::anthropic(...)`.
- Docs: Standardized message initialization to `Message::user(...)` or `Role` enums where appropriate.

### ✅ Validation
- `cargo build --examples` passes.
- `cargo test` (library and integration with `streaming` feature) passes.
- `cargo test --doc` passes (13 passed, 0 failed, 4 ignored).
## 0.3.4 - 2025-10-14

Updates
- Add compatibility alias `types::ChatMessage = Message` to ease migration.
- Add `ChatResponse::get_usage_safe()` returning `(prompt, completion, total)`.
- Add `ChatResponse::get_content()` returning the first choice content as `Option<&str>`.
- README install snippet updated to `0.3.4`.

Notes
- `ChatRequest::new(model)` remains as minimal constructor.
- Use `ChatRequest::new_with_messages(model, messages)` to pass initial message list.
- `Message::user/assistant/system` are preferred constructors; reasoning fields are auto-populated.

## 0.3.5 - 2025-10-14

Updates
- Add `StreamingResponse::get_content()` for convenience and API symmetry with `ChatResponse::get_content()`.

Notes
- No breaking changes; existing code continues to work. You can still access `choices[0].delta.content` directly.

