Skip to content

Commit 5ea1c90

Browse files
committed
docs(readme): expand TOC, document media-gen valves, fix stale architecture refs
README pass: align with the v1.10.0 surface and fix small staleness from the audit-batch shipping. TOC - Add subsection links that were missing under Usage (Common valve combinations, Reasoning tokens, Citations) and Configuration (Media Generation, Cost Display, Per-user settings, API key encryption, Tool calling). Badges - Add a release badge driven by github.com/.../releases/latest and a test-count badge (868 tests). Configuration — new Media Generation valve table - VIDEO_GENERATION_TIMEOUT (default 600 s) + VIDEO_POLL_INTERVAL (default 5 s) - AUDIO_OUTPUT_FORMAT (default mp3, ignored for openai/gpt-audio* which is auto-forced to pcm16 + WAV-wrapped) - AUDIO_OUTPUT_VOICE (default alloy, ignored by music models like Lyria) Display & Filtering - OUTPUT_MODALITIES doc string lists 'video' alongside text/image/ audio/embeddings. Common valve combinations - Added rows for flux image gen, grok-imagine cheap video, Lyria music, gpt-audio-mini speech (with AUDIO_OUTPUT_VOICE hint), SHOW_REMAINING_CREDIT, SHOW_COST_INFO + currency, ZDR_ENFORCE. Architecture table - Replace the stale '_non_stream_response()' row with '_non_stream_fetch() + _non_stream_with_events()' (the actual live path) and add rows for the tool loop (_run_tools_{stream,nonstream} + _stream_one_round), video generation (_run_video_generation), audio generation (_materialize_audio_output + _wrap_pcm16_as_wav), the shared upload helper (_owui_upload_bytes), and the SSRF / size / MIME security guards.
1 parent e5f6c45 commit 5ea1c90

1 file changed

Lines changed: 41 additions & 7 deletions

File tree

README.md

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
# OpenRouter Pipe
22

33
[![Build](https://github.com/sena-labs/Open-WebUI-Pipe-OpenRouter/actions/workflows/tests.yml/badge.svg)](https://github.com/sena-labs/Open-WebUI-Pipe-OpenRouter/actions/workflows/tests.yml)
4+
[![Release](https://img.shields.io/github/v/release/sena-labs/Open-WebUI-Pipe-OpenRouter?label=release)](https://github.com/sena-labs/Open-WebUI-Pipe-OpenRouter/releases/latest)
45
[![Python](https://img.shields.io/badge/Python-%E2%89%A53.10-blue)](https://www.python.org/)
6+
[![Tests](https://img.shields.io/badge/tests-868%20%E2%9C%93-brightgreen)](test_pipe.py)
57
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
68

79
Access the **full OpenRouter catalog (400+ models)** — chat, TTS, audio (input + generation),
@@ -18,13 +20,21 @@ control out of the box.
1820
- [Manual install](#manual-install)
1921
- [From source](#from-source)
2022
- [Usage](#usage)
23+
- [Common valve combinations](#common-valve-combinations)
24+
- [Reasoning tokens](#reasoning-tokens)
25+
- [Citations](#citations)
2126
- [Configuration](#configuration)
2227
- [Core](#core)
2328
- [Reasoning](#reasoning)
2429
- [Display & Filtering](#display--filtering)
2530
- [Provider Routing](#provider-routing)
31+
- [Media Generation](#media-generation)
2632
- [Advanced](#advanced)
2733
- [Network](#network)
34+
- [Cost Display](#cost-display)
35+
- [Per-user settings (UserValves)](#per-user-settings-uservalves)
36+
- [API key encryption at rest](#api-key-encryption-at-rest)
37+
- [Tool calling (native function calling)](#tool-calling-native-function-calling)
2838
- [Architecture](#architecture)
2939
- [Development](#development)
3040
- [Contributing](#contributing)
@@ -113,6 +123,13 @@ an environment variable fallback (see [Configuration](#configuration)).
113123
| Use DeepSeek for reasoning | select `deepseek/deepseek-r1`, `INCLUDE_REASONING = true` |
114124
| Route cheapest provider first | `PROVIDER_SORT = price` |
115125
| Add a fallback model | `FALLBACK_MODELS = anthropic/claude-3.5-sonnet` |
126+
| Generate an image (flux) | select `black-forest-labs/flux.2-klein-4b`, send any prompt — output renders inline |
127+
| Generate a video (cheap) | select `x-ai/grok-imagine-video` (~$0.05 / second, 480p) — output renders inline after polling |
128+
| Generate music (Lyria) | select `google/lyria-3-clip-preview` (~$0.04 / 30 s clip) — output renders inline as `<audio>` |
129+
| Generate speech (gpt-audio) | select `openai/gpt-audio-mini`, optionally set `AUDIO_OUTPUT_VOICE = nova` |
130+
| Surface remaining OpenRouter credit | `SHOW_REMAINING_CREDIT = true` |
131+
| Show cost + cached-token savings | `SHOW_COST_INFO = true`, `COST_CURRENCY = EUR` |
132+
| Enforce Zero Data Retention routing | `ZDR_ENFORCE = true`, optional `ZDR_MODELS_ONLY = true` to hide non-ZDR models |
116133

117134
### Reasoning tokens
118135

@@ -159,7 +176,7 @@ Every valve accepts an environment variable fallback. The table below lists both
159176
| `INVERT_PROVIDER_LIST` | `OPENROUTER_INVERT_PROVIDER_LIST` | `false` | Treat `MODEL_PROVIDERS` as an exclusion list |
160177
| `FREE_MODEL_FILTER` | `OPENROUTER_FREE_MODEL_FILTER` | `all` | Free-tier filter: `all` / `only` / `exclude` |
161178
| `TOOL_CALLING_FILTER` | `OPENROUTER_TOOL_CALLING_FILTER` | `all` | Tool-capable filter (reads `supported_parameters`): `all` / `only` / `exclude` |
162-
| `OUTPUT_MODALITIES` | `OPENROUTER_OUTPUT_MODALITIES` | `all` | Output modalities to fetch from `/models`. `all` (default) lists every model. Restrict with `text`, `image`, `audio`, `embeddings`, or a comma list (e.g. `text,audio`) |
179+
| `OUTPUT_MODALITIES` | `OPENROUTER_OUTPUT_MODALITIES` | `all` | Output modalities to fetch from `/models`. `all` (default) lists every model. Restrict with `text`, `image`, `audio`, `video`, `embeddings`, or a comma list (e.g. `text,image,video`) |
163180
| `MODEL_VARIANTS` | `OPENROUTER_MODEL_VARIANTS` | `""` | Comma-separated `base_id:tag` entries that surface virtual variant models (e.g. `openai/gpt-4o:nitro`). Tags: `free`, `thinking`, `online`, `nitro`, `exacto`, `extended` |
164181
| `MODEL_CATEGORY` | `OPENROUTER_MODEL_CATEGORY` | `""` | Server-side category filter (`?category=`). Common values: `programming`, `roleplay`, `marketing`, `science`, `legal`, `finance`, `health`, `academia` |
165182
| `HIDE_DEPRECATED_MODELS` | `OPENROUTER_HIDE_DEPRECATED_MODELS` | `false` | Hide models with a non-null `expiration_date`. When False, deprecated models are tagged `⚠ {name} (deprecated)` |
@@ -182,6 +199,18 @@ Every valve accepts an environment variable fallback. The table below lists both
182199
| `DATA_COLLECTION` | `OPENROUTER_DATA_COLLECTION` | `allow` | Data policy: `allow` or `deny` |
183200
| `ZDR_ENFORCE` | `OPENROUTER_ZDR_ENFORCE` | `false` | Send `provider.zdr=true` so OpenRouter routes only to ZDR endpoints (request fails if none available) |
184201

202+
### Media Generation
203+
204+
Tunes the new image / video / audio output flows. Defaults are tuned for OpenRouter's
205+
documented behaviour — most installs never need to change them.
206+
207+
| Valve | Env Var | Default | Description |
208+
| --- | --- | --- | --- |
209+
| `VIDEO_GENERATION_TIMEOUT` | `OPENROUTER_VIDEO_GENERATION_TIMEOUT` | `600` | Hard timeout for a video job (seconds). Veo/Kling clips typically finish in 30 s – 5 min; raise for longer or higher-resolution outputs |
210+
| `VIDEO_POLL_INTERVAL` | `OPENROUTER_VIDEO_POLL_INTERVAL` | `5` | Seconds between `GET /videos/<id>` poll requests. 5 – 10 s is a good range |
211+
| `AUDIO_OUTPUT_FORMAT` | `OPENROUTER_AUDIO_OUTPUT_FORMAT` | `mp3` | Audio container the pipe requests from audio-output models. Common: `mp3`, `wav`, `flac`, `opus`, `pcm16`. Ignored for OpenAI `gpt-audio*` (forced to `pcm16` because that's the only format the upstream accepts with `stream=true`, then auto-wrapped in a WAV container) |
212+
| `AUDIO_OUTPUT_VOICE` | `OPENROUTER_AUDIO_OUTPUT_VOICE` | `alloy` | Voice for speech-synthesis audio models (`gpt-audio*`). Common: `alloy`, `echo`, `fable`, `onyx`, `nova`, `shimmer`. Music models like Lyria ignore the field |
213+
185214
### Advanced
186215

187216
| Valve | Env Var | Default | Description |
@@ -251,12 +280,17 @@ The pipe implements the **Manifold** pattern: one pipe entry point that surfaces
251280

252281
| Layer | Files | Responsibility |
253282
| --- | --- | --- |
254-
| Entry points | `Pipe.pipes()`, `Pipe.pipe()` | Model listing and chat routing |
255-
| Payload | `_prepare_payload()` | Sanitize OWUI internals, inject routing and reasoning |
256-
| Transport | `_retryable_request()` | Retry wrapper with exponential backoff |
257-
| Streaming | `_stream_response()` | SSE parser, `<think>` management, mid-stream errors |
258-
| Non-streaming | `_non_stream_response()` | JSON response, body-level error detection |
259-
| Enrichment | `_inject_cache_control()`, `_insert_citations()` | Post-processing |
283+
| Entry points | `Pipe.pipes()`, `Pipe.pipe()` | Model listing (with atomic frozenset swap for the audio / video routing sets) and per-request routing |
284+
| Payload | `_prepare_payload()` | Sanitize OWUI internals, inject provider routing, reasoning, response format, fallbacks, web search, cache control |
285+
| Transport | `_retryable_request()` + `requests.Session` w/ `HTTPAdapter(pool_maxsize=64)` | Retry wrapper with exponential backoff + Retry-After awareness; one shared connection pool sized for concurrent users |
286+
| Streaming chat | `_stream_response()` + async `_wrap_stream` | SSE parser, `<think>` management, image/audio capture, final media materialization, mid-stream error sanitisation |
287+
| Non-streaming chat | `_non_stream_fetch()` + `_non_stream_with_events()` | Off-loop JSON request, image materialization, citation + credit events |
288+
| Tool loop | `_run_tools_stream()` / `_run_tools_nonstream()` + `_stream_one_round()` | Execute tools, feed results back, cap iterations; both paths now also capture image/audio output via `_stream_media_embeds` |
289+
| Video generation | `_run_video_generation()` | Submit to `/api/v1/videos`, poll, download with byte cap, embed via block-HTML `<video>` |
290+
| Audio generation | `_materialize_audio_output()` + `_wrap_pcm16_as_wav()` | Decode base64 audio chunks, wrap PCM in RIFF/WAVE for OpenAI, embed via block-HTML `<audio>` |
291+
| OWUI file upload | `_owui_upload_bytes()` | Single shared helper backing every image / video / audio re-host through OWUI |
292+
| Security guards | `_is_openrouter_url()`, MIME / size / scheme whitelists | SSRF + auth-leak protection on media downloads, citation URL filter |
293+
| Enrichment | `_inject_cache_control()`, `_insert_citations()`, `_format_credit_info()` | Anthropic prompt-cache breakpoints, `[n]` → markdown links, opt-in credit footer (pre-warmed off the event loop) |
260294

261295
```text
262296
Open-WebUI-Pipe-OpenRouter/

0 commit comments

Comments
 (0)