llmbridgekit 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- llmbridgekit-1.0.0/CHANGELOG.md +25 -0
- llmbridgekit-1.0.0/ENVIRONMENT_VARIABLES.md +94 -0
- llmbridgekit-1.0.0/MANIFEST.in +10 -0
- llmbridgekit-1.0.0/PKG-INFO +529 -0
- llmbridgekit-1.0.0/README.md +458 -0
- llmbridgekit-1.0.0/VERSION +1 -0
- llmbridgekit-1.0.0/llmbridgekit/__init__.py +77 -0
- llmbridgekit-1.0.0/llmbridgekit/client.py +609 -0
- llmbridgekit-1.0.0/llmbridgekit/config.py +209 -0
- llmbridgekit-1.0.0/llmbridgekit/exceptions.py +151 -0
- llmbridgekit-1.0.0/llmbridgekit/fallback.py +161 -0
- llmbridgekit-1.0.0/llmbridgekit/json_utils.py +210 -0
- llmbridgekit-1.0.0/llmbridgekit/models.py +265 -0
- llmbridgekit-1.0.0/llmbridgekit/pricing.py +167 -0
- llmbridgekit-1.0.0/llmbridgekit/providers/__init__.py +38 -0
- llmbridgekit-1.0.0/llmbridgekit/providers/anthropic_provider.py +219 -0
- llmbridgekit-1.0.0/llmbridgekit/providers/azure_openai_provider.py +211 -0
- llmbridgekit-1.0.0/llmbridgekit/providers/base.py +260 -0
- llmbridgekit-1.0.0/llmbridgekit/providers/cohere_provider.py +212 -0
- llmbridgekit-1.0.0/llmbridgekit/providers/custom_http_provider.py +235 -0
- llmbridgekit-1.0.0/llmbridgekit/providers/gemini_provider.py +252 -0
- llmbridgekit-1.0.0/llmbridgekit/providers/groq_provider.py +204 -0
- llmbridgekit-1.0.0/llmbridgekit/providers/huggingface_provider.py +183 -0
- llmbridgekit-1.0.0/llmbridgekit/providers/lmstudio_provider.py +181 -0
- llmbridgekit-1.0.0/llmbridgekit/providers/mistral_provider.py +193 -0
- llmbridgekit-1.0.0/llmbridgekit/providers/ollama_provider.py +193 -0
- llmbridgekit-1.0.0/llmbridgekit/providers/openai_provider.py +257 -0
- llmbridgekit-1.0.0/llmbridgekit/providers/openrouter_provider.py +230 -0
- llmbridgekit-1.0.0/llmbridgekit/providers/together_provider.py +214 -0
- llmbridgekit-1.0.0/llmbridgekit/redaction.py +170 -0
- llmbridgekit-1.0.0/llmbridgekit/registry.py +271 -0
- llmbridgekit-1.0.0/llmbridgekit/retry.py +206 -0
- llmbridgekit-1.0.0/llmbridgekit/usage.py +174 -0
- llmbridgekit-1.0.0/llmbridgekit/validation.py +234 -0
- llmbridgekit-1.0.0/llmbridgekit.egg-info/PKG-INFO +529 -0
- llmbridgekit-1.0.0/llmbridgekit.egg-info/SOURCES.txt +46 -0
- llmbridgekit-1.0.0/llmbridgekit.egg-info/dependency_links.txt +1 -0
- llmbridgekit-1.0.0/llmbridgekit.egg-info/requires.txt +70 -0
- llmbridgekit-1.0.0/llmbridgekit.egg-info/top_level.txt +1 -0
- llmbridgekit-1.0.0/llmbridgekit_USER_MANUAL.md +2168 -0
- llmbridgekit-1.0.0/pyproject.toml +183 -0
- llmbridgekit-1.0.0/requirements.txt +1 -0
- llmbridgekit-1.0.0/setup.cfg +4 -0
- llmbridgekit-1.0.0/setup.py +60 -0
- llmbridgekit-1.0.0/tests/test_client.py +197 -0
- llmbridgekit-1.0.0/tests/test_fallback.py +151 -0
- llmbridgekit-1.0.0/tests/test_providers.py +224 -0
- llmbridgekit-1.0.0/tests/test_utils.py +295 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to llmbridgekit will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.0.0] - 2026-06-01
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Initial release of llmbridgekit
|
|
12
|
+
- Multi-provider support: OpenAI, Azure OpenAI, Google Gemini, Anthropic Claude, Mistral AI, Cohere, Groq, Together AI, OpenRouter, Hugging Face
|
|
13
|
+
- Local model support: Ollama, LM Studio
|
|
14
|
+
- Custom HTTP endpoint support
|
|
15
|
+
- Unified API: generate(), chat(), generate_json(), generate_with_tools()
|
|
16
|
+
- Streaming support with real-time token streaming
|
|
17
|
+
- Full async/await support
|
|
18
|
+
- Fallback chains with automatic provider failover
|
|
19
|
+
- Retry logic with exponential backoff and jitter
|
|
20
|
+
- Timeout control per-request and per-provider
|
|
21
|
+
- Error normalization across providers
|
|
22
|
+
- Usage tracking with token counts and cost estimation
|
|
23
|
+
- PII redaction for sensitive data
|
|
24
|
+
- Provider registry for dynamic provider management
|
|
25
|
+
- Pydantic-based configuration and validation
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# LLMBridgeKit Environment Variables
|
|
2
|
+
|
|
3
|
+
## Provider API Keys
|
|
4
|
+
|
|
5
|
+
### OPENAI_API_KEY
|
|
6
|
+
- **Type:** String
|
|
7
|
+
- **Default:** None
|
|
8
|
+
- **Description:** API key for OpenAI provider
|
|
9
|
+
- **Required:** When using OpenAI or Azure OpenAI provider
|
|
10
|
+
|
|
11
|
+
### GEMINI_API_KEY
|
|
12
|
+
- **Type:** String
|
|
13
|
+
- **Default:** None
|
|
14
|
+
- **Description:** API key for Google Gemini provider
|
|
15
|
+
- **Required:** When using Gemini provider
|
|
16
|
+
|
|
17
|
+
### ANTHROPIC_API_KEY
|
|
18
|
+
- **Type:** String
|
|
19
|
+
- **Default:** None
|
|
20
|
+
- **Description:** API key for Anthropic Claude provider
|
|
21
|
+
- **Required:** When using Anthropic provider
|
|
22
|
+
|
|
23
|
+
### GROQ_API_KEY
|
|
24
|
+
- **Type:** String
|
|
25
|
+
- **Default:** None
|
|
26
|
+
- **Description:** API key for Groq provider
|
|
27
|
+
- **Required:** When using Groq provider
|
|
28
|
+
|
|
29
|
+
### MISTRAL_API_KEY
|
|
30
|
+
- **Type:** String
|
|
31
|
+
- **Default:** None
|
|
32
|
+
- **Description:** API key for Mistral AI provider
|
|
33
|
+
- **Required:** When using Mistral provider
|
|
34
|
+
|
|
35
|
+
### COHERE_API_KEY
|
|
36
|
+
- **Type:** String
|
|
37
|
+
- **Default:** None
|
|
38
|
+
- **Description:** API key for Cohere provider
|
|
39
|
+
- **Required:** When using Cohere provider
|
|
40
|
+
|
|
41
|
+
### TOGETHER_API_KEY
|
|
42
|
+
- **Type:** String
|
|
43
|
+
- **Default:** None
|
|
44
|
+
- **Description:** API key for Together AI provider
|
|
45
|
+
- **Required:** When using Together provider
|
|
46
|
+
|
|
47
|
+
### OPENROUTER_API_KEY
|
|
48
|
+
- **Type:** String
|
|
49
|
+
- **Default:** None
|
|
50
|
+
- **Description:** API key for OpenRouter provider
|
|
51
|
+
- **Required:** When using OpenRouter provider
|
|
52
|
+
|
|
53
|
+
### HUGGINGFACE_API_KEY
|
|
54
|
+
- **Type:** String
|
|
55
|
+
- **Default:** None
|
|
56
|
+
- **Description:** API key for Hugging Face Inference provider
|
|
57
|
+
- **Required:** When using Hugging Face provider
|
|
58
|
+
|
|
59
|
+
## Azure OpenAI
|
|
60
|
+
|
|
61
|
+
### AZURE_OPENAI_API_KEY
|
|
62
|
+
- **Type:** String
|
|
63
|
+
- **Default:** None
|
|
64
|
+
- **Description:** API key for Azure OpenAI
|
|
65
|
+
|
|
66
|
+
### AZURE_OPENAI_ENDPOINT
|
|
67
|
+
- **Type:** String
|
|
68
|
+
- **Default:** None
|
|
69
|
+
- **Description:** Azure OpenAI endpoint URL
|
|
70
|
+
|
|
71
|
+
### AZURE_OPENAI_API_VERSION
|
|
72
|
+
- **Type:** String
|
|
73
|
+
- **Default:** `2024-02-01`
|
|
74
|
+
- **Description:** Azure OpenAI API version
|
|
75
|
+
|
|
76
|
+
## Local Model Endpoints
|
|
77
|
+
|
|
78
|
+
### OLLAMA_BASE_URL
|
|
79
|
+
- **Type:** String
|
|
80
|
+
- **Default:** `http://localhost:11434`
|
|
81
|
+
- **Description:** Base URL for Ollama server
|
|
82
|
+
|
|
83
|
+
### LMSTUDIO_BASE_URL
|
|
84
|
+
- **Type:** String
|
|
85
|
+
- **Default:** `http://localhost:1234`
|
|
86
|
+
- **Description:** Base URL for LM Studio server
|
|
87
|
+
|
|
88
|
+
## Build-Time Variables
|
|
89
|
+
|
|
90
|
+
### LLMBRIDGEKIT_CYTHONIZE
|
|
91
|
+
- **Type:** String
|
|
92
|
+
- **Default:** unset or `0`
|
|
93
|
+
- **Description:** Enables Cython compilation for protected wheel builds
|
|
94
|
+
- **Accepted values:** `1` to enable, any other value to skip
|
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: llmbridgekit
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Universal Python LLM Provider Abstraction Library
|
|
5
|
+
Author-email: sreeyenan <sreeyenanek@gmail.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/sreeyenan/llmbridgekit
|
|
7
|
+
Project-URL: Documentation, https://github.com/sreeyenan/llmbridgekit#readme
|
|
8
|
+
Project-URL: Repository, https://github.com/sreeyenan/llmbridgekit
|
|
9
|
+
Project-URL: Issues, https://github.com/sreeyenan/llmbridgekit/issues
|
|
10
|
+
Keywords: llm,openai,gemini,anthropic,claude,gpt,ai,ml,nlp,chatgpt,language-model,provider-abstraction
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
Requires-Dist: pydantic<3.0,>=2.0
|
|
23
|
+
Provides-Extra: openai
|
|
24
|
+
Requires-Dist: openai>=1.0.0; extra == "openai"
|
|
25
|
+
Provides-Extra: gemini
|
|
26
|
+
Requires-Dist: google-genai>=0.1.0; extra == "gemini"
|
|
27
|
+
Provides-Extra: groq
|
|
28
|
+
Requires-Dist: groq>=0.4.0; extra == "groq"
|
|
29
|
+
Provides-Extra: anthropic
|
|
30
|
+
Requires-Dist: anthropic>=0.18.0; extra == "anthropic"
|
|
31
|
+
Provides-Extra: mistral
|
|
32
|
+
Requires-Dist: mistralai>=0.1.0; extra == "mistral"
|
|
33
|
+
Provides-Extra: cohere
|
|
34
|
+
Requires-Dist: cohere>=5.0.0; extra == "cohere"
|
|
35
|
+
Provides-Extra: local
|
|
36
|
+
Requires-Dist: httpx>=0.25.0; extra == "local"
|
|
37
|
+
Provides-Extra: yaml
|
|
38
|
+
Requires-Dist: pyyaml>=6.0; extra == "yaml"
|
|
39
|
+
Provides-Extra: validation
|
|
40
|
+
Requires-Dist: jsonschema>=4.19.0; extra == "validation"
|
|
41
|
+
Provides-Extra: http
|
|
42
|
+
Requires-Dist: httpx>=0.25.0; extra == "http"
|
|
43
|
+
Requires-Dist: requests>=2.31.0; extra == "http"
|
|
44
|
+
Provides-Extra: azure
|
|
45
|
+
Requires-Dist: llmbridgekit[openai]; extra == "azure"
|
|
46
|
+
Provides-Extra: ollama
|
|
47
|
+
Requires-Dist: llmbridgekit[local]; extra == "ollama"
|
|
48
|
+
Provides-Extra: lmstudio
|
|
49
|
+
Requires-Dist: llmbridgekit[local]; extra == "lmstudio"
|
|
50
|
+
Provides-Extra: openrouter
|
|
51
|
+
Requires-Dist: llmbridgekit[local]; extra == "openrouter"
|
|
52
|
+
Provides-Extra: huggingface
|
|
53
|
+
Requires-Dist: llmbridgekit[local]; extra == "huggingface"
|
|
54
|
+
Provides-Extra: together
|
|
55
|
+
Requires-Dist: llmbridgekit[local]; extra == "together"
|
|
56
|
+
Provides-Extra: cloud-providers
|
|
57
|
+
Requires-Dist: llmbridgekit[anthropic,cohere,gemini,groq,mistral,openai]; extra == "cloud-providers"
|
|
58
|
+
Provides-Extra: local-providers
|
|
59
|
+
Requires-Dist: llmbridgekit[lmstudio,ollama]; extra == "local-providers"
|
|
60
|
+
Provides-Extra: routers
|
|
61
|
+
Requires-Dist: llmbridgekit[huggingface,openrouter,together]; extra == "routers"
|
|
62
|
+
Provides-Extra: dev
|
|
63
|
+
Requires-Dist: pytest>=7.4.0; extra == "dev"
|
|
64
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
65
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
66
|
+
Requires-Dist: mypy>=1.6.0; extra == "dev"
|
|
67
|
+
Requires-Dist: black>=23.10.0; extra == "dev"
|
|
68
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
69
|
+
Provides-Extra: all
|
|
70
|
+
Requires-Dist: llmbridgekit[cloud-providers,dev,http,local-providers,routers,validation,yaml]; extra == "all"
|
|
71
|
+
|
|
72
|
+
# LLMBridgeKit
|
|
73
|
+
|
|
74
|
+
**Version:** 1.0.0
|
|
75
|
+
**Author:** [sreeyenan](https://github.com/sreeyenan)
|
|
76
|
+
**License:** MIT
|
|
77
|
+
**Python:** 3.10+
|
|
78
|
+
|
|
79
|
+
**Universal Python LLM Provider Abstraction Library**
|
|
80
|
+
|
|
81
|
+
A provider-agnostic Python library that lets any AI feature call multiple LLM providers through one consistent interface.
|
|
82
|
+
|
|
83
|
+
[](https://pypi.org/project/llmbridgekit/)
|
|
84
|
+
[](https://www.python.org/downloads/)
|
|
85
|
+
[](https://opensource.org/licenses/MIT)
|
|
86
|
+
|
|
87
|
+
## Features
|
|
88
|
+
|
|
89
|
+
### 🌐 Multi-Provider Support
|
|
90
|
+
- **Cloud Providers**: OpenAI, Azure OpenAI, Google Gemini, Anthropic Claude, Mistral AI, Cohere
|
|
91
|
+
- **Fast Inference**: Groq, Together AI
|
|
92
|
+
- **Model Routers**: OpenRouter, Hugging Face Inference Providers
|
|
93
|
+
- **Local Models**: Ollama, LM Studio
|
|
94
|
+
- **Custom**: Your own HTTP endpoint
|
|
95
|
+
|
|
96
|
+
### 🎯 Core Capabilities
|
|
97
|
+
- **Unified API**: Single interface for all providers
|
|
98
|
+
- **Text Generation**: Simple `.generate()` method
|
|
99
|
+
- **Chat**: Message-based `.chat()` method
|
|
100
|
+
- **Structured JSON**: `.generate_json()` with schema validation
|
|
101
|
+
- **Tool Calling**: `.generate_with_tools()` for function calling
|
|
102
|
+
- **Streaming**: Real-time token streaming
|
|
103
|
+
- **Async Support**: Full async/await support
|
|
104
|
+
|
|
105
|
+
### 🛡️ Reliability Features
|
|
106
|
+
- **Fallback Chains**: Automatic provider failover
|
|
107
|
+
- **Retry Logic**: Exponential backoff with jitter
|
|
108
|
+
- **Timeout Control**: Per-request and per-provider timeouts
|
|
109
|
+
- **Error Normalization**: Consistent error handling across providers
|
|
110
|
+
- **Rate Limiting**: Respect provider rate limits
|
|
111
|
+
|
|
112
|
+
### 📊 Observability
|
|
113
|
+
- **Usage Tracking**: Token counts and model usage
|
|
114
|
+
- **Cost Estimation**: Calculate API costs
|
|
115
|
+
- **Latency Metrics**: Track request duration
|
|
116
|
+
- **Audit Logging**: Request/response logging with redaction
|
|
117
|
+
- **Request IDs**: Distributed tracing support
|
|
118
|
+
|
|
119
|
+
### 🔒 Security
|
|
120
|
+
- **PII Redaction**: Mask sensitive data before sending
|
|
121
|
+
- **Secret Management**: Environment variable support
|
|
122
|
+
- **API Key Rotation**: Hot-reload credentials
|
|
123
|
+
|
|
124
|
+
## Installation
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# Core installation
|
|
128
|
+
pip install llmbridgekit
|
|
129
|
+
|
|
130
|
+
# With specific providers
|
|
131
|
+
pip install llmbridgekit[openai]
|
|
132
|
+
pip install llmbridgekit[gemini]
|
|
133
|
+
pip install llmbridgekit[anthropic]
|
|
134
|
+
|
|
135
|
+
# With multiple providers
|
|
136
|
+
pip install llmbridgekit[openai,gemini,groq]
|
|
137
|
+
|
|
138
|
+
# Local model support
|
|
139
|
+
pip install llmbridgekit[local]
|
|
140
|
+
|
|
141
|
+
# Everything
|
|
142
|
+
pip install llmbridgekit[all]
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Quick Start
|
|
146
|
+
|
|
147
|
+
### Basic Text Generation
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
from llmbridgekit import LLMClient
|
|
151
|
+
|
|
152
|
+
client = LLMClient(provider="gemini")
|
|
153
|
+
|
|
154
|
+
response = client.generate(
|
|
155
|
+
prompt="Explain what a materialized view is in ClickHouse."
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
print(response.text)
|
|
159
|
+
print(f"Tokens: {response.usage['total_tokens']}")
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Chat with Messages
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
response = client.chat(
|
|
166
|
+
messages=[
|
|
167
|
+
{"role": "system", "content": "You are a data analytics assistant."},
|
|
168
|
+
{"role": "user", "content": "Show revenue by region."}
|
|
169
|
+
],
|
|
170
|
+
provider="openai",
|
|
171
|
+
model="gpt-4o"
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
print(response.text)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Structured JSON Output
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
schema = {
|
|
181
|
+
"type": "object",
|
|
182
|
+
"properties": {
|
|
183
|
+
"intent": {
|
|
184
|
+
"type": "string",
|
|
185
|
+
"enum": ["query", "chart", "dashboard", "report"]
|
|
186
|
+
},
|
|
187
|
+
"confidence": {"type": "number", "minimum": 0, "maximum": 1},
|
|
188
|
+
"entities": {
|
|
189
|
+
"type": "array",
|
|
190
|
+
"items": {"type": "string"}
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
"required": ["intent", "confidence"]
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
response = client.generate_json(
|
|
197
|
+
prompt="User asks: 'Show me sales by region for last quarter'",
|
|
198
|
+
schema=schema
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
print(response.json_data)
|
|
202
|
+
# {'intent': 'query', 'confidence': 0.95, 'entities': ['sales', 'region', 'last quarter']}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Streaming
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
for chunk in client.stream(
|
|
209
|
+
prompt="Write a detailed analysis of Q4 performance.",
|
|
210
|
+
provider="anthropic"
|
|
211
|
+
):
|
|
212
|
+
print(chunk.text, end="", flush=True)
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Fallback Chain
|
|
216
|
+
|
|
217
|
+
```python
|
|
218
|
+
response = client.generate(
|
|
219
|
+
prompt="Generate a SQL query for revenue by category.",
|
|
220
|
+
fallback_chain=[
|
|
221
|
+
{"provider": "gemini", "model": "gemini-2.0-flash-exp"},
|
|
222
|
+
{"provider": "groq", "model": "llama-3.3-70b-versatile"},
|
|
223
|
+
{"provider": "ollama", "model": "qwen2.5:3b"}
|
|
224
|
+
]
|
|
225
|
+
)
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Tool Calling
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
tools = [
|
|
232
|
+
{
|
|
233
|
+
"name": "get_weather",
|
|
234
|
+
"description": "Get current weather for a location",
|
|
235
|
+
"parameters": {
|
|
236
|
+
"type": "object",
|
|
237
|
+
"properties": {
|
|
238
|
+
"location": {"type": "string"}
|
|
239
|
+
},
|
|
240
|
+
"required": ["location"]
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
]
|
|
244
|
+
|
|
245
|
+
response = client.generate_with_tools(
|
|
246
|
+
prompt="What's the weather in San Francisco?",
|
|
247
|
+
tools=tools,
|
|
248
|
+
provider="openai"
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
if response.tool_calls:
|
|
252
|
+
for tool_call in response.tool_calls:
|
|
253
|
+
print(f"Tool: {tool_call['name']}")
|
|
254
|
+
print(f"Args: {tool_call['arguments']}")
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Configuration
|
|
258
|
+
|
|
259
|
+
### YAML Configuration
|
|
260
|
+
|
|
261
|
+
```yaml
|
|
262
|
+
# config.yaml
|
|
263
|
+
default_provider: gemini
|
|
264
|
+
default_timeout: 60
|
|
265
|
+
default_retries: 2
|
|
266
|
+
|
|
267
|
+
providers:
|
|
268
|
+
openai:
|
|
269
|
+
api_key_env: OPENAI_API_KEY
|
|
270
|
+
model: gpt-4o
|
|
271
|
+
temperature: 0
|
|
272
|
+
max_tokens: 1000
|
|
273
|
+
|
|
274
|
+
gemini:
|
|
275
|
+
api_key_env: GEMINI_API_KEY
|
|
276
|
+
model: gemini-2.0-flash-exp
|
|
277
|
+
temperature: 0
|
|
278
|
+
|
|
279
|
+
ollama:
|
|
280
|
+
base_url: http://localhost:11434
|
|
281
|
+
model: qwen2.5:3b
|
|
282
|
+
temperature: 0
|
|
283
|
+
|
|
284
|
+
fallback_chains:
|
|
285
|
+
default:
|
|
286
|
+
- provider: gemini
|
|
287
|
+
model: gemini-2.0-flash-exp
|
|
288
|
+
- provider: groq
|
|
289
|
+
model: llama-3.3-70b-versatile
|
|
290
|
+
|
|
291
|
+
tasks:
|
|
292
|
+
classification:
|
|
293
|
+
provider: groq
|
|
294
|
+
model: llama-3.3-70b-versatile
|
|
295
|
+
temperature: 0
|
|
296
|
+
max_tokens: 500
|
|
297
|
+
|
|
298
|
+
text_to_sql:
|
|
299
|
+
provider: gemini
|
|
300
|
+
model: gemini-2.0-flash-exp
|
|
301
|
+
temperature: 0
|
|
302
|
+
fallback_chain: default
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Load configuration:
|
|
306
|
+
|
|
307
|
+
```python
|
|
308
|
+
from llmbridgekit import LLMClient
|
|
309
|
+
|
|
310
|
+
client = LLMClient.from_yaml("config.yaml")
|
|
311
|
+
|
|
312
|
+
# Use task-based routing
|
|
313
|
+
response = client.run_task(
|
|
314
|
+
task="text_to_sql",
|
|
315
|
+
prompt="Show me revenue by product category"
|
|
316
|
+
)
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
## Supported Providers
|
|
320
|
+
|
|
321
|
+
| Provider | Structured Output | Tool Calling | Streaming | Local | Status |
|
|
322
|
+
|----------|:-----------------:|:------------:|:---------:|:-----:|--------|
|
|
323
|
+
| OpenAI | ✅ | ✅ | ✅ | ❌ | Stable |
|
|
324
|
+
| Azure OpenAI | ✅ | ✅ | ✅ | ❌ | Stable |
|
|
325
|
+
| Google Gemini | ✅ | ✅ | ✅ | ❌ | Stable |
|
|
326
|
+
| Anthropic Claude | ✅ | ✅ | ✅ | ❌ | Stable |
|
|
327
|
+
| Groq | ✅ | ✅ | ✅ | ❌ | Stable |
|
|
328
|
+
| Mistral AI | ✅ | ✅ | ✅ | ❌ | Stable |
|
|
329
|
+
| Cohere | ✅ | ✅ | ✅ | ❌ | Stable |
|
|
330
|
+
| Ollama | ✅ | ✅ | ✅ | ✅ | Stable |
|
|
331
|
+
| LM Studio | ✅ | ✅ | ✅ | ✅ | Stable |
|
|
332
|
+
| OpenRouter | ✅ | ✅ | ✅ | ❌ | Stable |
|
|
333
|
+
| Hugging Face | ✅ | ✅ | ✅ | ❌ | Stable |
|
|
334
|
+
| Together AI | ✅ | ✅ | ✅ | ❌ | Stable |
|
|
335
|
+
| Custom HTTP | ✅ | ✅ | ✅ | ⚠️ | Stable |
|
|
336
|
+
|
|
337
|
+
## Use Cases
|
|
338
|
+
|
|
339
|
+
### NLQ (Natural Language Query)
|
|
340
|
+
```python
|
|
341
|
+
# Context resolution
|
|
342
|
+
response = client.generate_json(
|
|
343
|
+
prompt=context_resolver_prompt,
|
|
344
|
+
schema=context_resolution_schema,
|
|
345
|
+
provider="ollama", # Local fallback
|
|
346
|
+
model="qwen2.5:3b"
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
# Text-to-SQL generation
|
|
350
|
+
response = client.generate(
|
|
351
|
+
prompt=sql_generation_prompt,
|
|
352
|
+
provider="gemini",
|
|
353
|
+
fallback_chain="default"
|
|
354
|
+
)
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### RAG (Retrieval Augmented Generation)
|
|
358
|
+
```python
|
|
359
|
+
# Generate embeddings
|
|
360
|
+
embeddings = client.embed(
|
|
361
|
+
texts=["chunk1", "chunk2", "chunk3"],
|
|
362
|
+
provider="openai"
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
# Generate answer with context
|
|
366
|
+
response = client.chat(
|
|
367
|
+
messages=[
|
|
368
|
+
{"role": "system", "content": "You are a helpful assistant."},
|
|
369
|
+
{"role": "user", "content": f"Context: {context}\n\nQuestion: {question}"}
|
|
370
|
+
]
|
|
371
|
+
)
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Chart/Dashboard Generation
|
|
375
|
+
```python
|
|
376
|
+
response = client.generate_json(
|
|
377
|
+
prompt=f"Generate chart config for: {user_request}",
|
|
378
|
+
schema=chart_config_schema,
|
|
379
|
+
provider="openai",
|
|
380
|
+
model="gpt-4o"
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
chart_config = response.json_data
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Document Q&A
|
|
387
|
+
```python
|
|
388
|
+
response = client.chat(
|
|
389
|
+
messages=[
|
|
390
|
+
{"role": "system", "content": "Answer based on the document."},
|
|
391
|
+
{"role": "user", "content": f"Document: {document}\n\nQuestion: {question}"}
|
|
392
|
+
],
|
|
393
|
+
provider="anthropic",
|
|
394
|
+
model="claude-opus-4"
|
|
395
|
+
)
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
## Advanced Features
|
|
399
|
+
|
|
400
|
+
### Async Support
|
|
401
|
+
|
|
402
|
+
```python
|
|
403
|
+
import asyncio
|
|
404
|
+
from llmbridgekit import LLMClient
|
|
405
|
+
|
|
406
|
+
async def main():
|
|
407
|
+
client = LLMClient(provider="gemini")
|
|
408
|
+
|
|
409
|
+
response = await client.agenerate(
|
|
410
|
+
prompt="Explain async/await in Python"
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
print(response.text)
|
|
414
|
+
|
|
415
|
+
asyncio.run(main())
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Cost Tracking
|
|
419
|
+
|
|
420
|
+
```python
|
|
421
|
+
response = client.generate(
|
|
422
|
+
prompt="Analyze sales data",
|
|
423
|
+
provider="openai",
|
|
424
|
+
model="gpt-4o"
|
|
425
|
+
)
|
|
426
|
+
|
|
427
|
+
print(f"Cost: ${response.cost['total_cost']:.4f}")
|
|
428
|
+
print(f"Input tokens: {response.usage['prompt_tokens']}")
|
|
429
|
+
print(f"Output tokens: {response.usage['completion_tokens']}")
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Redaction
|
|
433
|
+
|
|
434
|
+
```python
|
|
435
|
+
from llmbridgekit import LLMClient, RedactionConfig
|
|
436
|
+
|
|
437
|
+
client = LLMClient(
|
|
438
|
+
provider="openai",
|
|
439
|
+
redaction=RedactionConfig(
|
|
440
|
+
mask_email=True,
|
|
441
|
+
mask_phone=True,
|
|
442
|
+
mask_api_keys=True,
|
|
443
|
+
custom_patterns=[
|
|
444
|
+
r'\b\d{3}-\d{2}-\d{4}\b' # SSN
|
|
445
|
+
]
|
|
446
|
+
)
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
response = client.generate(
|
|
450
|
+
prompt="User email: john@example.com, phone: 555-1234"
|
|
451
|
+
)
|
|
452
|
+
# Prompt sent: "User email: [EMAIL_REDACTED], phone: [PHONE_REDACTED]"
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### Custom Provider
|
|
456
|
+
|
|
457
|
+
```python
|
|
458
|
+
from llmbridgekit.providers import BaseProvider, ProviderFeatures
|
|
459
|
+
from llmbridgekit import provider_registry
|
|
460
|
+
|
|
461
|
+
class MyCustomProvider(BaseProvider):
|
|
462
|
+
name = "my_custom"
|
|
463
|
+
features = ProviderFeatures(
|
|
464
|
+
chat=True,
|
|
465
|
+
structured_outputs=True,
|
|
466
|
+
streaming=True
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
def generate(self, prompt, config):
|
|
470
|
+
# Your implementation
|
|
471
|
+
response = self._call_api(prompt, config)
|
|
472
|
+
return self._parse_response(response)
|
|
473
|
+
|
|
474
|
+
# Register
|
|
475
|
+
provider_registry.register("my_custom", MyCustomProvider)
|
|
476
|
+
|
|
477
|
+
# Use
|
|
478
|
+
client = LLMClient(provider="my_custom")
|
|
479
|
+
response = client.generate("Hello!")
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
## Testing
|
|
483
|
+
|
|
484
|
+
```bash
|
|
485
|
+
# Install dev dependencies
|
|
486
|
+
pip install llm-gateway[dev]
|
|
487
|
+
|
|
488
|
+
# Run tests
|
|
489
|
+
pytest
|
|
490
|
+
|
|
491
|
+
# Run with coverage
|
|
492
|
+
pytest --cov=llmbridgekit --cov-report=html
|
|
493
|
+
|
|
494
|
+
# Run specific provider tests
|
|
495
|
+
pytest tests/providers/test_openai_provider.py -v
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
## Documentation
|
|
499
|
+
|
|
500
|
+
- **[User Manual](llmbridgekit_USER_MANUAL.md)** - Complete usage guide
|
|
501
|
+
- **[Changelog](CHANGELOG.md)** - Version history
|
|
502
|
+
- **[Environment Variables](ENVIRONMENT_VARIABLES.md)** - Configuration reference
|
|
503
|
+
- **[Examples](examples/)** - Code examples for common use cases
|
|
504
|
+
|
|
505
|
+
## Architecture
|
|
506
|
+
|
|
507
|
+
```
|
|
508
|
+
Application Layer
|
|
509
|
+
↓
|
|
510
|
+
LLMClient (llmbridgekit/client.py)
|
|
511
|
+
↓
|
|
512
|
+
Task Router / Fallback Chain
|
|
513
|
+
↓
|
|
514
|
+
Provider Registry
|
|
515
|
+
↓
|
|
516
|
+
BaseProvider
|
|
517
|
+
↓
|
|
518
|
+
OpenAI | Gemini | Anthropic | Groq | ... | Custom HTTP
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
## License
|
|
522
|
+
|
|
523
|
+
MIT License - see LICENSE file for details.
|
|
524
|
+
|
|
525
|
+
## Support
|
|
526
|
+
|
|
527
|
+
- **Issues**: https://github.com/sreeyenan/llmbridgekit/issues
|
|
528
|
+
- **Discussions**: https://github.com/analytic-ai/llm-gateway/discussions
|
|
529
|
+
- **Documentation**: https://llm-gateway.readthedocs.io
|