drupaltools-tip-generator 0.1.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.
Files changed (34) hide show
  1. drupaltools_tip_generator-0.1.0/.env.example +22 -0
  2. drupaltools_tip_generator-0.1.0/.github/workflows/publish.yml +29 -0
  3. drupaltools_tip_generator-0.1.0/.gitignore +30 -0
  4. drupaltools_tip_generator-0.1.0/LICENSE +20 -0
  5. drupaltools_tip_generator-0.1.0/PKG-INFO +253 -0
  6. drupaltools_tip_generator-0.1.0/PUBLISH.md +105 -0
  7. drupaltools_tip_generator-0.1.0/README.md +229 -0
  8. drupaltools_tip_generator-0.1.0/SKILL.md +96 -0
  9. drupaltools_tip_generator-0.1.0/config.json +122 -0
  10. drupaltools_tip_generator-0.1.0/example.config.json +10 -0
  11. drupaltools_tip_generator-0.1.0/pyproject.toml +42 -0
  12. drupaltools_tip_generator-0.1.0/setup.cfg +4 -0
  13. drupaltools_tip_generator-0.1.0/src/drupaltools_tip_generator.egg-info/PKG-INFO +253 -0
  14. drupaltools_tip_generator-0.1.0/src/drupaltools_tip_generator.egg-info/SOURCES.txt +32 -0
  15. drupaltools_tip_generator-0.1.0/src/drupaltools_tip_generator.egg-info/dependency_links.txt +1 -0
  16. drupaltools_tip_generator-0.1.0/src/drupaltools_tip_generator.egg-info/entry_points.txt +2 -0
  17. drupaltools_tip_generator-0.1.0/src/drupaltools_tip_generator.egg-info/requires.txt +2 -0
  18. drupaltools_tip_generator-0.1.0/src/drupaltools_tip_generator.egg-info/top_level.txt +1 -0
  19. drupaltools_tip_generator-0.1.0/src/tip_generator/MANIFEST.in +5 -0
  20. drupaltools_tip_generator-0.1.0/src/tip_generator/__init__.py +1691 -0
  21. drupaltools_tip_generator-0.1.0/src/tip_generator/config.json +122 -0
  22. drupaltools_tip_generator-0.1.0/src/tip_generator/templates/about.html +68 -0
  23. drupaltools_tip_generator-0.1.0/src/tip_generator/templates/index.html +97 -0
  24. drupaltools_tip_generator-0.1.0/src/tip_generator/url_cache.py +454 -0
  25. drupaltools_tip_generator-0.1.0/src/tip_generator/viewer.py +200 -0
  26. drupaltools_tip_generator-0.1.0/src/tip_generator.egg-info/PKG-INFO +253 -0
  27. drupaltools_tip_generator-0.1.0/src/tip_generator.egg-info/SOURCES.txt +25 -0
  28. drupaltools_tip_generator-0.1.0/src/tip_generator.egg-info/dependency_links.txt +1 -0
  29. drupaltools_tip_generator-0.1.0/src/tip_generator.egg-info/entry_points.txt +2 -0
  30. drupaltools_tip_generator-0.1.0/src/tip_generator.egg-info/requires.txt +2 -0
  31. drupaltools_tip_generator-0.1.0/src/tip_generator.egg-info/top_level.txt +1 -0
  32. drupaltools_tip_generator-0.1.0/static/style.css +369 -0
  33. drupaltools_tip_generator-0.1.0/templates/about.html +68 -0
  34. drupaltools_tip_generator-0.1.0/templates/index.html +97 -0
@@ -0,0 +1,22 @@
1
+ # Copy this file to .env and fill in your API keys
2
+ # The tip generator will automatically load these values
3
+ # All variables use TIPGEN_ prefix to avoid overriding global environment variables
4
+
5
+ # Anthropic API (for claude models). See models at https://docs.anthropic.com/en/docs/about-claude/models/overview
6
+ TIPGEN_ANTHROPIC_API_KEY=your_anthropic_key_here
7
+ TIPGEN_ANTHROPIC_MODEL=claude-haiku-4-5
8
+ # Optional: Custom API URL for Anthropic-compatible endpoints (e.g., local LLM servers)
9
+ # TIPGEN_ANTHROPIC_API_URL=https://api.anthropic.com
10
+
11
+ # OpenAI API (for gpt models). See models at https://platform.openai.com/docs/models
12
+ TIPGEN_OPENAI_API_KEY=your_openai_key_here
13
+ TIPGEN_OPENAI_MODEL=gpt-5.4-mini
14
+ # Optional: Custom API URL for OpenAI-compatible endpoints (e.g., local LLM servers, Ollama, vLLM)
15
+ # TIPGEN_OPENAI_API_URL=https://api.openai.com/v1
16
+
17
+ # OpenRouter API (access to many models). See https://openrouter.ai/models
18
+ TIPGEN_OPENROUTER_API_KEY=your_openrouter_key_here
19
+ TIPGEN_OPENROUTER_MODEL=openai/gpt-5.1-codex-mini
20
+
21
+ # Optional: Custom tips directory (default: tips/ folder in package)
22
+ # TIPGEN_TIPS_DIR=/path/to/custom/tips
@@ -0,0 +1,29 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+
14
+ - name: Set up Python
15
+ uses: actions/setup-python@v5
16
+ with:
17
+ python-version: '3.11'
18
+
19
+ - name: Install build dependencies
20
+ run: pip install --upgrade build twine
21
+
22
+ - name: Build package
23
+ run: python -m build
24
+
25
+ - name: Publish to PyPI
26
+ env:
27
+ TWINE_USERNAME: __token__
28
+ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
29
+ run: twine upload dist/*
@@ -0,0 +1,30 @@
1
+ # Environment variables (contains API keys)
2
+ .env
3
+
4
+ # Error log
5
+ errors.json
6
+
7
+ # Generated tips (can be regenerated)
8
+ tips/
9
+
10
+ # Cached remote data (URL fetches)
11
+ cache-data/
12
+
13
+ # Python
14
+ __pycache__/
15
+ *.py[cod]
16
+ *$py.class
17
+ .venv/
18
+ venv/
19
+ ENV/
20
+
21
+ # IDE
22
+ .idea/
23
+ .vscode/
24
+ *.swp
25
+ *.swo
26
+
27
+ # Build artifacts
28
+ dist/
29
+ build/
30
+ *.egg-info/
@@ -0,0 +1,20 @@
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 2, June 1991
3
+
4
+ Copyright (C) 2026 Drupal Tools
5
+
6
+ This program is free software; you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation; either version 2 of the License, or
9
+ (at your option) any later version.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License along
17
+ with this program; if not, write to the Free Software Foundation, Inc.,
18
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
+
20
+ Full license text: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
@@ -0,0 +1,253 @@
1
+ Metadata-Version: 2.4
2
+ Name: drupaltools-tip-generator
3
+ Version: 0.1.0
4
+ Summary: Generate static MD tip files for Drupal development tips using various LLM providers
5
+ Author-email: Drupal Tools Team <info@drupaltools.com>
6
+ License-Expression: GPL-2.0-or-later
7
+ Project-URL: Homepage, https://github.com/drupaltools/tip-generator
8
+ Project-URL: Repository, https://github.com/drupaltools/tip-generator.git
9
+ Project-URL: Issues, https://github.com/drupaltools/tip-generator/issues
10
+ Keywords: drupal,tips,llm,generator,ai,cli
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Software Development
18
+ Requires-Python: >=3.11
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: anthropic>=0.18.0
22
+ Requires-Dist: openai>=1.0.0
23
+ Dynamic: license-file
24
+
25
+ # Drupal Tip Generator
26
+
27
+ Generate static MD tip files for the `drupal-tip` skill using various LLM providers.
28
+
29
+ ## Setup
30
+
31
+ ### 1. Create Virtual Environment
32
+
33
+ ```bash
34
+ cd ~/.claude/skills/drupal-tip
35
+ python3 -m venv .venv
36
+ source .venv/bin/activate
37
+ pip install openai anthropic
38
+ ```
39
+
40
+ ### 2. Configure API Keys
41
+
42
+ Copy the example environment file and add your keys:
43
+
44
+ ```bash
45
+ cp .env.example .env
46
+ ```
47
+
48
+ Edit `.env` with your API keys (use `TIPGEN_` prefix):
49
+
50
+ ```env
51
+ TIPGEN_ANTHROPIC_API_KEY=sk-ant-...
52
+ TIPGEN_OPENAI_API_KEY=sk-...
53
+ TIPGEN_OPENROUTER_API_KEY=sk-or-...
54
+ ```
55
+
56
+ ## Usage
57
+
58
+ ### Get a Random Existing Tip (FAST!)
59
+
60
+ Get a tip from the pre-generated database instantly — no API call needed:
61
+
62
+ ```bash
63
+ .venv/bin/python tip_generator.py --random-tip
64
+ .venv/bin/python tip_generator.py --random-tip --tip-category core-service
65
+ .venv/bin/python tip_generator.py --list-existing
66
+ ```
67
+
68
+ ### List Available Categories
69
+
70
+ ```bash
71
+ .venv/bin/python tip_generator.py --list-categories
72
+ ```
73
+
74
+ ### Generate Tips
75
+
76
+ **Using Anthropic:**
77
+ ```bash
78
+ .venv/bin/python tip_generator.py -c 35 -n 5 -p anthropic
79
+ ```
80
+
81
+ **Using OpenAI (batch mode - 50% cheaper):**
82
+ ```bash
83
+ .venv/bin/python tip_generator.py -c 35 -n 5 -p openai
84
+ ```
85
+
86
+ **Using OpenRouter:**
87
+ ```bash
88
+ .venv/bin/python tip_generator.py -c 35 -n 5 -p openrouter
89
+ ```
90
+
91
+ ### Arguments
92
+
93
+ | Argument | Description |
94
+ |----------|-------------|
95
+ | `-c, --category` | Category number(s) or `all` |
96
+ | `-n, --count` | Number of tips per category (default: 5) |
97
+ | `-p, --provider` | LLM provider: `anthropic`, `openai`, `openrouter` |
98
+ | `-m, --model` | Override default model |
99
+ | `-u, --api-url` | Custom API URL for OpenAI/Anthropic-compatible endpoints |
100
+ | `-t, --max-tokens` | Maximum tokens for response (default: 4096) |
101
+ | `--tips-dir` | Custom tips directory (or set `TIPGEN_TIPS_DIR` env var or `tips_dir` in config.json) |
102
+ | `--save-truncated` | Save tips even if truncated (use with caution) |
103
+ | `--no-wait` | Don't wait for batch completion |
104
+ | `--dry-run` | Show what would be done without calling API |
105
+ | `--list-categories` | List all available categories |
106
+ | `--random-tip` | Get a random existing tip (fast, no API) |
107
+ | `--list-existing` | List categories with existing tips |
108
+ | `--tip-category` | Filter random tip by category name |
109
+ | `--validate` | Enable validation mode |
110
+ | `--validate-file` | Validate a specific tip file |
111
+ | `--validate-category` | Validate all tips in a category |
112
+ | `--validate-all` | Validate all tips across all categories |
113
+
114
+ ### Examples
115
+
116
+ ```bash
117
+ # Generate 3 tips for category 35 (core-service)
118
+ .venv/bin/python tip_generator.py -c 35 -n 3 -p openrouter
119
+
120
+ # Generate 5 tips for multiple categories
121
+ .venv/bin/python tip_generator.py -c 35,36,37 -n 5 -p openrouter
122
+
123
+ # Generate 1 tip for ALL categories
124
+ .venv/bin/python tip_generator.py -c all -n 1 -p openrouter
125
+
126
+ # Use a specific model
127
+ .venv/bin/python tip_generator.py -c 35 -n 5 -p openrouter -m anthropic/claude-opus-4
128
+
129
+ # Use a custom API URL (e.g., Together.xyz, local LLM server)
130
+ .venv/bin/python tip_generator.py -c 35 -n 5 -p openai -u https://api.together.xyz/v1
131
+
132
+ # Increase max tokens for longer responses (avoid truncation)
133
+ .venv/bin/python tip_generator.py -c 60 -n 20 -p openai --max-tokens 8192
134
+
135
+ # Save tips even if truncated (use with caution)
136
+ .venv/bin/python tip_generator.py -c 35 -n 5 -p openai --save-truncated
137
+ ```
138
+
139
+ ## Batch API Notes
140
+
141
+ | Provider | Batch Support | Discount | Notes |
142
+ |----------|---------------|----------|-------|
143
+ | Anthropic | Yes | 50% | Uses `message-batches-2024-09-24` beta |
144
+ | OpenAI | Yes | 50% | Results within 24h |
145
+ | OpenRouter | ⚠️ Sync only | - | Batch API not supported |
146
+
147
+ ## Check Batch Status
148
+
149
+ If you ran batch mode with `--no-wait`:
150
+
151
+ ```bash
152
+ .venv/bin/python tip_generator.py --check-batch BATCH_ID -p anthropic
153
+ .venv/bin/python tip_generator.py --check-batch BATCH_ID -p openai --save-results
154
+ ```
155
+
156
+ ## Output
157
+
158
+ Tips are saved to `tips/{category-name}/{uuid}.md` with 8-character random IDs:
159
+
160
+ ```
161
+ tips/
162
+ ├── core-service/
163
+ │ ├── a1b2c3d4.md
164
+ │ └── e5f6g7h8.md
165
+ └── rare-drush-command/
166
+ └── 9i0j1k2l.md
167
+ ```
168
+
169
+ Each file has frontmatter:
170
+
171
+ ```markdown
172
+ ---
173
+ category: core-service
174
+ title: [Generated title]
175
+ ---
176
+
177
+ [Tip content]
178
+ ```
179
+
180
+ ## Configuration
181
+
182
+ Categories and the prompt template are defined in `config.json`:
183
+
184
+ ```json
185
+ {
186
+ "prompt_template": "Generate a Drupal tip for category #{cat_id}: {cat_desc}...",
187
+ "code_language": "php",
188
+ "tips_dir": "/path/to/custom/tips",
189
+ "categories": {
190
+ "1": {"name": "proposed-new-module", "desc": "Proposed new module"},
191
+ "35": {"name": "core-service", "desc": "Lesser-known core service"}
192
+ }
193
+ }
194
+ ```
195
+
196
+ ### Tips Directory Configuration
197
+
198
+ The tips directory can be configured via (in priority order):
199
+
200
+ 1. **CLI argument**: `--tips-dir /path/to/tips`
201
+ 2. **Environment variable**: `TIPGEN_TIPS_DIR=/path/to/tips`
202
+ 3. **Config file**: `"tips_dir": "/path/to/tips"` in `config.json`
203
+ 4. **Default**: `tips/` folder in the package directory
204
+
205
+ To add or modify categories, edit `config.json` directly - no code changes needed.
206
+
207
+ ## Development
208
+
209
+ ### Running Tests
210
+
211
+ ```bash
212
+ # Dry run to verify configuration
213
+ .venv/bin/python tip_generator.py -c 35 -n 1 -p openrouter --dry-run
214
+ ```
215
+
216
+ ## Validation
217
+
218
+ Validate generated tips for formatting issues, truncation, and quality:
219
+
220
+ ```bash
221
+ # Validate a single file
222
+ .venv/bin/python tip_generator.py --validate --validate-file tips/core-service/a1b2c3d4.md
223
+
224
+ # Validate all tips in a category
225
+ .venv/bin/python tip_generator.py --validate --validate-category core-service
226
+
227
+ # Validate ALL tips across all categories
228
+ .venv/bin/python tip_generator.py --validate --validate-all
229
+ ```
230
+
231
+ ### Validation Checks
232
+
233
+ - **Formatting**: Frontmatter structure, code block balance, line counts
234
+ - **Completeness**: Truncation patterns (trailing `...`, `[TODO]`, incomplete code blocks)
235
+ - **Quality**: Generic openings, placeholder text, excessive code ratio
236
+ - **Fake Content**: Non-existent Drupal APIs, hallucinated functions, wrong service names
237
+
238
+ ## Web Viewer
239
+
240
+ A simple web UI to browse tips:
241
+
242
+ ```bash
243
+ pip install flask
244
+ python tip_viewer.py # http://localhost:5000
245
+ python tip_viewer.py --port 8080 # Custom port
246
+ python tip_viewer.py --host 0.0.0.0 # Public access
247
+ python tip_viewer.py --debug # Debug mode
248
+ ```
249
+
250
+ Features:
251
+ - Filter tips by category
252
+ - Get random tip with one click
253
+ - View all tips or browse by category
@@ -0,0 +1,105 @@
1
+ # Publishing tip-generator to PyPI
2
+
3
+ ## Prerequisites
4
+
5
+ - Python 3.11+
6
+ - PyPI account with API token
7
+ - Git repository with push access
8
+
9
+ ## Setup
10
+
11
+ ### 1. Install build tools
12
+
13
+ ```bash
14
+ pip install --upgrade build twine
15
+ ```
16
+
17
+ ### 2. Configure PyPI credentials
18
+
19
+ Create `~/.pypirc`:
20
+
21
+ ```ini
22
+ [pypi]
23
+ username = __token__
24
+ password = pypi-...
25
+ ```
26
+
27
+ Or use environment variable:
28
+
29
+ ```bash
30
+ export TWINE_USERNAME=__token__
31
+ export TWINE_PASSWORD=pypi-...
32
+ ```
33
+
34
+ ## Build
35
+
36
+ ```bash
37
+ # Clean previous builds
38
+ rm -rf dist/ build/ src/*.egg-info
39
+
40
+ # Build package
41
+ python -m build
42
+ ```
43
+
44
+ Output:
45
+ - `dist/tip_generator-X.X.X-py3-none-any.whl`
46
+ - `dist/tip_generator-X.X.X.tar.gz`
47
+
48
+ ## Publish
49
+
50
+ ### Manual publish
51
+
52
+ ```bash
53
+ # Check package before upload
54
+ twine check dist/*
55
+
56
+ # Upload to PyPI
57
+ twine upload dist/*
58
+ ```
59
+
60
+ ### Automated publish via GitHub Actions
61
+
62
+ The workflow `.github/workflows/publish.yml` automatically publishes on tag push:
63
+
64
+ ```bash
65
+ # Update version in pyproject.toml first
66
+ # Then create and push tag
67
+ git tag v0.1.0
68
+ git push origin v0.1.0
69
+ ```
70
+
71
+ ## Version Bumping
72
+
73
+ 1. Update `version` in `pyproject.toml`
74
+ 2. Update `__version__` in `src/tip_generator/__init__.py`
75
+ 3. Commit changes
76
+ 4. Create tag matching version
77
+
78
+ ```bash
79
+ # Example: bump to 0.2.0
80
+ sed -i 's/version = "0.1.0"/version = "0.2.0"/' pyproject.toml
81
+ sed -i 's/__version__ = "0.1.0"/__version__ = "0.2.0"/' src/tip_generator/__init__.py
82
+ git commit -am "Bump version to 0.2.0"
83
+ git tag v0.2.0
84
+ git push origin master --tags
85
+ ```
86
+
87
+ ## Test Publishing (TestPyPI)
88
+
89
+ ```bash
90
+ # Build
91
+ python -m build
92
+
93
+ # Upload to TestPyPI first
94
+ twine upload --repository testpypi dist/*
95
+
96
+ # Test install
97
+ pip install --index-url https://test.pypi.org/simple/ tip-generator
98
+ ```
99
+
100
+ ## Verify Installation
101
+
102
+ ```bash
103
+ pip install tip-generator
104
+ drupal-tip-generator --help
105
+ ```
@@ -0,0 +1,229 @@
1
+ # Drupal Tip Generator
2
+
3
+ Generate static MD tip files for the `drupal-tip` skill using various LLM providers.
4
+
5
+ ## Setup
6
+
7
+ ### 1. Create Virtual Environment
8
+
9
+ ```bash
10
+ cd ~/.claude/skills/drupal-tip
11
+ python3 -m venv .venv
12
+ source .venv/bin/activate
13
+ pip install openai anthropic
14
+ ```
15
+
16
+ ### 2. Configure API Keys
17
+
18
+ Copy the example environment file and add your keys:
19
+
20
+ ```bash
21
+ cp .env.example .env
22
+ ```
23
+
24
+ Edit `.env` with your API keys (use `TIPGEN_` prefix):
25
+
26
+ ```env
27
+ TIPGEN_ANTHROPIC_API_KEY=sk-ant-...
28
+ TIPGEN_OPENAI_API_KEY=sk-...
29
+ TIPGEN_OPENROUTER_API_KEY=sk-or-...
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ ### Get a Random Existing Tip (FAST!)
35
+
36
+ Get a tip from the pre-generated database instantly — no API call needed:
37
+
38
+ ```bash
39
+ .venv/bin/python tip_generator.py --random-tip
40
+ .venv/bin/python tip_generator.py --random-tip --tip-category core-service
41
+ .venv/bin/python tip_generator.py --list-existing
42
+ ```
43
+
44
+ ### List Available Categories
45
+
46
+ ```bash
47
+ .venv/bin/python tip_generator.py --list-categories
48
+ ```
49
+
50
+ ### Generate Tips
51
+
52
+ **Using Anthropic:**
53
+ ```bash
54
+ .venv/bin/python tip_generator.py -c 35 -n 5 -p anthropic
55
+ ```
56
+
57
+ **Using OpenAI (batch mode - 50% cheaper):**
58
+ ```bash
59
+ .venv/bin/python tip_generator.py -c 35 -n 5 -p openai
60
+ ```
61
+
62
+ **Using OpenRouter:**
63
+ ```bash
64
+ .venv/bin/python tip_generator.py -c 35 -n 5 -p openrouter
65
+ ```
66
+
67
+ ### Arguments
68
+
69
+ | Argument | Description |
70
+ |----------|-------------|
71
+ | `-c, --category` | Category number(s) or `all` |
72
+ | `-n, --count` | Number of tips per category (default: 5) |
73
+ | `-p, --provider` | LLM provider: `anthropic`, `openai`, `openrouter` |
74
+ | `-m, --model` | Override default model |
75
+ | `-u, --api-url` | Custom API URL for OpenAI/Anthropic-compatible endpoints |
76
+ | `-t, --max-tokens` | Maximum tokens for response (default: 4096) |
77
+ | `--tips-dir` | Custom tips directory (or set `TIPGEN_TIPS_DIR` env var or `tips_dir` in config.json) |
78
+ | `--save-truncated` | Save tips even if truncated (use with caution) |
79
+ | `--no-wait` | Don't wait for batch completion |
80
+ | `--dry-run` | Show what would be done without calling API |
81
+ | `--list-categories` | List all available categories |
82
+ | `--random-tip` | Get a random existing tip (fast, no API) |
83
+ | `--list-existing` | List categories with existing tips |
84
+ | `--tip-category` | Filter random tip by category name |
85
+ | `--validate` | Enable validation mode |
86
+ | `--validate-file` | Validate a specific tip file |
87
+ | `--validate-category` | Validate all tips in a category |
88
+ | `--validate-all` | Validate all tips across all categories |
89
+
90
+ ### Examples
91
+
92
+ ```bash
93
+ # Generate 3 tips for category 35 (core-service)
94
+ .venv/bin/python tip_generator.py -c 35 -n 3 -p openrouter
95
+
96
+ # Generate 5 tips for multiple categories
97
+ .venv/bin/python tip_generator.py -c 35,36,37 -n 5 -p openrouter
98
+
99
+ # Generate 1 tip for ALL categories
100
+ .venv/bin/python tip_generator.py -c all -n 1 -p openrouter
101
+
102
+ # Use a specific model
103
+ .venv/bin/python tip_generator.py -c 35 -n 5 -p openrouter -m anthropic/claude-opus-4
104
+
105
+ # Use a custom API URL (e.g., Together.xyz, local LLM server)
106
+ .venv/bin/python tip_generator.py -c 35 -n 5 -p openai -u https://api.together.xyz/v1
107
+
108
+ # Increase max tokens for longer responses (avoid truncation)
109
+ .venv/bin/python tip_generator.py -c 60 -n 20 -p openai --max-tokens 8192
110
+
111
+ # Save tips even if truncated (use with caution)
112
+ .venv/bin/python tip_generator.py -c 35 -n 5 -p openai --save-truncated
113
+ ```
114
+
115
+ ## Batch API Notes
116
+
117
+ | Provider | Batch Support | Discount | Notes |
118
+ |----------|---------------|----------|-------|
119
+ | Anthropic | Yes | 50% | Uses `message-batches-2024-09-24` beta |
120
+ | OpenAI | Yes | 50% | Results within 24h |
121
+ | OpenRouter | ⚠️ Sync only | - | Batch API not supported |
122
+
123
+ ## Check Batch Status
124
+
125
+ If you ran batch mode with `--no-wait`:
126
+
127
+ ```bash
128
+ .venv/bin/python tip_generator.py --check-batch BATCH_ID -p anthropic
129
+ .venv/bin/python tip_generator.py --check-batch BATCH_ID -p openai --save-results
130
+ ```
131
+
132
+ ## Output
133
+
134
+ Tips are saved to `tips/{category-name}/{uuid}.md` with 8-character random IDs:
135
+
136
+ ```
137
+ tips/
138
+ ├── core-service/
139
+ │ ├── a1b2c3d4.md
140
+ │ └── e5f6g7h8.md
141
+ └── rare-drush-command/
142
+ └── 9i0j1k2l.md
143
+ ```
144
+
145
+ Each file has frontmatter:
146
+
147
+ ```markdown
148
+ ---
149
+ category: core-service
150
+ title: [Generated title]
151
+ ---
152
+
153
+ [Tip content]
154
+ ```
155
+
156
+ ## Configuration
157
+
158
+ Categories and the prompt template are defined in `config.json`:
159
+
160
+ ```json
161
+ {
162
+ "prompt_template": "Generate a Drupal tip for category #{cat_id}: {cat_desc}...",
163
+ "code_language": "php",
164
+ "tips_dir": "/path/to/custom/tips",
165
+ "categories": {
166
+ "1": {"name": "proposed-new-module", "desc": "Proposed new module"},
167
+ "35": {"name": "core-service", "desc": "Lesser-known core service"}
168
+ }
169
+ }
170
+ ```
171
+
172
+ ### Tips Directory Configuration
173
+
174
+ The tips directory can be configured via (in priority order):
175
+
176
+ 1. **CLI argument**: `--tips-dir /path/to/tips`
177
+ 2. **Environment variable**: `TIPGEN_TIPS_DIR=/path/to/tips`
178
+ 3. **Config file**: `"tips_dir": "/path/to/tips"` in `config.json`
179
+ 4. **Default**: `tips/` folder in the package directory
180
+
181
+ To add or modify categories, edit `config.json` directly - no code changes needed.
182
+
183
+ ## Development
184
+
185
+ ### Running Tests
186
+
187
+ ```bash
188
+ # Dry run to verify configuration
189
+ .venv/bin/python tip_generator.py -c 35 -n 1 -p openrouter --dry-run
190
+ ```
191
+
192
+ ## Validation
193
+
194
+ Validate generated tips for formatting issues, truncation, and quality:
195
+
196
+ ```bash
197
+ # Validate a single file
198
+ .venv/bin/python tip_generator.py --validate --validate-file tips/core-service/a1b2c3d4.md
199
+
200
+ # Validate all tips in a category
201
+ .venv/bin/python tip_generator.py --validate --validate-category core-service
202
+
203
+ # Validate ALL tips across all categories
204
+ .venv/bin/python tip_generator.py --validate --validate-all
205
+ ```
206
+
207
+ ### Validation Checks
208
+
209
+ - **Formatting**: Frontmatter structure, code block balance, line counts
210
+ - **Completeness**: Truncation patterns (trailing `...`, `[TODO]`, incomplete code blocks)
211
+ - **Quality**: Generic openings, placeholder text, excessive code ratio
212
+ - **Fake Content**: Non-existent Drupal APIs, hallucinated functions, wrong service names
213
+
214
+ ## Web Viewer
215
+
216
+ A simple web UI to browse tips:
217
+
218
+ ```bash
219
+ pip install flask
220
+ python tip_viewer.py # http://localhost:5000
221
+ python tip_viewer.py --port 8080 # Custom port
222
+ python tip_viewer.py --host 0.0.0.0 # Public access
223
+ python tip_viewer.py --debug # Debug mode
224
+ ```
225
+
226
+ Features:
227
+ - Filter tips by category
228
+ - Get random tip with one click
229
+ - View all tips or browse by category