Skip to content

Commit adbc585

Browse files
committed
chore: add community files, extended tests, and README polish
- Add CODE_OF_CONDUCT.md (Contributor Covenant v2.1) - Add PULL_REQUEST_TEMPLATE.md with checklist - Add requirements.txt (requests>=2.20, pydantic>=2.0) - Add CHANGELOG compare links for all versions - Add README Table of Contents, Screenshots placeholder, Troubleshooting/FAQ - Fix error prefix consistency in empty response message - Add 39 new unit tests (234 total): _is_safe_url, _clean_model_id, model caching, base URL validator, pipe() guards, fallback attribution, citation edge cases, pipes() edge cases - Update test counts (195->234) across all docs - Update Project Structure to include new files - Update CONTRIBUTING prerequisites with version numbers
1 parent af3c238 commit adbc585

9 files changed

Lines changed: 519 additions & 7 deletions

.github/CODE_OF_CONDUCT.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# Contributor Covenant Code of Conduct
2+
3+
## Our Pledge
4+
5+
We as members, contributors, and leaders pledge to make participation in our
6+
community a harassment-free experience for everyone, regardless of age, body
7+
size, visible or invisible disability, ethnicity, sex characteristics, gender
8+
identity and expression, level of experience, education, socio-economic status,
9+
nationality, personal appearance, race, caste, color, religion, or sexual
10+
identity and orientation.
11+
12+
We pledge to act and interact in ways that contribute to an open, welcoming,
13+
diverse, inclusive, and healthy community.
14+
15+
## Our Standards
16+
17+
Examples of behavior that contributes to a positive environment for our
18+
community include:
19+
20+
- Demonstrating empathy and kindness toward other people
21+
- Being respectful of differing opinions, viewpoints, and experiences
22+
- Giving and gracefully accepting constructive feedback
23+
- Accepting responsibility and apologizing to those affected by our mistakes,
24+
and learning from the experience
25+
- Focusing on what is best not just for us as individuals, but for the overall
26+
community
27+
28+
Examples of unacceptable behavior include:
29+
30+
- The use of sexualized language or imagery, and sexual attention or advances of
31+
any kind
32+
- Trolling, insulting or derogatory comments, and personal or political attacks
33+
- Public or private harassment
34+
- Publishing others' private information, such as a physical or email address,
35+
without their explicit permission
36+
- Other conduct which could reasonably be considered inappropriate in a
37+
professional setting
38+
39+
## Enforcement Responsibilities
40+
41+
Community leaders are responsible for clarifying and enforcing our standards of
42+
acceptable behavior and will take appropriate and fair corrective action in
43+
response to any behavior that they deem inappropriate, threatening, offensive,
44+
or harmful.
45+
46+
Community leaders have the right and responsibility to remove, edit, or reject
47+
comments, commits, code, wiki edits, issues, and other contributions that are
48+
not aligned to this Code of Conduct, and will communicate reasons for moderation
49+
decisions when appropriate.
50+
51+
## Scope
52+
53+
This Code of Conduct applies within all community spaces, and also applies when
54+
an individual is officially representing the community in public spaces.
55+
Examples of representing our community include using an official email address,
56+
posting via an official social media account, or acting as an appointed
57+
representative at an online or offline event.
58+
59+
## Enforcement
60+
61+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
62+
reported to the community leaders responsible for enforcement via
63+
[GitHub Issues](https://github.com/sena-labs/OpenRouter-Pipe/issues) or by
64+
contacting the maintainers through
65+
[GitHub private vulnerability reporting](https://github.com/sena-labs/OpenRouter-Pipe/security/advisories/new).
66+
67+
All complaints will be reviewed and investigated promptly and fairly.
68+
69+
All community leaders are obligated to respect the privacy and security of the
70+
reporter of any incident.
71+
72+
## Enforcement Guidelines
73+
74+
Community leaders will follow these Community Impact Guidelines in determining
75+
the consequences for any action they deem in violation of this Code of Conduct:
76+
77+
### 1. Correction
78+
79+
**Community Impact**: Use of inappropriate language or other behavior deemed
80+
unprofessional or unwelcome in the community.
81+
82+
**Consequence**: A private, written warning from community leaders, providing
83+
clarity around the nature of the violation and an explanation of why the
84+
behavior was inappropriate. A public apology may be requested.
85+
86+
### 2. Warning
87+
88+
**Community Impact**: A violation through a single incident or series of
89+
actions.
90+
91+
**Consequence**: A warning with consequences for continued behavior. No
92+
interaction with the people involved, including unsolicited interaction with
93+
those enforcing the Code of Conduct, for a specified period of time. This
94+
includes avoiding interactions in community spaces as well as external channels
95+
like social media. Violating these terms may lead to a temporary or permanent
96+
ban.
97+
98+
### 3. Temporary Ban
99+
100+
**Community Impact**: A serious violation of community standards, including
101+
sustained inappropriate behavior.
102+
103+
**Consequence**: A temporary ban from any sort of interaction or public
104+
communication with the community for a specified period of time. No public or
105+
private interaction with the people involved, including unsolicited interaction
106+
with those enforcing the Code of Conduct, is allowed during this period.
107+
Violating these terms may lead to a permanent ban.
108+
109+
### 4. Permanent Ban
110+
111+
**Community Impact**: Demonstrating a pattern of violation of community
112+
standards, including sustained inappropriate behavior, harassment of an
113+
individual, or aggression toward or disparagement of classes of individuals.
114+
115+
**Consequence**: A permanent ban from any sort of public interaction within the
116+
community.
117+
118+
## Attribution
119+
120+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
121+
version 2.1, available at
122+
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
123+
124+
Community Impact Guidelines were inspired by
125+
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
126+
127+
For answers to common questions about this code of conduct, see the FAQ at
128+
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
129+
[https://www.contributor-covenant.org/translations][translations].
130+
131+
[homepage]: https://www.contributor-covenant.org
132+
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
133+
[Mozilla CoC]: https://github.com/mozilla/diversity
134+
[FAQ]: https://www.contributor-covenant.org/faq
135+
[translations]: https://www.contributor-covenant.org/translations

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
## Description
2+
3+
<!-- Brief description of the changes in this PR -->
4+
5+
## Type of Change
6+
7+
- [ ] Bug fix (non-breaking change that fixes an issue)
8+
- [ ] New feature (non-breaking change that adds functionality)
9+
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
10+
- [ ] Documentation update
11+
- [ ] Refactoring (no functional changes)
12+
13+
## Checklist
14+
15+
- [ ] I have read the [CONTRIBUTING.md](../CONTRIBUTING.md) guidelines
16+
- [ ] All tests pass (`python test_pipe.py` — 234/234 ✓)
17+
- [ ] I have added tests for new functionality (if applicable)
18+
- [ ] I have updated `CHANGELOG.md` under `[Unreleased]`
19+
- [ ] I have updated documentation (if applicable)
20+
- [ ] My code follows the project's code style (PEP 8, type hints)
21+
- [ ] No secrets, API keys, or credentials are included in this PR
22+
23+
## Related Issues
24+
25+
<!-- Link any related issues: Fixes #123, Closes #456 -->
26+
27+
## Additional Notes
28+
29+
<!-- Any additional context, screenshots, or information -->

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,11 @@ No unreleased changes.
116116
- Streaming and non-streaming chat completions
117117
- Basic error handling and timeout configuration
118118
- Model prefix customization
119+
120+
<!-- Compare links -->
121+
[Unreleased]: https://github.com/sena-labs/OpenRouter-Pipe/compare/v1.2.0...HEAD
122+
[1.2.0]: https://github.com/sena-labs/OpenRouter-Pipe/compare/v1.1.1...v1.2.0
123+
[1.1.1]: https://github.com/sena-labs/OpenRouter-Pipe/compare/v1.1.0...v1.1.1
124+
[1.1.0]: https://github.com/sena-labs/OpenRouter-Pipe/compare/v1.0.0...v1.1.0
125+
[1.0.0]: https://github.com/sena-labs/OpenRouter-Pipe/compare/v0.1.0...v1.0.0
126+
[0.1.0]: https://github.com/sena-labs/OpenRouter-Pipe/releases/tag/v0.1.0

CONTRIBUTING.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,19 @@ python test_pipe.py
1717
### Prerequisites
1818

1919
- Python 3.10+
20-
- `requests` library
21-
- `pydantic` library
20+
- `requests` >= 2.20
21+
- `pydantic` >= 2.0
22+
23+
Install dependencies:
24+
25+
```bash
26+
pip install -r requirements.txt
27+
```
2228

2329
### Running Tests
2430

2531
```bash
26-
python test_pipe.py # Unit tests (195 tests)
32+
python test_pipe.py # Unit tests (234 tests)
2733
python integration_test.py # Live API tests (requires OPENROUTER_API_KEY)
2834
```
2935

README.md

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,23 @@ Provider routing · Reasoning tokens · Streaming · Fallbacks · Cache control
2121

2222
---
2323

24+
## Table of Contents
25+
26+
- [Why OpenRouter Pipe?](#why-openrouter-pipe)
27+
- [Screenshots](#screenshots)
28+
- [Quick Start](#quick-start)
29+
- [Features](#features)
30+
- [Configuration](#configuration)
31+
- [API Reference](#api-reference)
32+
- [Compatibility](#compatibility)
33+
- [Project Structure](#project-structure)
34+
- [Testing](#testing)
35+
- [Troubleshooting](#troubleshooting)
36+
- [Contributing](#contributing)
37+
- [License](#license)
38+
39+
---
40+
2441
## Why OpenRouter Pipe?
2542

2643
OpenRouter Pipe is the most feature-complete integration between [Open WebUI](https://docs.openwebui.com) and [OpenRouter](https://openrouter.ai). It gives you access to **300+ AI models** — including GPT-5, Claude 4, Gemini 2.5, Llama 4, DeepSeek R1, and more — directly in your Open WebUI interface, with zero configuration beyond an API key.
@@ -34,6 +51,20 @@ OpenRouter Pipe is the most feature-complete integration between [Open WebUI](ht
3451

3552
---
3653

54+
## Screenshots
55+
56+
<!-- TODO: Add screenshots of the pipe in action -->
57+
<!-- Suggested screenshots:
58+
1. Model selector showing OpenRouter models with provider icons
59+
2. Streaming response with <think> reasoning blocks
60+
3. Valve configuration panel in Open WebUI admin
61+
4. Fallback model attribution ("Responded by: ...")
62+
-->
63+
64+
*Screenshots coming soon — contributions welcome!*
65+
66+
---
67+
3768
## Quick Start
3869

3970
### Prerequisites
@@ -184,7 +215,7 @@ It also removes `user` when sent as a dict (OWUI format) since OpenRouter expect
184215
OpenRouter-Pipe/
185216
├── openrouter_pipe.py # Main pipe source (install this in Open WebUI)
186217
├── function.json # Open WebUI community manifest (metadata, tags, categories)
187-
├── test_pipe.py # Unit test suite (195 tests)
218+
├── test_pipe.py # Unit test suite (234 tests)
188219
├── integration_test.py # Live API integration tests (47 tests)
189220
├── TESTING.md # Pre-release testing checklist
190221
├── SECURITY.md # Security policy and vulnerability reporting
@@ -193,8 +224,11 @@ OpenRouter-Pipe/
193224
├── CONTRIBUTING.md # Contribution guidelines
194225
├── LICENSE # MIT License
195226
├── .gitignore # Git ignore rules
227+
├── requirements.txt # Python dependencies
196228
└── .github/
197229
├── FUNDING.yml # GitHub Sponsors configuration
230+
├── CODE_OF_CONDUCT.md # Contributor Covenant v2.1
231+
├── PULL_REQUEST_TEMPLATE.md # PR checklist template
198232
├── workflows/
199233
│ └── tests.yml # CI pipeline (Python 3.10–3.13)
200234
└── ISSUE_TEMPLATE/
@@ -223,6 +257,55 @@ Tests cover:
223257

224258
---
225259

260+
## Troubleshooting
261+
262+
<details>
263+
<summary><strong>"OpenRouter API key not configured"</strong></summary>
264+
265+
Set your API key in **Admin Panel → Functions → OpenRouter Pipe → Valves** (⚙️ icon), or set the `OPENROUTER_API_KEY` environment variable on the server.
266+
</details>
267+
268+
<details>
269+
<summary><strong>"Invalid API key (HTTP 401/502)"</strong></summary>
270+
271+
Your API key is incorrect or malformed. Get a valid key from [openrouter.ai/keys](https://openrouter.ai/keys) and make sure it starts with `sk-or-`.
272+
</details>
273+
274+
<details>
275+
<summary><strong>"Rate limit exceeded (HTTP 429)"</strong></summary>
276+
277+
You're sending too many requests. Wait a moment and try again. Consider setting `MAX_RETRIES` to `2` or higher for automatic backoff.
278+
</details>
279+
280+
<details>
281+
<summary><strong>"Insufficient credits (HTTP 402)"</strong></summary>
282+
283+
Your OpenRouter account balance is too low. Add credits at [openrouter.ai/credits](https://openrouter.ai/credits).
284+
</details>
285+
286+
<details>
287+
<summary><strong>"Request timed out"</strong></summary>
288+
289+
The model took too long to respond. Increase `REQUEST_TIMEOUT` in the valve settings (default: 90 seconds), or try a different model.
290+
</details>
291+
292+
<details>
293+
<summary><strong>No models showing in the selector</strong></summary>
294+
295+
1. Check that your API key is valid
296+
2. If using `MODEL_PROVIDERS`, verify the provider names are correct (e.g., `openai`, `anthropic`, `google`)
297+
3. If `FREE_ONLY` is enabled, some providers may not have free models available
298+
4. Try setting `MODEL_PROVIDERS` to `ALL` to see all models
299+
</details>
300+
301+
<details>
302+
<summary><strong>Models load but chat returns errors</strong></summary>
303+
304+
Some models may be temporarily unavailable on OpenRouter. Try a different model or check [OpenRouter Status](https://status.openrouter.ai).
305+
</details>
306+
307+
---
308+
226309
## Contributing
227310

228311
Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for details.

TESTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Manual checklist to verify every Pipe feature before release.
1212
python test_pipe.py
1313
```
1414

15-
Must print **195/195 passed**. If any test fails, **do not release**.
15+
Must print **234/234 passed**. If any test fails, **do not release**.
1616

1717
---
1818

@@ -191,7 +191,7 @@ Must print **195/195 passed**. If any test fails, **do not release**.
191191
## Quick pre-release checklist
192192

193193
```
194-
[ ] python test_pipe.py → 195/195
194+
[ ] python test_pipe.py → 234/234
195195
[ ] python integration_test.py → 47/47 ✓
196196
[ ] Empty API key → clear error
197197
[ ] Valid API key → 340+ models

openrouter_pipe.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,7 @@ def _non_stream_response(self, headers: dict, payload: dict) -> str:
583583
return f"OpenRouter Error: {msg}"
584584

585585
if not res.get("choices"):
586-
return "OpenRouter returned an empty response. The model may be temporarily unavailable."
586+
return "OpenRouter Error: Empty response. The model may be temporarily unavailable."
587587
choice = res["choices"][0]
588588
message = choice.get("message", {})
589589
citations = res.get("citations", [])

requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
requests>=2.20
2+
pydantic>=2.0

0 commit comments

Comments
 (0)