inference-proxy 3.2.2__tar.gz → 3.3.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.
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/PKG-INFO +73 -8
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/README.md +68 -4
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/__main__.py +0 -1
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/app.py +0 -1
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/base_types.py +0 -1
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/bootstrap.py +5 -2
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/config.py +4 -0
- inference_proxy-3.3.0/lm_proxy/config_loaders/json.py +11 -0
- inference_proxy-3.3.0/lm_proxy/config_loaders/toml.py +11 -0
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/core.py +29 -0
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/pyproject.toml +3 -3
- inference_proxy-3.2.2/lm_proxy/config_loaders/json.py +0 -9
- inference_proxy-3.2.2/lm_proxy/config_loaders/toml.py +0 -9
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/LICENSE +0 -0
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/__init__.py +0 -0
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/api_key_check/__init__.py +0 -0
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/api_key_check/allow_all.py +0 -0
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/api_key_check/in_config.py +0 -0
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/api_key_check/with_request.py +0 -0
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/config_loaders/__init__.py +0 -0
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/config_loaders/python.py +0 -0
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/config_loaders/yaml.py +0 -0
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/errors.py +0 -0
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/handlers/__init__.py +0 -0
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/handlers/forward_http_headers.py +0 -0
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/handlers/rate_limiter.py +0 -0
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/loggers.py +0 -0
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/models_endpoint.py +0 -0
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/strategies/__init__.py +0 -0
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/strategies/fallback.py +0 -0
- {inference_proxy-3.2.2 → inference_proxy-3.3.0}/lm_proxy/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: inference-proxy
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.3.0
|
|
4
4
|
Summary: Inference Proxy is an OpenAI-compatible http proxy server for inferencing various LLMs capable of working with Google, Anthropic, OpenAI APIs, local PyTorch inference, etc.
|
|
5
5
|
License: MIT License
|
|
6
6
|
|
|
@@ -23,6 +23,7 @@ License: MIT License
|
|
|
23
23
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
24
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
25
25
|
SOFTWARE.
|
|
26
|
+
License-File: LICENSE
|
|
26
27
|
Keywords: llm,large language models,ai,gpt,openai,proxy,http,proxy-server,llm gateway,openai,anthropic,google genai
|
|
27
28
|
Author: Vitalii Stepanenko
|
|
28
29
|
Author-email: mail@vitaliy.in
|
|
@@ -45,10 +46,10 @@ Provides-Extra: all
|
|
|
45
46
|
Provides-Extra: anthropic
|
|
46
47
|
Provides-Extra: google
|
|
47
48
|
Provides-Extra: test
|
|
48
|
-
Requires-Dist: ai-microcore (>=
|
|
49
|
+
Requires-Dist: ai-microcore (>=6.6.1,<7)
|
|
49
50
|
Requires-Dist: anthropic (>=0.77,<1) ; extra == "all"
|
|
50
51
|
Requires-Dist: anthropic (>=0.77,<1) ; extra == "anthropic"
|
|
51
|
-
Requires-Dist: fastapi (>=0.
|
|
52
|
+
Requires-Dist: fastapi (>=0.136.3,<1)
|
|
52
53
|
Requires-Dist: google-genai (>=1.62.0,<2) ; extra == "all"
|
|
53
54
|
Requires-Dist: google-genai (>=1.62.0,<2) ; extra == "google"
|
|
54
55
|
Requires-Dist: pydantic (>=2.12.5,<2.13.0)
|
|
@@ -71,7 +72,7 @@ Description-Content-Type: text/markdown
|
|
|
71
72
|
<a href="https://pypi.org/project/lm-proxy/"><img src="https://img.shields.io/pypi/v/lm-proxy?color=blue" alt="PyPI"></a>
|
|
72
73
|
<a href="https://github.com/Nayjest/lm-proxy/actions/workflows/tests.yml"><img src="https://github.com/Nayjest/lm-proxy/actions/workflows/tests.yml/badge.svg" alt="Tests"></a>
|
|
73
74
|
<a href="https://github.com/Nayjest/lm-proxy/actions/workflows/code-style.yml"><img src="https://github.com/Nayjest/lm-proxy/actions/workflows/code-style.yml/badge.svg" alt="Code Style"></a>
|
|
74
|
-
<img src="https://raw.githubusercontent.com/Nayjest/lm-proxy/
|
|
75
|
+
<img src="https://raw.githubusercontent.com/Nayjest/lm-proxy/coverage-badge/coverage.svg" alt="Code Coverage">
|
|
75
76
|
<a href="https://www.bestpractices.dev/projects/11364"><img src="https://www.bestpractices.dev/projects/11364/badge"></a>
|
|
76
77
|
<br>
|
|
77
78
|
<a href="https://github.com/vshymanskyy/StandWithUkraine/blob/main/README.md"><img src="https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/refs/heads/main/badges/StandWithUkraine.svg" alt="Stand With Ukraine"></a>
|
|
@@ -91,6 +92,7 @@ It works as a drop-in replacement for OpenAI's API, allowing you to switch betwe
|
|
|
91
92
|
- [Getting Started](#-getting-started)
|
|
92
93
|
- [Installation](#installation)
|
|
93
94
|
- [Quick Start](#quick-start)
|
|
95
|
+
- [Run with Docker](#run-with-docker)
|
|
94
96
|
- [Configuration](#-configuration)
|
|
95
97
|
- [Basic Structure](#basic-structure)
|
|
96
98
|
- [Environment Variables](#environment-variables)
|
|
@@ -114,6 +116,8 @@ It works as a drop-in replacement for OpenAI's API, allowing you to switch betwe
|
|
|
114
116
|
- [Guides & Reference](#-guides--reference)
|
|
115
117
|
- [Known Limitations](#-known-limitations)
|
|
116
118
|
- [Debugging](#-debugging)
|
|
119
|
+
- [Debugging Mode](#debugging-mode)
|
|
120
|
+
- [Printing LLM Requests and Responses](#printing-llm-requests-and-responses)
|
|
117
121
|
- [Contributing](#-contributing)
|
|
118
122
|
- [License](#-license)
|
|
119
123
|
|
|
@@ -210,6 +214,39 @@ completion = client.chat.completions.create(
|
|
|
210
214
|
)
|
|
211
215
|
```
|
|
212
216
|
|
|
217
|
+
### Run with Docker<a id="run-with-docker"></a>
|
|
218
|
+
|
|
219
|
+
Official images are published to GitHub Container Registry on every release
|
|
220
|
+
(`latest`, `3`, `3.2`, `3.2.2`, …; `edge` tracks the `main` branch).
|
|
221
|
+
They include the Anthropic and Google connectors and YAML config support out of the box.
|
|
222
|
+
|
|
223
|
+
Mount your `config.toml` and provide API keys via an `.env` file:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
docker run -d --name inference-proxy \
|
|
227
|
+
-p 8000:8000 \
|
|
228
|
+
-v ./config.toml:/app/config.toml:ro \
|
|
229
|
+
--env-file .env \
|
|
230
|
+
lmproxy/lmproxy:edge
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Any value referenced in the config as `env:<VAR_NAME>` (upstream provider keys,
|
|
234
|
+
client API keys, etc.) can be defined in the `.env` file:
|
|
235
|
+
|
|
236
|
+
```ini
|
|
237
|
+
OPENAI_API_KEY=sk-...
|
|
238
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
See [examples/docker-compose.yml](examples/docker-compose.yml) for a Docker Compose setup.
|
|
242
|
+
|
|
243
|
+
To bake additional Python packages into the image (e.g. for
|
|
244
|
+
[database log storage](#database-connector)), build it with the `EXTRA_PIP_PACKAGES` argument:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
docker build --build-arg EXTRA_PIP_PACKAGES="inference-proxy-db-connector sqlalchemy psycopg2-binary" -t inference-proxy .
|
|
248
|
+
```
|
|
249
|
+
|
|
213
250
|
|
|
214
251
|
## 📝 Configuration<a id="-configuration"></a>
|
|
215
252
|
|
|
@@ -220,6 +257,7 @@ Inference Proxy is configured through a TOML/YAML/JSON/Python file that specifie
|
|
|
220
257
|
host = "0.0.0.0" # Interface to bind to
|
|
221
258
|
port = 8000 # Port to listen on
|
|
222
259
|
dev_autoreload = false # Enable for development
|
|
260
|
+
print_stream = false # Print LLM requests / responses to stdout, see "Debugging"
|
|
223
261
|
|
|
224
262
|
# API key validation function (optional)
|
|
225
263
|
api_key_check = "lm_proxy.api_key_check.check_api_key_in_config"
|
|
@@ -258,7 +296,7 @@ api_keys = [
|
|
|
258
296
|
[[loggers]]
|
|
259
297
|
class = 'lm_proxy.loggers.BaseLogger'
|
|
260
298
|
[loggers.log_writer]
|
|
261
|
-
class = 'lm_proxy.loggers.
|
|
299
|
+
class = 'lm_proxy.loggers.JsonLogWriter'
|
|
262
300
|
file_name = 'storage/json.log'
|
|
263
301
|
[loggers.entry_transformer]
|
|
264
302
|
class = 'lm_proxy.loggers.LogEntryTransformer'
|
|
@@ -714,6 +752,7 @@ prefix = "SECURITY_AUDIT"
|
|
|
714
752
|
For more detailed information, check out these articles:
|
|
715
753
|
- [HTTP Header Management](https://github.com/Nayjest/lm-proxy/blob/main/doc/http_headers.md)
|
|
716
754
|
- [Configuring fallbacks](https://github.com/Nayjest/lm-proxy/blob/main/doc/fallback.md)
|
|
755
|
+
- [HTTPS / TLS Setup](https://github.com/Nayjest/lm-proxy/blob/main/doc/https.md)
|
|
717
756
|
|
|
718
757
|
|
|
719
758
|
## 🚧 Known Limitations<a id="-known-limitations"></a>
|
|
@@ -725,7 +764,9 @@ For more detailed information, check out these articles:
|
|
|
725
764
|
|
|
726
765
|
## 🔍 Debugging<a id="-debugging"></a>
|
|
727
766
|
|
|
728
|
-
###
|
|
767
|
+
### Debugging Mode<a id="debugging-mode"></a>
|
|
768
|
+
|
|
769
|
+
#### Overview
|
|
729
770
|
When **debugging mode** is enabled,
|
|
730
771
|
Inference Proxy provides detailed logging information to help diagnose issues:
|
|
731
772
|
- Stack traces for exceptions are shown in the console
|
|
@@ -734,7 +775,7 @@ Inference Proxy provides detailed logging information to help diagnose issues:
|
|
|
734
775
|
> **Warning** ⚠️
|
|
735
776
|
> Never enable debugging mode in production environments, as it may expose sensitive information to the application logs.
|
|
736
777
|
|
|
737
|
-
|
|
778
|
+
#### Enabling Debugging Mode
|
|
738
779
|
To enable debugging, set the `LM_PROXY_DEBUG` environment variable to a truthy value (e.g., "1", "true", "yes").
|
|
739
780
|
> **Tip** 💡
|
|
740
781
|
> Environment variables can also be defined in a `.env` file.
|
|
@@ -746,6 +787,30 @@ Alternatively, you can enable or disable debugging via the command-line argument
|
|
|
746
787
|
> **Note** ℹ️
|
|
747
788
|
> CLI arguments override environment variable settings.
|
|
748
789
|
|
|
790
|
+
### Printing LLM Requests and Responses<a id="printing-llm-requests-and-responses"></a>
|
|
791
|
+
|
|
792
|
+
The `print_stream` configuration option makes Inference Proxy print every LLM request
|
|
793
|
+
and response to stdout, with the response appearing token by token as it is generated:
|
|
794
|
+
|
|
795
|
+
```toml
|
|
796
|
+
print_stream = true
|
|
797
|
+
```
|
|
798
|
+
|
|
799
|
+
```text
|
|
800
|
+
Requesting LLM gpt-5:
|
|
801
|
+
[User]:
|
|
802
|
+
What is the capital of France?
|
|
803
|
+
LLM Response:
|
|
804
|
+
The capital of France is Paris.
|
|
805
|
+
```
|
|
806
|
+
|
|
807
|
+
This works for both streaming and non-streaming client requests.
|
|
808
|
+
|
|
809
|
+
> **Warning** ⚠️
|
|
810
|
+
> Intended for local development and troubleshooting only.
|
|
811
|
+
> Prompts and generated content are written to the console in plain text,
|
|
812
|
+
> and the output of requests processed in parallel is interleaved.
|
|
813
|
+
|
|
749
814
|
|
|
750
815
|
## 🤝 Contributing<a id="-contributing"></a>
|
|
751
816
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<a href="https://pypi.org/project/lm-proxy/"><img src="https://img.shields.io/pypi/v/lm-proxy?color=blue" alt="PyPI"></a>
|
|
7
7
|
<a href="https://github.com/Nayjest/lm-proxy/actions/workflows/tests.yml"><img src="https://github.com/Nayjest/lm-proxy/actions/workflows/tests.yml/badge.svg" alt="Tests"></a>
|
|
8
8
|
<a href="https://github.com/Nayjest/lm-proxy/actions/workflows/code-style.yml"><img src="https://github.com/Nayjest/lm-proxy/actions/workflows/code-style.yml/badge.svg" alt="Code Style"></a>
|
|
9
|
-
<img src="https://raw.githubusercontent.com/Nayjest/lm-proxy/
|
|
9
|
+
<img src="https://raw.githubusercontent.com/Nayjest/lm-proxy/coverage-badge/coverage.svg" alt="Code Coverage">
|
|
10
10
|
<a href="https://www.bestpractices.dev/projects/11364"><img src="https://www.bestpractices.dev/projects/11364/badge"></a>
|
|
11
11
|
<br>
|
|
12
12
|
<a href="https://github.com/vshymanskyy/StandWithUkraine/blob/main/README.md"><img src="https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/refs/heads/main/badges/StandWithUkraine.svg" alt="Stand With Ukraine"></a>
|
|
@@ -26,6 +26,7 @@ It works as a drop-in replacement for OpenAI's API, allowing you to switch betwe
|
|
|
26
26
|
- [Getting Started](#-getting-started)
|
|
27
27
|
- [Installation](#installation)
|
|
28
28
|
- [Quick Start](#quick-start)
|
|
29
|
+
- [Run with Docker](#run-with-docker)
|
|
29
30
|
- [Configuration](#-configuration)
|
|
30
31
|
- [Basic Structure](#basic-structure)
|
|
31
32
|
- [Environment Variables](#environment-variables)
|
|
@@ -49,6 +50,8 @@ It works as a drop-in replacement for OpenAI's API, allowing you to switch betwe
|
|
|
49
50
|
- [Guides & Reference](#-guides--reference)
|
|
50
51
|
- [Known Limitations](#-known-limitations)
|
|
51
52
|
- [Debugging](#-debugging)
|
|
53
|
+
- [Debugging Mode](#debugging-mode)
|
|
54
|
+
- [Printing LLM Requests and Responses](#printing-llm-requests-and-responses)
|
|
52
55
|
- [Contributing](#-contributing)
|
|
53
56
|
- [License](#-license)
|
|
54
57
|
|
|
@@ -145,6 +148,39 @@ completion = client.chat.completions.create(
|
|
|
145
148
|
)
|
|
146
149
|
```
|
|
147
150
|
|
|
151
|
+
### Run with Docker<a id="run-with-docker"></a>
|
|
152
|
+
|
|
153
|
+
Official images are published to GitHub Container Registry on every release
|
|
154
|
+
(`latest`, `3`, `3.2`, `3.2.2`, …; `edge` tracks the `main` branch).
|
|
155
|
+
They include the Anthropic and Google connectors and YAML config support out of the box.
|
|
156
|
+
|
|
157
|
+
Mount your `config.toml` and provide API keys via an `.env` file:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
docker run -d --name inference-proxy \
|
|
161
|
+
-p 8000:8000 \
|
|
162
|
+
-v ./config.toml:/app/config.toml:ro \
|
|
163
|
+
--env-file .env \
|
|
164
|
+
lmproxy/lmproxy:edge
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Any value referenced in the config as `env:<VAR_NAME>` (upstream provider keys,
|
|
168
|
+
client API keys, etc.) can be defined in the `.env` file:
|
|
169
|
+
|
|
170
|
+
```ini
|
|
171
|
+
OPENAI_API_KEY=sk-...
|
|
172
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
See [examples/docker-compose.yml](examples/docker-compose.yml) for a Docker Compose setup.
|
|
176
|
+
|
|
177
|
+
To bake additional Python packages into the image (e.g. for
|
|
178
|
+
[database log storage](#database-connector)), build it with the `EXTRA_PIP_PACKAGES` argument:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
docker build --build-arg EXTRA_PIP_PACKAGES="inference-proxy-db-connector sqlalchemy psycopg2-binary" -t inference-proxy .
|
|
182
|
+
```
|
|
183
|
+
|
|
148
184
|
|
|
149
185
|
## 📝 Configuration<a id="-configuration"></a>
|
|
150
186
|
|
|
@@ -155,6 +191,7 @@ Inference Proxy is configured through a TOML/YAML/JSON/Python file that specifie
|
|
|
155
191
|
host = "0.0.0.0" # Interface to bind to
|
|
156
192
|
port = 8000 # Port to listen on
|
|
157
193
|
dev_autoreload = false # Enable for development
|
|
194
|
+
print_stream = false # Print LLM requests / responses to stdout, see "Debugging"
|
|
158
195
|
|
|
159
196
|
# API key validation function (optional)
|
|
160
197
|
api_key_check = "lm_proxy.api_key_check.check_api_key_in_config"
|
|
@@ -193,7 +230,7 @@ api_keys = [
|
|
|
193
230
|
[[loggers]]
|
|
194
231
|
class = 'lm_proxy.loggers.BaseLogger'
|
|
195
232
|
[loggers.log_writer]
|
|
196
|
-
class = 'lm_proxy.loggers.
|
|
233
|
+
class = 'lm_proxy.loggers.JsonLogWriter'
|
|
197
234
|
file_name = 'storage/json.log'
|
|
198
235
|
[loggers.entry_transformer]
|
|
199
236
|
class = 'lm_proxy.loggers.LogEntryTransformer'
|
|
@@ -649,6 +686,7 @@ prefix = "SECURITY_AUDIT"
|
|
|
649
686
|
For more detailed information, check out these articles:
|
|
650
687
|
- [HTTP Header Management](https://github.com/Nayjest/lm-proxy/blob/main/doc/http_headers.md)
|
|
651
688
|
- [Configuring fallbacks](https://github.com/Nayjest/lm-proxy/blob/main/doc/fallback.md)
|
|
689
|
+
- [HTTPS / TLS Setup](https://github.com/Nayjest/lm-proxy/blob/main/doc/https.md)
|
|
652
690
|
|
|
653
691
|
|
|
654
692
|
## 🚧 Known Limitations<a id="-known-limitations"></a>
|
|
@@ -660,7 +698,9 @@ For more detailed information, check out these articles:
|
|
|
660
698
|
|
|
661
699
|
## 🔍 Debugging<a id="-debugging"></a>
|
|
662
700
|
|
|
663
|
-
###
|
|
701
|
+
### Debugging Mode<a id="debugging-mode"></a>
|
|
702
|
+
|
|
703
|
+
#### Overview
|
|
664
704
|
When **debugging mode** is enabled,
|
|
665
705
|
Inference Proxy provides detailed logging information to help diagnose issues:
|
|
666
706
|
- Stack traces for exceptions are shown in the console
|
|
@@ -669,7 +709,7 @@ Inference Proxy provides detailed logging information to help diagnose issues:
|
|
|
669
709
|
> **Warning** ⚠️
|
|
670
710
|
> Never enable debugging mode in production environments, as it may expose sensitive information to the application logs.
|
|
671
711
|
|
|
672
|
-
|
|
712
|
+
#### Enabling Debugging Mode
|
|
673
713
|
To enable debugging, set the `LM_PROXY_DEBUG` environment variable to a truthy value (e.g., "1", "true", "yes").
|
|
674
714
|
> **Tip** 💡
|
|
675
715
|
> Environment variables can also be defined in a `.env` file.
|
|
@@ -681,6 +721,30 @@ Alternatively, you can enable or disable debugging via the command-line argument
|
|
|
681
721
|
> **Note** ℹ️
|
|
682
722
|
> CLI arguments override environment variable settings.
|
|
683
723
|
|
|
724
|
+
### Printing LLM Requests and Responses<a id="printing-llm-requests-and-responses"></a>
|
|
725
|
+
|
|
726
|
+
The `print_stream` configuration option makes Inference Proxy print every LLM request
|
|
727
|
+
and response to stdout, with the response appearing token by token as it is generated:
|
|
728
|
+
|
|
729
|
+
```toml
|
|
730
|
+
print_stream = true
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
```text
|
|
734
|
+
Requesting LLM gpt-5:
|
|
735
|
+
[User]:
|
|
736
|
+
What is the capital of France?
|
|
737
|
+
LLM Response:
|
|
738
|
+
The capital of France is Paris.
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
This works for both streaming and non-streaming client requests.
|
|
742
|
+
|
|
743
|
+
> **Warning** ⚠️
|
|
744
|
+
> Intended for local development and troubleshooting only.
|
|
745
|
+
> Prompts and generated content are written to the console in plain text,
|
|
746
|
+
> and the output of requests processed in parallel is interleaved.
|
|
747
|
+
|
|
684
748
|
|
|
685
749
|
## 🤝 Contributing<a id="-contributing"></a>
|
|
686
750
|
|
|
@@ -84,7 +84,7 @@ class Env:
|
|
|
84
84
|
# initialize connections
|
|
85
85
|
env.connections = {}
|
|
86
86
|
for conn_name, conn_config in env.config.connections.items():
|
|
87
|
-
logging.info("Initializing
|
|
87
|
+
logging.info("Initializing '%s' LLM proxy connection...", ui.green(conn_name))
|
|
88
88
|
try:
|
|
89
89
|
fn_or_config = resolve_instance_or_callable(conn_config, allow_types=[dict])
|
|
90
90
|
if _is_async_callable(fn_or_config):
|
|
@@ -94,7 +94,10 @@ class Env:
|
|
|
94
94
|
env.connections[conn_name] = mc.env().llm_async_function
|
|
95
95
|
except mc.LLMConfigError as e:
|
|
96
96
|
raise ValueError(f"Error in configuration for connection '{conn_name}': {e}") from e
|
|
97
|
-
|
|
97
|
+
if config.print_stream:
|
|
98
|
+
mc.use_logging(stream=True)
|
|
99
|
+
# Proxied prompts are printed in full, without "...(output was truncated)..."
|
|
100
|
+
mc.logging.LoggingConfig.STRIP_REQUEST_LINES = None
|
|
98
101
|
logging.info("Done initializing %d connections.", len(env.connections))
|
|
99
102
|
|
|
100
103
|
|
|
@@ -90,6 +90,10 @@ class Config(BaseModel):
|
|
|
90
90
|
)
|
|
91
91
|
components: dict[str, Union[str, Callable, dict]] = Field(default_factory=dict)
|
|
92
92
|
before: list[Union[str, Callable, dict]] = Field(default_factory=list)
|
|
93
|
+
print_stream: bool = Field(
|
|
94
|
+
default=False,
|
|
95
|
+
description="Prints LLM requests / responses to stdout"
|
|
96
|
+
)
|
|
93
97
|
|
|
94
98
|
def __init__(self, **data):
|
|
95
99
|
super().__init__(**data)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""JSON configuration loader."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def load_json_config(config_path: str) -> dict:
|
|
7
|
+
"""Loads configuration from a JSON file."""
|
|
8
|
+
# utf-8-sig skips the byte order mark that Windows text editors may add,
|
|
9
|
+
# the JSON parser rejects it
|
|
10
|
+
with open(config_path, "r", encoding="utf-8-sig") as f:
|
|
11
|
+
return json.load(f)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""TOML configuration loader."""
|
|
2
|
+
|
|
3
|
+
import tomllib
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def load_toml_config(config_path: str) -> dict:
|
|
7
|
+
"""Loads configuration from a TOML file."""
|
|
8
|
+
# utf-8-sig skips the byte order mark that Windows text editors may add,
|
|
9
|
+
# tomllib rejects it
|
|
10
|
+
with open(config_path, "r", encoding="utf-8-sig") as f:
|
|
11
|
+
return tomllib.loads(f.read())
|
|
@@ -11,6 +11,7 @@ import inspect
|
|
|
11
11
|
from datetime import datetime
|
|
12
12
|
from typing import Optional
|
|
13
13
|
|
|
14
|
+
import microcore as mc
|
|
14
15
|
from fastapi import HTTPException
|
|
15
16
|
from openai.types.chat.chat_completion import Choice
|
|
16
17
|
from starlette.requests import Request
|
|
@@ -65,6 +66,30 @@ def resolve_connection_and_model(config: Config, external_model: str) -> tuple[s
|
|
|
65
66
|
)
|
|
66
67
|
|
|
67
68
|
|
|
69
|
+
def print_llm_request(ctx: RequestContext):
|
|
70
|
+
"""
|
|
71
|
+
Prints the LLM request to stdout when the `print_stream` option is enabled.
|
|
72
|
+
|
|
73
|
+
LM-Proxy queries the LLM API function directly instead of using microcore.allm(),
|
|
74
|
+
so microcore request / response handlers are triggered explicitly.
|
|
75
|
+
"""
|
|
76
|
+
if env.config.print_stream:
|
|
77
|
+
for handler in mc.env().llm_before_handlers:
|
|
78
|
+
handler(ctx.request.messages, **ctx.llm_params)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def finish_printing_llm_response(ctx: RequestContext):
|
|
82
|
+
"""
|
|
83
|
+
Completes printing of the LLM response to stdout, in particular terminates
|
|
84
|
+
the line of the streamed output, when the `print_stream` option is enabled.
|
|
85
|
+
|
|
86
|
+
See print_llm_request().
|
|
87
|
+
"""
|
|
88
|
+
if env.config.print_stream:
|
|
89
|
+
for handler in mc.env().llm_after_handlers:
|
|
90
|
+
handler(ctx.response)
|
|
91
|
+
|
|
92
|
+
|
|
68
93
|
async def process_stream(
|
|
69
94
|
async_llm_func,
|
|
70
95
|
request: ChatCompletionRequest,
|
|
@@ -121,6 +146,7 @@ async def process_stream(
|
|
|
121
146
|
except Exception as e:
|
|
122
147
|
ctx.error = e
|
|
123
148
|
yield make_chunk(error={"message": str(e), "type": type(e).__name__})
|
|
149
|
+
finish_printing_llm_response(ctx)
|
|
124
150
|
|
|
125
151
|
yield make_chunk(finish_reason="error" if ctx.error else "stop")
|
|
126
152
|
yield "data: [DONE]\n\n"
|
|
@@ -252,6 +278,7 @@ async def chat_completions(request: ChatCompletionRequest, raw_request: Request)
|
|
|
252
278
|
async_llm_func = env.connections[connection]
|
|
253
279
|
|
|
254
280
|
logging.info("Querying LLM... params: %s", ctx.llm_params)
|
|
281
|
+
print_llm_request(ctx)
|
|
255
282
|
if request.stream:
|
|
256
283
|
return StreamingResponse(
|
|
257
284
|
process_stream(async_llm_func, request, ctx),
|
|
@@ -261,9 +288,11 @@ async def chat_completions(request: ChatCompletionRequest, raw_request: Request)
|
|
|
261
288
|
try:
|
|
262
289
|
out = await async_llm_func(request.messages, **ctx.llm_params)
|
|
263
290
|
ctx.response = out
|
|
291
|
+
finish_printing_llm_response(ctx)
|
|
264
292
|
logging.info("LLM response: %s", out)
|
|
265
293
|
except Exception as e:
|
|
266
294
|
ctx.error = e
|
|
295
|
+
finish_printing_llm_response(ctx)
|
|
267
296
|
await log_non_blocking(ctx)
|
|
268
297
|
error_details = f" [{type(e).__name__}]: {e}" if env.debug else ""
|
|
269
298
|
logging.exception(e)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "inference-proxy"
|
|
3
|
-
version = "3.
|
|
3
|
+
version = "3.3.0"
|
|
4
4
|
description = "Inference Proxy is an OpenAI-compatible http proxy server for inferencing various LLMs capable of working with Google, Anthropic, OpenAI APIs, local PyTorch inference, etc."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
keywords = ["llm", "large language models", "ai", "gpt", "openai", "proxy", "http", "proxy-server", "llm gateway", "openai", "anthropic", "google genai"]
|
|
@@ -35,8 +35,8 @@ documentation = "https://github.com/Nayjest/lm-proxy#readme"
|
|
|
35
35
|
license = { file = "LICENSE" }
|
|
36
36
|
|
|
37
37
|
dependencies = [
|
|
38
|
-
"ai-microcore>=
|
|
39
|
-
"fastapi>=0.
|
|
38
|
+
"ai-microcore>=6.6.1,<7",
|
|
39
|
+
"fastapi>=0.136.3,<1",
|
|
40
40
|
"uvicorn>=0.41.0",
|
|
41
41
|
"typer>=0.24.0,<1",
|
|
42
42
|
"requests>=2.32.5,<3",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|