Skip to content

Commit 60064ad

Browse files
committed
release: v1.10.1 — icon coverage 99.3% (every visible model gets a real brand icon)
10 icon-fix commits between fc5b411 and 1a3d7d4 bring the live-VPS brand-icon coverage from 261/408 (64%) to 448/451 (99.3%). Only the three kwaivgi/kling-* models remain on the deterministic letter-SVG fallback because Kuaishou's video team has no public icon source. function.json - version 1.10.0 → 1.10.1 - updated_at bumped to 2026-05-31 CHANGELOG.md - new [1.10.1] section under Added / Changed / Fixed / Docs / Tests documenting the layered fallback chain, the 41 hardcoded brand URLs, the orphan-DB sweep, the awaitable resolver, the /static/favicon.png recognition, and the SPA-broken URL fixes README / TESTING / CONTRIBUTING / PR template - test count 868 → 939 .gitignore - tighten Chrome MCP screenshot pattern so extensionless dumps (e.g. 107-kling, 113-mid, 117-mid-clean) are caught too
1 parent 1a3d7d4 commit 60064ad

7 files changed

Lines changed: 46 additions & 17 deletions

File tree

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
## Testing
2727

28-
- [ ] All unit tests pass (`python test_pipe.py`868/868 ✓)
28+
- [ ] All unit tests pass (`python test_pipe.py`939/939 ✓)
2929
- [ ] New tests added for the changes
3030
- [ ] Integration tests pass (`python integration_test.py`) — if applicable
3131
- [ ] `CHANGELOG.md` updated under `[Unreleased]`

.gitignore

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,8 @@ logs/security/
6868
ruvector.db
6969

7070
# Browser-driven smoke-test artifacts (Chrome MCP saves screenshots/HTML
71-
# captures keyed by frame number — purely local debug output)
72-
[0-9][0-9][0-9]-*.html
73-
[0-9][0-9][0-9]-*.png
74-
[0-9][0-9][0-9]-*.md
75-
[0-9][0-9][0-9]-*.txt
76-
[0-9][0-9][0-9]-rendered
77-
[0-9][0-9][0-9]-loaded
71+
# captures keyed by frame number — purely local debug output). Match
72+
# both extensionless dumps and the four common extensions Chrome MCP
73+
# emits — the [a-z]* suffix catches free-form names like 107-kling,
74+
# 113-mid, 117-mid-clean, etc.
75+
[0-9][0-9][0-9]-*

CHANGELOG.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.10.1] — 2026-05-31
11+
12+
### Added
13+
14+
- **Layered icon-resolution fallback chain** — every model in the selector now shows a real brand icon (or, as a last resort, a deterministic letter tile). New order: OpenRouter registry → hyphen-stripped slug → hardcoded `_PROVIDER_ICONS``_PROVIDER_SLUG_ALIASES` rewrite → provider-domain favicon (extracted from the registry's gstatic `url=` query parameter) → generated letter-SVG. Live VPS audit went from 261/408 hosted icons (64%) to **448/451 (99.3%)** — only the three `kwaivgi/kling-*` models remain on letter-SVG because Kuaishou's video team has no public icon source.
15+
- **41 official brand / HuggingFace-avatar icons added to `_PROVIDER_ICONS`** — covers nousresearch, sao10k, openrouter, sentence-transformers, inclusionai, baai, intfloat, tencent, zyphra, thenlper, allenai, kwaipilot, deepcogito, gryphe, essentialai, undi95, cognitivecomputations, writer, anthracite-org, prime-intellect, canopylabs, hexgrad, sesame, alfredpros, upstage, inflection, baidu, stepfun, rekaai, relace, aion-labs, arcee-ai, inception, liquid, z-ai, ai21, mancer, bytedance, bytedance-seed, thedrummer, ibm-granite, nex-agi. Each URL HEAD-checked against the actual served content type so SPA fallbacks that return `text/html` for missing assets no longer leak through as broken images.
16+
- **`USE_PROVIDER_DOMAIN_FAVICON` admin valve** (default `true`) — when gstatic is suppressed for privacy and no hardcoded icon exists, fall back to `https://<provider-domain>/favicon.ico` rather than the letter-SVG. Privacy-preferable to gstatic (the favicon request hits the provider directly, no Google middleman).
17+
- **`_generate_letter_icon` final fallback** — deterministic data: SVG with the provider's initial on an HSL-from-SHA256-of-key background. Privacy-safe (no external request), stable across syncs (no churn on the icon-managed check).
18+
- **`_sync_orphan_db_icons` sweep**`pipes()` now also iterates active OWUI model rows whose ID has our manifold prefix but no longer appears in the current catalog (deprecated / withdrawn models OWUI never cleans up). Six visible orphans on the live deployment were stuck on `/static/favicon.png` because the per-catalog sync only walked the current `pipes()` output.
19+
20+
### Fixed
21+
22+
- **`/static/favicon.png` was not recognised as managed** — the OWUI 0.4+ server-default favicon placeholder slipped through `_is_owui_managed_icon` and the regular sync refused to overwrite it. Added `/static/` to the managed-prefix list.
23+
- **`Models.{get,update,insert}_model_by_id` are async on OWUI ≥ 0.4**`_sync_model_icons` was sync and the coroutines were silently discarded, so the in-place sync never wrote to the model DB on modern OWUI. New `_resolve_maybe_awaitable` helper drains the coroutine with `asyncio.run` when needed (thread-pool fallback when invoked from inside a running loop).
24+
- **Provider-domain favicon URLs that returned `text/html` (SPA shell)**`ai21.com/favicon.ico` (200 but 0 bytes), `bytedance.com/favicon.svg`, `mancer.tech/favicon.ico`, and `openrouter.ai/favicon.svg` all returned the SPA index page instead of an image, so the OWUI selector rendered them as broken-image placeholders. Replaced each with the HuggingFace avatar URL or, for OpenRouter itself, `apple-touch-icon.png` (a real 6.4KB PNG).
25+
- **Provider slug aliases** — new `_PROVIDER_SLUG_ALIASES` map (`bytedance-seed → bytedance`, `rekaai → reka`, `grok → x-ai`, plus convenience entries for `gemini`/`claude`/`google-vertex`) handles model-author IDs that don't appear in the OpenRouter registry directly.
26+
27+
### Changed
28+
29+
- **`_is_owui_managed_icon` recognises every CDN we ship**`cdn-avatars.huggingface.co`, `huggingface.co/avatars/`, `github.com/<user>.png`, `gravatar.com/avatar/`, `openrouter.ai/{favicon.svg,apple-touch-icon.png}`, `sbert.net/_static/logo.png`, `bytedance.com/favicon.svg`, plus any top-level `https://<host>/favicon.ico`. Future refreshes can rotate stale CDN URLs without ever touching a user-set custom icon (which would live on a different host).
30+
- **Module-level `_PROVIDER_DOMAIN_CACHE`** populated alongside the icon registry — the provider website extracted from each gstatic favicon `url=` query param is indexed under both the exact slug and the hyphen-stripped variant.
31+
32+
### Docs
33+
34+
- **README**: expanded TOC to include all configuration subsections (Common valve combinations, Reasoning tokens, Citations, Media Generation, Cost Display, Per-user settings, API key encryption, Tool calling); added a dedicated **Media Generation** valve table documenting `VIDEO_GENERATION_TIMEOUT`, `VIDEO_POLL_INTERVAL`, `AUDIO_OUTPUT_FORMAT`, `AUDIO_OUTPUT_VOICE`; expanded **Common valve combinations** with flux / grok-imagine / Lyria / gpt-audio-mini examples and `SHOW_REMAINING_CREDIT` / `ZDR_ENFORCE` entries; rewrote the Architecture table with the actual live functions (`_non_stream_fetch + _non_stream_with_events` instead of the dead `_non_stream_response`, plus rows for the tool loop, video / audio generation, the shared `_owui_upload_bytes` helper, and the SSRF / size / MIME security guards); added release-version and test-count badges.
35+
- **Test count updated to 939** across README, TESTING, CONTRIBUTING, and the PR template.
36+
37+
### Tests
38+
39+
- 868 → **939** tests (+71). New coverage for the letter-SVG fallback, provider-domain favicon path, slug aliases, the orphan-DB sweep, the awaitable-resolver helper, the 41 newly hardcoded icon URLs, and the `_is_owui_managed_icon` recognition of the seven CDNs we ship from. All green on Python 3.10–3.13.
40+
1041
## [1.10.0] — 2026-05-30
1142

1243
### Added

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ By participating, you agree to uphold this code.
5555

5656
| Command | Description |
5757
| --- | --- |
58-
| `python test_pipe.py` | Run the full unit test suite (868 tests) |
58+
| `python test_pipe.py` | Run the full unit test suite (939 tests) |
5959
| `python integration_test.py` | Run live API tests (requires `OPENROUTER_API_KEY`) |
6060

6161
## Deliverable-PR playbook
@@ -74,7 +74,7 @@ of value. The playbook:
7474
incidental refactors.
7575

7676
3. **Add or update tests.** A change without test coverage needs a written justification
77-
in the PR body. The unit test suite must remain at 868/868.
77+
in the PR body. The unit test suite must remain at 939/939.
7878

7979
4. **Validate locally** using the same commands CI runs:
8080

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
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)
44
[![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)
55
[![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)
6+
[![Tests](https://img.shields.io/badge/tests-939%20%E2%9C%93-brightgreen)](test_pipe.py)
77
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
88

99
Access the **full OpenRouter catalog (400+ models)** — chat, TTS, audio (input + generation),
@@ -106,7 +106,7 @@ All OpenRouter models will appear in the model selector immediately.
106106
git clone https://github.com/sena-labs/Open-WebUI-Pipe-OpenRouter.git
107107
cd Open-WebUI-Pipe-OpenRouter
108108
pip install -r requirements.txt
109-
python test_pipe.py # 868 tests — verify everything is green
109+
python test_pipe.py # 939 tests — verify everything is green
110110
```
111111

112112
## Usage
@@ -296,7 +296,7 @@ The pipe implements the **Manifold** pattern: one pipe entry point that surfaces
296296
Open-WebUI-Pipe-OpenRouter/
297297
├── openrouter_pipe.py # Main pipe source — install this in Open WebUI
298298
├── function.json # Open WebUI community manifest
299-
├── test_pipe.py # Unit test suite (868 tests)
299+
├── test_pipe.py # Unit test suite (939 tests)
300300
├── integration_test.py # Live API integration tests (44 assertions)
301301
├── TESTING.md # Manual pre-release checklist
302302
├── SECURITY.md # Security policy
@@ -326,7 +326,7 @@ It also removes `user` when sent as a dict (Open WebUI format) since OpenRouter
326326
## Development
327327

328328
```bash
329-
python test_pipe.py # Unit tests (868 tests)
329+
python test_pipe.py # Unit tests (939 tests)
330330
python integration_test.py # Live API tests (requires OPENROUTER_API_KEY)
331331
```
332332

TESTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ Must exit with `All tests passed! ✓` and `✗ Failed: 0`. If any test fails, *
295295

296296
## Quick pre-release checklist
297297

298-
- [ ] `python test_pipe.py`868 passed, 0 failed
298+
- [ ] `python test_pipe.py`939 passed, 0 failed
299299
- [ ] `python integration_test.py` → 44/44
300300
- [ ] Empty API key → clear error message in model selector
301301
- [ ] Valid API key → 400+ models with provider icons

function.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"author": "Sena Labs",
1010
"author_url": "https://github.com/sena-labs",
1111
"funding_url": "https://github.com/sponsors/sena-labs",
12-
"version": "1.10.0",
12+
"version": "1.10.1",
1313
"license": "MIT",
1414
"required_open_webui_version": "0.4.0",
1515
"requirements": ["requests>=2.32.4", "pydantic>=2.0"]
@@ -36,6 +36,6 @@
3636
"content": "openrouter_pipe.py",
3737
"is_active": true,
3838
"is_global": true,
39-
"updated_at": "2026-05-30T00:00:00.000Z",
39+
"updated_at": "2026-05-31T00:00:00.000Z",
4040
"created_at": "2026-01-21T00:00:00.000Z"
4141
}

0 commit comments

Comments
 (0)