|
1 | 1 | # Contributing to OpenRouter Pipe |
2 | 2 |
|
3 | | -> **Maintained by [Sena Labs](https://github.com/sena-labs)** · [GitHub](https://github.com/sena-labs/OpenRouter-Pipe) |
| 3 | +Thanks for wanting to contribute! This document is intentionally opinionated: it codifies the |
| 4 | +**deliverable-PR playbook** the maintainers use day-to-day so new contributors can ship changes |
| 5 | +with the same cadence and quality. |
4 | 6 |
|
5 | | -Thanks for your interest in contributing. |
| 7 | +## Table of Contents |
6 | 8 |
|
7 | | -## Quick Start |
| 9 | +- [Code of Conduct](#code-of-conduct) |
| 10 | +- [Getting started](#getting-started) |
| 11 | +- [Development setup](#development-setup) |
| 12 | +- [Deliverable-PR playbook](#deliverable-pr-playbook) |
| 13 | +- [Commit messages](#commit-messages) |
| 14 | +- [Coding standards](#coding-standards) |
| 15 | +- [Testing](#testing) |
| 16 | +- [Reporting bugs](#reporting-bugs) |
| 17 | +- [Suggesting features](#suggesting-features) |
8 | 18 |
|
9 | | -```bash |
10 | | -git clone https://github.com/sena-labs/OpenRouter-Pipe.git |
11 | | -cd OpenRouter-Pipe |
12 | | -python test_pipe.py |
13 | | -``` |
| 19 | +## Code of Conduct |
| 20 | + |
| 21 | +This project follows the [Contributor Covenant Code of Conduct](.github/CODE_OF_CONDUCT.md). |
| 22 | +By participating, you agree to uphold this code. |
| 23 | + |
| 24 | +## Getting started |
| 25 | + |
| 26 | +1. **Fork** the repository on GitHub. |
| 27 | +2. **Clone** your fork locally: |
| 28 | + |
| 29 | + ```bash |
| 30 | + git clone https://github.com/<your-username>/OpenRouter-Pipe.git |
| 31 | + cd OpenRouter-Pipe |
| 32 | + ``` |
| 33 | + |
| 34 | +3. **Install** dependencies: |
| 35 | + |
| 36 | + ```bash |
| 37 | + pip install -r requirements.txt |
| 38 | + ``` |
14 | 39 |
|
15 | | -## Development |
| 40 | +4. **Verify** the baseline is green before changing anything: |
| 41 | + |
| 42 | + ```bash |
| 43 | + python test_pipe.py |
| 44 | + ``` |
| 45 | + |
| 46 | +## Development setup |
16 | 47 |
|
17 | 48 | ### Prerequisites |
18 | 49 |
|
19 | | -- Python 3.10+ |
20 | | -- `requests` >= 2.20 |
21 | | -- `pydantic` >= 2.0 |
| 50 | +- **Python** ≥ 3.10 (matches the CI matrix). |
| 51 | +- **`requests`** ≥ 2.20. |
| 52 | +- **`pydantic`** ≥ 2.0. |
22 | 53 |
|
23 | | -Install dependencies: |
| 54 | +### Useful commands |
24 | 55 |
|
25 | | -```bash |
26 | | -pip install -r requirements.txt |
27 | | -``` |
| 56 | +| Command | Description | |
| 57 | +| --- | --- | |
| 58 | +| `python test_pipe.py` | Run the full unit test suite (252 tests) | |
| 59 | +| `python integration_test.py` | Run live API tests (requires `OPENROUTER_API_KEY`) | |
28 | 60 |
|
29 | | -### Running Tests |
| 61 | +## Deliverable-PR playbook |
30 | 62 |
|
31 | | -```bash |
32 | | -python test_pipe.py # Unit tests (252 tests) |
33 | | -python integration_test.py # Live API tests (requires OPENROUTER_API_KEY) |
34 | | -``` |
| 63 | +Every change is shipped as a **single-deliverable pull request**. One PR = one reviewable unit |
| 64 | +of value. The playbook: |
| 65 | + |
| 66 | +1. **Sync `main`** and create a branch with a descriptive slug: |
| 67 | + |
| 68 | + ```bash |
| 69 | + git checkout main && git pull |
| 70 | + git checkout -b feat/<slug> |
| 71 | + ``` |
| 72 | + |
| 73 | +2. **Implement** the smallest complete slice of the change. Prefer surgical edits over |
| 74 | + incidental refactors. |
35 | 75 |
|
36 | | -All unit tests must pass. If adding new functionality, add corresponding tests. |
| 76 | +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 252/252. |
37 | 78 |
|
38 | | -### Code Style |
| 79 | +4. **Validate locally** using the same commands CI runs: |
39 | 80 |
|
40 | | -- Follow PEP 8 conventions |
41 | | -- Use type hints for all function signatures |
42 | | -- Keep methods focused — one responsibility per method |
43 | | -- Add docstrings for public methods |
44 | | -- Use `print(f"[OpenRouter Pipe] ...")` for debug logging |
| 81 | + ```bash |
| 82 | + python test_pipe.py |
| 83 | + python integration_test.py # optional, requires a valid API key |
| 84 | + ``` |
45 | 85 |
|
46 | | -## Pull Request Process |
| 86 | +5. **Update `CHANGELOG.md`.** Prepend a bullet under `## [Unreleased]` describing the |
| 87 | + user-visible impact. |
47 | 88 |
|
48 | | -1. **Fork** the repository |
49 | | -2. Create a **feature branch** (`git checkout -b feature/my-feature`) |
50 | | -3. Make your changes |
51 | | -4. **Run the test suite** and ensure all tests pass |
52 | | -5. Update `CHANGELOG.md` with your changes under `[Unreleased]` |
53 | | -6. Commit with a clear message (`git commit -m "feat: add XYZ support"`) |
54 | | -7. Push to your fork and **open a Pull Request** |
| 89 | +6. **Commit with Conventional Commits** (see [Commit messages](#commit-messages)) and push: |
| 90 | + |
| 91 | + ```bash |
| 92 | + git push -u origin feat/<slug> |
| 93 | + ``` |
| 94 | + |
| 95 | +7. **Open the pull request** using the [PR template](.github/PULL_REQUEST_TEMPLATE.md) and |
| 96 | + fill every section. |
| 97 | + |
| 98 | +8. **Verify CI** goes green. A failing test leg blocks the merge — fix forward rather than |
| 99 | + disabling the check. |
| 100 | + |
| 101 | +Keep the branch focused: if the diff grows beyond ~300 lines of non-generated code, split it. |
| 102 | + |
| 103 | +## Commit messages |
| 104 | + |
| 105 | +We follow [Conventional Commits](https://www.conventionalcommits.org/): |
| 106 | + |
| 107 | +```text |
| 108 | +<type>(<scope>): <description> |
| 109 | +
|
| 110 | +[optional body] |
| 111 | +
|
| 112 | +[optional footer] |
| 113 | +``` |
| 114 | + |
| 115 | +**Types:** `feat`, `fix`, `docs`, `refactor`, `test`, `chore`, `ci`. |
| 116 | + |
| 117 | +**Examples:** |
| 118 | + |
| 119 | +```text |
| 120 | +feat(routing): add PROVIDER_IGNORE valve |
| 121 | +fix(stream): close think tag on mid-stream error |
| 122 | +docs: update README installation steps |
| 123 | +test: add retry exhaustion coverage |
| 124 | +``` |
55 | 125 |
|
56 | | -### Commit Convention |
| 126 | +## Coding standards |
57 | 127 |
|
58 | | -We use [Conventional Commits](https://www.conventionalcommits.org/): |
| 128 | +- **PEP 8** — enforced by convention; keep line length ≤ 100 chars. |
| 129 | +- **Type hints** on every function signature. |
| 130 | +- **One responsibility per method** — keep functions under ~50 lines; extract helpers when they grow. |
| 131 | +- **Docstrings** on every public method using the one-line summary style. |
| 132 | +- **Logging** via `print(f"[OpenRouter Pipe] …")` — never log API keys or user content. |
| 133 | +- No `any`-equivalent type erasure; use proper `dict[str, Any]` annotations. |
59 | 134 |
|
60 | | -| Prefix | Usage | |
61 | | -|--------|-------| |
62 | | -| `feat:` | New feature | |
63 | | -| `fix:` | Bug fix | |
64 | | -| `docs:` | Documentation only | |
65 | | -| `refactor:` | Code restructuring | |
66 | | -| `test:` | Adding or updating tests | |
67 | | -| `chore:` | Maintenance tasks | |
| 135 | +## Testing |
68 | 136 |
|
69 | | -### PR Checklist |
| 137 | +- **Framework:** Python `unittest` (stdlib). |
| 138 | +- **Mock strategy:** `unittest.mock.patch` for HTTP calls and Open WebUI internals. |
| 139 | +- **Conventions:** |
| 140 | + - Test path mirrors source: `openrouter_pipe.py` ↔ `test_pipe.py`. |
| 141 | + - Each test class covers one unit (`TestPreparePayload`, `TestStreamResponse`, etc.). |
| 142 | + - Use descriptive method names: `test_fallback_deduplication_removes_duplicates`. |
| 143 | +- **Run the suite the same way CI does:** `python test_pipe.py`. Integration tests require a |
| 144 | + live API key and are optional for most contributions. |
70 | 145 |
|
71 | | -- [ ] Tests pass (`python test_pipe.py` and `python integration_test.py` → 0 failures) |
72 | | -- [ ] New features have corresponding tests |
73 | | -- [ ] `CHANGELOG.md` updated |
74 | | -- [ ] Code follows existing style conventions |
75 | | -- [ ] No OpenRouter API keys or secrets committed |
| 146 | +## Reporting bugs |
76 | 147 |
|
77 | | -## Reporting Issues |
| 148 | +When reporting a bug, open a [GitHub issue](https://github.com/sena-labs/OpenRouter-Pipe/issues) |
| 149 | +using the **Bug report** template and include: |
78 | 150 |
|
79 | | -When reporting a bug, please include: |
| 151 | +1. **Open WebUI version** (`Admin Panel → About`). |
| 152 | +2. **Python version** (`python --version`). |
| 153 | +3. **Steps to reproduce** the issue. |
| 154 | +4. **Expected vs. actual behavior.** |
| 155 | +5. **Error logs** — check the Open WebUI server logs and filter for `[OpenRouter Pipe]` messages. |
80 | 156 |
|
81 | | -1. **Open WebUI version** you're running |
82 | | -2. **Python version** (`python --version`) |
83 | | -3. **Steps to reproduce** the issue |
84 | | -4. **Expected vs actual behavior** |
85 | | -5. **Error logs** (check Open WebUI server logs for `[OpenRouter Pipe]` messages) |
| 157 | +**Do not** include your API key in the issue. Redact it before pasting logs. |
86 | 158 |
|
87 | | -## Feature Requests |
| 159 | +## Suggesting features |
88 | 160 |
|
89 | | -Before requesting a feature: |
| 161 | +Before opening a feature request: |
90 | 162 |
|
91 | | -1. Check [OpenRouter API docs](https://openrouter.ai/docs) to confirm the feature exists upstream |
92 | | -2. Check [Open WebUI Pipe docs](https://docs.openwebui.com/features/plugin/functions/pipe) for compatibility |
93 | | -3. Open an issue describing the feature and its use case |
| 163 | +1. Check the [OpenRouter API docs](https://openrouter.ai/docs) to confirm the feature exists upstream. |
| 164 | +2. Check the [Open WebUI Pipe docs](https://docs.openwebui.com/features/plugin/functions/pipe) for compatibility constraints. |
| 165 | +3. Open an issue using the **Feature request** template and describe the use case and expected behavior. |
94 | 166 |
|
95 | | -## License |
| 167 | +--- |
96 | 168 |
|
97 | | -By contributing, you agree that your contributions will be licensed under the [MIT License](LICENSE). |
| 169 | +Thanks for helping improve OpenRouter Pipe! 🚀 |
0 commit comments