1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Copyright 2024-2026 Reflective Labs
// SPDX-License-Identifier: MIT
// See LICENSE file in the project root for full license information.
//! Example: Refactored provider using common abstractions.
//!
//! This shows how to implement a provider using the common abstractions
//! to reduce code duplication.
//!
//! # Benefits
//!
//! - **~50 lines** vs ~185 lines without abstractions
//! - **No manual HTTP client setup** - uses `HttpProviderConfig`
//! - **No manual request/response parsing** - uses `ChatCompletionRequest`/`ChatCompletionResponse`
//! - **Automatic error handling** - uses `handle_openai_style_error()` via `OpenAiCompatibleProvider`
//! - **Consistent behavior** - same patterns as all other OpenAI-compatible providers
use crate;
use crate;
/// Example provider using common abstractions.
///
/// This demonstrates the fully refactored approach:
/// 1. Uses `HttpProviderConfig` for HTTP setup
/// 2. Implements `OpenAiCompatibleProvider` for default behavior
/// 3. Gets automatic error handling via `handle_openai_style_error()`
/// 4. Gets automatic request/response handling via `make_chat_completion_request()`
///
/// # Example
///
/// ```ignore
/// use converge_provider::ExampleProvider;
/// use crate::provider_api::{LlmProvider, LlmRequest};
///
/// let provider = ExampleProvider::new("api-key", "model-name");
/// let response = provider.complete(&LlmRequest::new("Hello!"))?;
/// ```
// ============================================================================
// Comparison: Before vs After Refactoring
// ============================================================================
//
// BEFORE (without abstractions): ~185 lines
// - Manual HTTP client setup (api_key, model, client, base_url)
// - Manual request structs (Request, Message, etc.)
// - Manual response structs (Response, Choice, Usage, etc.)
// - Manual error handling (~25 lines of parsing and mapping)
// - Manual response parsing (~20 lines)
// - Manual finish_reason mapping
//
// AFTER (with abstractions): ~80 lines
// - HttpProviderConfig handles HTTP setup
// - ChatCompletionRequest handles request building
// - ChatCompletionResponse handles response parsing
// - handle_openai_style_error() handles error parsing
// - OpenAiCompatibleProvider trait provides default implementation
//
// SAVINGS: ~105 lines (57% reduction)
//
// ============================================================================
// What You Get Automatically
// ============================================================================
//
// ✅ HTTP client setup and configuration
// ✅ Request building from LlmRequest
// ✅ Error handling with proper LlmError mapping
// ✅ Response parsing to LlmResponse
// ✅ Finish reason mapping
// ✅ Token usage extraction
//
// ============================================================================
// What You Still Need to Provide
// ============================================================================
//
// - Provider name (for `name()`)
// - Base URL (in `new()`)
// - Endpoint path (in `endpoint()`)
// - Environment variable name (in `from_env()`)
//
// That's it! Everything else is handled by the abstractions.