git-cai-cli 0.16.2__tar.gz → 0.17.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 (113) hide show
  1. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.linters/lychee.toml +4 -1
  2. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/PKG-INFO +36 -7
  3. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/README.md +35 -6
  4. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/docs/git-cai.txt +81 -11
  5. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/docs/man/git-cai.1 +181 -13
  6. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/_version.py +3 -3
  7. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/cli/cli.py +10 -0
  8. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/completion.py +9 -3
  9. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/config.py +46 -6
  10. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/doctor.py +5 -4
  11. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/generation.py +3 -3
  12. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/llm.py +42 -15
  13. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/options.py +21 -0
  14. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/pr.py +3 -3
  15. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/squash.py +4 -4
  16. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/validate.py +27 -1
  17. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/main.py +2 -2
  18. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli.egg-info/PKG-INFO +36 -7
  19. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli.egg-info/SOURCES.txt +1 -0
  20. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli.egg-info/scm_file_list.json +1 -0
  21. git_cai_cli-0.17.0/src/git_cai_cli.egg-info/scm_version.json +8 -0
  22. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_completion.py +9 -24
  23. git_cai_cli-0.17.0/tests/unit/test_custom_provider.py +208 -0
  24. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/uv.lock +88 -88
  25. git_cai_cli-0.16.2/src/git_cai_cli.egg-info/scm_version.json +0 -8
  26. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.caiignore +0 -0
  27. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.gitattributes +0 -0
  28. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.github/cd/.SRCINFO +0 -0
  29. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.github/cd/PKGBUILD +0 -0
  30. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.github/ci/_version.py +0 -0
  31. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.github/ci/cai_config.ci.yml +0 -0
  32. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.github/ci/tokens.ci.yml +0 -0
  33. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.github/workflows/python-tests.yml +0 -0
  34. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.github/workflows/release.yml +0 -0
  35. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.github/workflows/release_aur.yml +0 -0
  36. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.gitignore +0 -0
  37. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.linters/.bandit.yml +0 -0
  38. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.linters/.checkov.yml +0 -0
  39. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.linters/.flake8 +0 -0
  40. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.linters/.ls-lint.yml +0 -0
  41. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.linters/.markdownlint.json +0 -0
  42. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.linters/.proselintrc.json +0 -0
  43. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.linters/.pylintrc +0 -0
  44. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.linters/.yamllint.yml +0 -0
  45. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.linters/check_git_branch_name.sh +0 -0
  46. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.linters/pyrightconfig.json +0 -0
  47. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.markdownlintignore +0 -0
  48. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.mega-linter.yml +0 -0
  49. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.semgrepignore +0 -0
  50. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/.trivyignore +0 -0
  51. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/CLAUDE.md +0 -0
  52. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/LICENSE +0 -0
  53. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/Makefile +0 -0
  54. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/cai_config.yml +0 -0
  55. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/pyproject.toml +0 -0
  56. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/setup.cfg +0 -0
  57. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/__init__.py +0 -0
  58. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/cli/__init__.py +0 -0
  59. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/cli/helptext.py +0 -0
  60. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/cli/modes.py +0 -0
  61. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/__init__.py +0 -0
  62. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/changelog.py +0 -0
  63. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/explain.py +0 -0
  64. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/gitutils.py +0 -0
  65. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/init.py +0 -0
  66. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/languages.py +0 -0
  67. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/prompts_fallback.py +0 -0
  68. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/release.py +0 -0
  69. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/secrets.py +0 -0
  70. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/spinner.py +0 -0
  71. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/split.py +0 -0
  72. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli/core/stats.py +0 -0
  73. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli.egg-info/dependency_links.txt +0 -0
  74. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli.egg-info/entry_points.txt +0 -0
  75. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli.egg-info/requires.txt +0 -0
  76. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/src/git_cai_cli.egg-info/top_level.txt +0 -0
  77. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/conftest.py +0 -0
  78. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/integration/test_cli_integration.py +0 -0
  79. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/integration/test_config_integration.py +0 -0
  80. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/integration/test_gitutils_integration.py +0 -0
  81. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/integration/test_modes_integration.py +0 -0
  82. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/integration/test_options_integration.py +0 -0
  83. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/integration/test_pr_integration.py +0 -0
  84. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/integration/test_squash_integration.py +0 -0
  85. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_amend.py +0 -0
  86. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_branch_context.py +0 -0
  87. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_changelog.py +0 -0
  88. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_classification.py +0 -0
  89. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_cli.py +0 -0
  90. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_config.py +0 -0
  91. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_conventional.py +0 -0
  92. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_doctor.py +0 -0
  93. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_explain.py +0 -0
  94. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_generation.py +0 -0
  95. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_gitutils.py +0 -0
  96. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_helptext.py +0 -0
  97. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_init.py +0 -0
  98. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_llm.py +0 -0
  99. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_main.py +0 -0
  100. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_modes.py +0 -0
  101. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_options.py +0 -0
  102. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_pr.py +0 -0
  103. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_print.py +0 -0
  104. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_prompt_loading.py +0 -0
  105. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_release.py +0 -0
  106. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_secrets.py +0 -0
  107. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_set_config.py +0 -0
  108. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_signoff.py +0 -0
  109. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_spinner.py +0 -0
  110. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_split.py +0 -0
  111. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_squash.py +0 -0
  112. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_stats.py +0 -0
  113. {git_cai_cli-0.16.2 → git_cai_cli-0.17.0}/tests/unit/test_validate.py +0 -0
@@ -8,7 +8,10 @@ accept = ["200", "429"]
8
8
 
9
9
  exclude = [
10
10
  "https://megalinter.io/configuration/",
11
- "file:///tmp/lint/dwh/models/logo.png"
11
+ "file:///tmp/lint/dwh/models/logo.png",
12
+ # Example endpoints in the custom provider docs, not browsable pages.
13
+ "^http://localhost",
14
+ "^https://openrouter\\.ai/api/v1$",
12
15
  ]
13
16
 
14
17
  exclude_path = [
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: git-cai-cli
3
- Version: 0.16.2
3
+ Version: 0.17.0
4
4
  Summary: Use LLM to create git commit messages
5
5
  Author-email: Thorsten Foltz <thorsten.foltz@live.com>
6
6
  License-Expression: MIT
@@ -49,6 +49,7 @@ Currently supported providers:
49
49
  - Mistral
50
50
  - DeepSeek
51
51
  - Ollama (local)
52
+ - Any OpenAI compatible API (OpenRouter, Together, Cerebras, LM Studio, vLLM, llama.cpp, LiteLLM, ...) via `base_url`
52
53
 
53
54
  ---
54
55
 
@@ -58,6 +59,7 @@ Currently supported providers:
58
59
  - [pipx](https://pypi.org/project/pipx/)
59
60
  - Either:
60
61
  - Ollama installed and running locally, or
62
+ - A local OpenAI compatible server such as LM Studio or vLLM, or
61
63
  - An API key for at least one of the following providers:
62
64
  - OpenAI
63
65
  - Gemini (free tier available)
@@ -74,7 +76,7 @@ Currently supported providers:
74
76
  - Automatically detects added, modified, and deleted files
75
77
  - Generates meaningful, context-aware commit messages using an LLM
76
78
  - Seamless integration with Git
77
- - Supports multiple LLM providers and models
79
+ - Supports multiple LLM providers and models, plus any OpenAI compatible endpoint
78
80
  - Global configuration with per-repository overrides
79
81
  - Interactive `--init` wizard for first-time setup (provider, token, language, style)
80
82
  - Repository-specific language, style, and model selection
@@ -93,7 +95,7 @@ Currently supported providers:
93
95
  - Optional large-diff guard (`max_diff_bytes`) that truncates oversized diffs before sending
94
96
  - Generation time measurement
95
97
  - Local-only usage analytics (per-provider commits, tokens, latency) with opt-in SQLite storage
96
- - Shell completion for bash, zsh, and fish
98
+ - Shell completion for bash, zsh, and fish (including custom providers from your config)
97
99
  - Local secret scan that blocks the diff before it reaches the provider when likely credentials are detected
98
100
  - Configuration doctor (`--check`) that validates your setup offline, with an optional live provider probe (`--ping`)
99
101
  - Mixed code and documentation diffs are classified by the functional change rather than mislabelled as docs
@@ -188,6 +190,27 @@ Set your preferred LLM in `cai_config.yml` (Groq by default).
188
190
 
189
191
  If you want to use Ollama, install it, set `default: ollama` and configure the `ollama:` block (model/temperature). Ollama is automatically started when used.
190
192
 
193
+ ### Custom OpenAI compatible providers
194
+
195
+ Any service speaking the OpenAI `/chat/completions` API can be added as a provider.
196
+ Pick a name, add a block with `base_url` and `model`, and set `default:` to that name:
197
+
198
+ ```yaml
199
+ default: openrouter
200
+ openrouter:
201
+ base_url: https://openrouter.ai/api/v1
202
+ model: meta-llama/llama-3.3-70b-instruct:free
203
+ lmstudio:
204
+ base_url: http://localhost:1234/v1
205
+ model: qwen2.5-coder
206
+ requires_token: false
207
+ ```
208
+
209
+ The API key goes into `tokens.yml` under the same name (`openrouter: sk-or-...`).
210
+ With `requires_token: false` no key is needed. `/chat/completions` is appended to
211
+ `base_url` unless it is already there. The name works with `-P` / `--provider`
212
+ and shows up in `git cai -l provider` and shell completion.
213
+
191
214
  ### Custom prompts (Markdown)
192
215
 
193
216
  The generated commit message is guided by prompt files.
@@ -247,6 +270,10 @@ git cai -g
247
270
  - `style` – tone or style of the commit message
248
271
  - `emoji` – enable or disable emojis
249
272
  - `load_tokens_from` – path to the file where API tokens are stored
273
+ - `base_url` – per provider block: endpoint of a custom OpenAI compatible provider, or a proxy/gateway for a built in one.
274
+ OpenAI style providers include the version (`https://gateway.example/v1`); `anthropic` and `gemini` take the host without it (`https://gateway.example`)
275
+ - `requires_token` – per provider block: set to `false` for custom providers that need no API key; default `true`
276
+ - `max_output_tokens` – per provider block: cap on the reply length for Anthropic and OpenAI compatible providers; only sent when set
250
277
  - `prompt_file` - path to the file where the prompt for the commit is stored
251
278
  - `squash_prompt_file` - path to the file where the prompt for the squash is stored
252
279
  - `full_files_prompt_file` - path to the prompt used when `-F` / `--full-files` attaches full file contents
@@ -264,7 +291,8 @@ git cai -g
264
291
  No diff content, commit messages, or file paths are stored — only metadata (provider, model, kind, repo name, token counts, latency, settings)
265
292
  - `signoff` – append a `Signed-off-by:` trailer (built from git `user.name` / `user.email`) to every commit message; default `false`
266
293
  - `secret_scan` – scan the outgoing diff for likely secrets and ask before sending; default `true`. Bypass once with `-B` / `--allow-secrets`,
267
- or disable entirely by setting it to `false`. Skipped for tokenless providers (Ollama), where nothing leaves the machine
294
+ or disable entirely by setting it to `false`. Skipped for tokenless providers (Ollama), where nothing leaves the machine.
295
+ Custom providers are always scanned, even with `requires_token: false`, since the diff may leave the machine
268
296
 
269
297
  ---
270
298
 
@@ -286,13 +314,13 @@ In addition to `git cai`, the following options are available:
286
314
  - `-H`, `--set-home` – set a config value in home config (`key=value`), always targets `~/.config/cai/`
287
315
  - `-h`, `--help` – show help and available commands
288
316
  - `-I`, `--init` – interactive setup wizard (writes home config and tokens.yml)
289
- - `-i`, `--install-completion` – install shell completion for bash, zsh, or fish
317
+ - `-i`, `--install-completion` – install shell completion for bash, zsh, or fish. Rerun after upgrading to get custom provider completion
290
318
  - `-k`, `--check` – run configuration diagnostics offline (config source, provider, token, prompts, editor, style)
291
319
  - `-l`, `--list` – list available information. Valid types: `config`, `editor`, `language`, `model`, `path`, `provider`, `style`
292
320
  - `-m`, `--model` – override the model for this invocation (requires `-P`)
293
321
  - `-n`, `--ping` – with `--check`, also send a tiny request to the active provider to confirm reachability
294
322
  - `-o`, `--signoff` / `--no-signoff` – append a `Signed-off-by:` trailer (uses git `user.name` / `user.email`); applies to commit, amend, and squash modes
295
- - `-P`, `--provider` – override the LLM provider for this invocation
323
+ - `-P`, `--provider` – override the LLM provider for this invocation (built in or custom; tab completion lists both)
296
324
  - `-p`, `--generate-prompts` – generate default `commit_prompt.md` and `squash_prompt.md` in the current directory (for customization)
297
325
  - `--print` – print the generated commit message to stdout and exit without committing (commit/amend modes only; mutually exclusive with `-c`)
298
326
  - `-q`, `--sql true|false` – override stats writing for this run (wins over the persisted `stats` config)
@@ -511,7 +539,8 @@ git cai -S secret_scan=false # disable the scan persistently
511
539
 
512
540
  Obvious placeholders (`example`, `dummy`, repeated filler, and similar) are
513
541
  ignored to keep the noise down, and the scan is skipped entirely for tokenless
514
- providers such as Ollama, where nothing leaves the machine. In non-interactive
542
+ providers such as Ollama, where nothing leaves the machine. Custom providers are
543
+ always scanned, even with `requires_token: false`. In non-interactive
515
544
  runs (`-c` / `--crazy`, or no TTY) a detection aborts the send instead of
516
545
  prompting; re-run with `-B` to override.
517
546
 
@@ -20,6 +20,7 @@ Currently supported providers:
20
20
  - Mistral
21
21
  - DeepSeek
22
22
  - Ollama (local)
23
+ - Any OpenAI compatible API (OpenRouter, Together, Cerebras, LM Studio, vLLM, llama.cpp, LiteLLM, ...) via `base_url`
23
24
 
24
25
  ---
25
26
 
@@ -29,6 +30,7 @@ Currently supported providers:
29
30
  - [pipx](https://pypi.org/project/pipx/)
30
31
  - Either:
31
32
  - Ollama installed and running locally, or
33
+ - A local OpenAI compatible server such as LM Studio or vLLM, or
32
34
  - An API key for at least one of the following providers:
33
35
  - OpenAI
34
36
  - Gemini (free tier available)
@@ -45,7 +47,7 @@ Currently supported providers:
45
47
  - Automatically detects added, modified, and deleted files
46
48
  - Generates meaningful, context-aware commit messages using an LLM
47
49
  - Seamless integration with Git
48
- - Supports multiple LLM providers and models
50
+ - Supports multiple LLM providers and models, plus any OpenAI compatible endpoint
49
51
  - Global configuration with per-repository overrides
50
52
  - Interactive `--init` wizard for first-time setup (provider, token, language, style)
51
53
  - Repository-specific language, style, and model selection
@@ -64,7 +66,7 @@ Currently supported providers:
64
66
  - Optional large-diff guard (`max_diff_bytes`) that truncates oversized diffs before sending
65
67
  - Generation time measurement
66
68
  - Local-only usage analytics (per-provider commits, tokens, latency) with opt-in SQLite storage
67
- - Shell completion for bash, zsh, and fish
69
+ - Shell completion for bash, zsh, and fish (including custom providers from your config)
68
70
  - Local secret scan that blocks the diff before it reaches the provider when likely credentials are detected
69
71
  - Configuration doctor (`--check`) that validates your setup offline, with an optional live provider probe (`--ping`)
70
72
  - Mixed code and documentation diffs are classified by the functional change rather than mislabelled as docs
@@ -159,6 +161,27 @@ Set your preferred LLM in `cai_config.yml` (Groq by default).
159
161
 
160
162
  If you want to use Ollama, install it, set `default: ollama` and configure the `ollama:` block (model/temperature). Ollama is automatically started when used.
161
163
 
164
+ ### Custom OpenAI compatible providers
165
+
166
+ Any service speaking the OpenAI `/chat/completions` API can be added as a provider.
167
+ Pick a name, add a block with `base_url` and `model`, and set `default:` to that name:
168
+
169
+ ```yaml
170
+ default: openrouter
171
+ openrouter:
172
+ base_url: https://openrouter.ai/api/v1
173
+ model: meta-llama/llama-3.3-70b-instruct:free
174
+ lmstudio:
175
+ base_url: http://localhost:1234/v1
176
+ model: qwen2.5-coder
177
+ requires_token: false
178
+ ```
179
+
180
+ The API key goes into `tokens.yml` under the same name (`openrouter: sk-or-...`).
181
+ With `requires_token: false` no key is needed. `/chat/completions` is appended to
182
+ `base_url` unless it is already there. The name works with `-P` / `--provider`
183
+ and shows up in `git cai -l provider` and shell completion.
184
+
162
185
  ### Custom prompts (Markdown)
163
186
 
164
187
  The generated commit message is guided by prompt files.
@@ -218,6 +241,10 @@ git cai -g
218
241
  - `style` – tone or style of the commit message
219
242
  - `emoji` – enable or disable emojis
220
243
  - `load_tokens_from` – path to the file where API tokens are stored
244
+ - `base_url` – per provider block: endpoint of a custom OpenAI compatible provider, or a proxy/gateway for a built in one.
245
+ OpenAI style providers include the version (`https://gateway.example/v1`); `anthropic` and `gemini` take the host without it (`https://gateway.example`)
246
+ - `requires_token` – per provider block: set to `false` for custom providers that need no API key; default `true`
247
+ - `max_output_tokens` – per provider block: cap on the reply length for Anthropic and OpenAI compatible providers; only sent when set
221
248
  - `prompt_file` - path to the file where the prompt for the commit is stored
222
249
  - `squash_prompt_file` - path to the file where the prompt for the squash is stored
223
250
  - `full_files_prompt_file` - path to the prompt used when `-F` / `--full-files` attaches full file contents
@@ -235,7 +262,8 @@ git cai -g
235
262
  No diff content, commit messages, or file paths are stored — only metadata (provider, model, kind, repo name, token counts, latency, settings)
236
263
  - `signoff` – append a `Signed-off-by:` trailer (built from git `user.name` / `user.email`) to every commit message; default `false`
237
264
  - `secret_scan` – scan the outgoing diff for likely secrets and ask before sending; default `true`. Bypass once with `-B` / `--allow-secrets`,
238
- or disable entirely by setting it to `false`. Skipped for tokenless providers (Ollama), where nothing leaves the machine
265
+ or disable entirely by setting it to `false`. Skipped for tokenless providers (Ollama), where nothing leaves the machine.
266
+ Custom providers are always scanned, even with `requires_token: false`, since the diff may leave the machine
239
267
 
240
268
  ---
241
269
 
@@ -257,13 +285,13 @@ In addition to `git cai`, the following options are available:
257
285
  - `-H`, `--set-home` – set a config value in home config (`key=value`), always targets `~/.config/cai/`
258
286
  - `-h`, `--help` – show help and available commands
259
287
  - `-I`, `--init` – interactive setup wizard (writes home config and tokens.yml)
260
- - `-i`, `--install-completion` – install shell completion for bash, zsh, or fish
288
+ - `-i`, `--install-completion` – install shell completion for bash, zsh, or fish. Rerun after upgrading to get custom provider completion
261
289
  - `-k`, `--check` – run configuration diagnostics offline (config source, provider, token, prompts, editor, style)
262
290
  - `-l`, `--list` – list available information. Valid types: `config`, `editor`, `language`, `model`, `path`, `provider`, `style`
263
291
  - `-m`, `--model` – override the model for this invocation (requires `-P`)
264
292
  - `-n`, `--ping` – with `--check`, also send a tiny request to the active provider to confirm reachability
265
293
  - `-o`, `--signoff` / `--no-signoff` – append a `Signed-off-by:` trailer (uses git `user.name` / `user.email`); applies to commit, amend, and squash modes
266
- - `-P`, `--provider` – override the LLM provider for this invocation
294
+ - `-P`, `--provider` – override the LLM provider for this invocation (built in or custom; tab completion lists both)
267
295
  - `-p`, `--generate-prompts` – generate default `commit_prompt.md` and `squash_prompt.md` in the current directory (for customization)
268
296
  - `--print` – print the generated commit message to stdout and exit without committing (commit/amend modes only; mutually exclusive with `-c`)
269
297
  - `-q`, `--sql true|false` – override stats writing for this run (wins over the persisted `stats` config)
@@ -482,7 +510,8 @@ git cai -S secret_scan=false # disable the scan persistently
482
510
 
483
511
  Obvious placeholders (`example`, `dummy`, repeated filler, and similar) are
484
512
  ignored to keep the noise down, and the scan is skipped entirely for tokenless
485
- providers such as Ollama, where nothing leaves the machine. In non-interactive
513
+ providers such as Ollama, where nothing leaves the machine. Custom providers are
514
+ always scanned, even with `requires_token: false`. In non-interactive
486
515
  runs (`-c` / `--crazy`, or no TTY) a detection aborts the send instead of
487
516
  prompting; re-run with `-B` to override.
488
517
 
@@ -73,7 +73,8 @@ First run / configuration (manual):
73
73
  - Add at least one API key to `~/.config/cai/tokens.yml` (created as a template if missing).
74
74
  The YAML keys are provider names (for example: `openai`, `anthropic`, `gemini`,
75
75
  `groq`, `xai`, `mistral`, `deepseek`).
76
- If you use `ollama` as provider, no token is required.
76
+ If you use `ollama` as provider, no token is required. Custom providers use
77
+ their own name as key (see below).
77
78
  - In `~/.config/cai/cai_config.yml`, set `default:` to the provider you want and
78
79
  adjust the provider block (model/temperature) as needed.
79
80
 
@@ -89,6 +90,46 @@ Custom prompts (optional):
89
90
  - Generate prompt files in the current directory with `git cai -p`.
90
91
  - Point `prompt_file` / `squash_prompt_file` in `cai_config.yml` to your custom files.
91
92
 
93
+ Custom OpenAI compatible providers (optional):
94
+
95
+ - Any service speaking the OpenAI `/chat/completions` API (OpenRouter, Together,
96
+ Cerebras, GitHub Models, LiteLLM, vLLM, LM Studio, llama.cpp, ...) can be added
97
+ as a provider. Pick a name, add a block with `base_url` and `model`, and set
98
+ `default:` to that name:
99
+
100
+ default: openrouter
101
+ openrouter:
102
+ base_url: https://openrouter.ai/api/v1
103
+ model: meta-llama/llama-3.3-70b-instruct:free
104
+ temperature: 0 # optional
105
+ timeout: 60 # optional
106
+ max_output_tokens: 2048 # optional, cap on the reply length
107
+ lmstudio:
108
+ base_url: http://localhost:1234/v1
109
+ model: qwen2.5-coder
110
+ requires_token: false # optional, default true
111
+
112
+ - `/chat/completions` is appended to `base_url` unless it is already there.
113
+ - The API key goes into `~/.config/cai/tokens.yml` under the same name
114
+ (`openrouter: sk-or-...`). With `requires_token: false` no key is needed and
115
+ no `Authorization` header is sent.
116
+ - The name works with `--provider` (`git cai -P lmstudio`), is listed by
117
+ `git cai -l provider`, and is offered by shell completion.
118
+ - `max_output_tokens` is only sent when set. Useful for local servers whose
119
+ default reply limit truncates commit messages. It is sent as `max_tokens`,
120
+ or as `max_completion_tokens` for the `openai` block.
121
+ - `base_url` also works in the built in blocks to route them through a proxy or
122
+ gateway. Use the same form as the vendor SDKs:
123
+ `openai`, `deepseek`, `groq`, `mistral`, `xai`: include the version,
124
+ e.g. `https://gateway.example/v1` (`/chat/completions` is appended);
125
+ `anthropic`: without version, e.g. `https://gateway.example`
126
+ (`/v1/messages` is appended);
127
+ `gemini`: without version, e.g. `https://gateway.example`
128
+ (`/v1beta/models/<model>:generateContent` is appended).
129
+ `ollama` keeps using the `OLLAMA_HOST` environment variable.
130
+ - The secret scan stays active for custom providers, including local ones.
131
+ Set `secret_scan: false` to disable it.
132
+
92
133
  OPTIONS
93
134
  -------
94
135
  -A, --amend::
@@ -349,7 +390,10 @@ git cai -I
349
390
 
350
391
  -i, --install-completion::
351
392
  Install shell completion for `git cai`. Supports bash, zsh, and fish.
352
- Completions cover all flags and provider names for `--provider`.
393
+ Completions cover all flags and provider names for `--provider`, including
394
+ custom providers from the active config (looked up on each TAB press, so new
395
+ providers show up without reinstalling). Users of an older script need to run
396
+ `git cai -i` once more to get this.
353
397
  +
354
398
  After installation, restart your terminal or source your shell configuration
355
399
  file for the completions to take effect.
@@ -361,8 +405,9 @@ git cai -i
361
405
  -k, --check::
362
406
  Run configuration diagnostics and exit. The check is offline by default: it
363
407
  reports which config is authoritative (repository, home, or built-in), validates
364
- the config keys, confirms the default provider has a model and a
365
- usable token, that the commit/squash/full-files/PR prompts resolve, and that the
408
+ the config keys, confirms the default provider has a model (and shows its
409
+ `base_url` if set) and a usable token (skipped for `ollama` and providers with
410
+ `requires_token: false`), that the commit/squash/full-files/PR prompts resolve, and that the
366
411
  configured editor is on `PATH`. Exits non-zero if any check fails. Add `--ping`
367
412
  to also probe the active provider with a tiny live request.
368
413
  +
@@ -476,11 +521,14 @@ git cai -s --signoff
476
521
  Override the LLM provider for this invocation. The model and temperature
477
522
  from the configuration for that provider are used unless `--model` is also
478
523
  specified. Available providers: `anthropic`, `deepseek`, `gemini`, `groq`,
479
- `mistral`, `ollama`, `openai`, `xai`.
524
+ `mistral`, `ollama`, `openai`, `xai`, plus any custom OpenAI compatible
525
+ provider defined in the active config (see SETUP). Shell completion offers
526
+ both.
480
527
  +
481
528
  ----
482
529
  git cai -P anthropic
483
530
  git cai -P groq -m llama-3.3-70b
531
+ git cai -P openrouter
484
532
  ----
485
533
 
486
534
  -p, --generate-prompts::
@@ -941,7 +989,9 @@ Configuration file paths:
941
989
  provider::
942
990
  List all supported LLM providers. Each provider is shown with its default
943
991
  model and whether an API token is required. Providers that do not require a
944
- token (currently only `ollama`) are marked accordingly.
992
+ token (`ollama`, and custom providers with `requires_token: false`) are
993
+ marked accordingly. Custom OpenAI compatible providers from the active config
994
+ follow in a separate section with their `base_url`.
945
995
  +
946
996
  ----
947
997
  git cai -l provider
@@ -960,6 +1010,11 @@ Supported providers:
960
1010
  ollama model: llama3.1 (no token required)
961
1011
  openai model: gpt-5.4-mini (token required)
962
1012
  xai model: grok-4.3 (token required)
1013
+
1014
+ Custom providers (OpenAI compatible, from config):
1015
+
1016
+ lmstudio model: qwen2.5-coder (no token required) http://localhost:1234/v1
1017
+ openrouter model: meta-llama/llama-3.3-70b-instruct:free (token required) https://openrouter.ai/api/v1
963
1018
  ----
964
1019
 
965
1020
  style::
@@ -1019,7 +1074,8 @@ Available configuration keys:
1019
1074
  credential formats are flagged (private keys, AWS/GitHub/Slack/Google/OpenAI
1020
1075
  keys); obvious placeholders (values containing `example`, `sample`, `dummy`,
1021
1076
  and repeated-character filler) are ignored. Local providers (Ollama) skip the
1022
- scan, since nothing leaves the machine. When you confirm a flagged send in an
1077
+ scan, since nothing leaves the machine. Custom providers are always scanned,
1078
+ even with `requires_token: false`, since the diff may leave the machine. When you confirm a flagged send in an
1023
1079
  interactive commit (a false alarm), git-cai offers, per flagged file, to
1024
1080
  remember the decision: add the file to `.caiignore` (drop it from git-cai
1025
1081
  entirely), add it to `secret_scan_exclude` (keep sending it but skip its
@@ -1073,10 +1129,18 @@ Available configuration keys:
1073
1129
  the middle step).
1074
1130
  - `<provider>.model` -- model name for a specific provider
1075
1131
  - `<provider>.temperature` -- temperature for a specific provider
1076
- - `anthropic.max_tokens` -- upper bound on Anthropic response tokens
1077
- (default `32768`)
1078
- - `ollama.timeout` -- HTTP timeout in seconds for Ollama generation calls
1079
- (default `300`; overrides the global `timeout` for this provider only)
1132
+ - `<provider>.base_url` -- endpoint of a custom OpenAI compatible provider,
1133
+ or a proxy/gateway for a built in one. OpenAI style providers include the
1134
+ version (`https://gateway.example/v1`); `anthropic` and `gemini` take the
1135
+ host without it (`https://gateway.example`). Must be an http(s) URL. Not
1136
+ used by `ollama` (use `OLLAMA_HOST`).
1137
+ - `<provider>.requires_token` -- set to `false` for a custom provider that
1138
+ needs no API key; no `Authorization` header is sent (default `true`)
1139
+ - `<provider>.max_output_tokens` -- upper bound on response tokens. For
1140
+ `anthropic` the default is `32768` (`max_tokens` is still read as a legacy
1141
+ alias). For OpenAI compatible providers it is only sent when set.
1142
+ - `<provider>.timeout` -- HTTP timeout in seconds for one provider,
1143
+ overriding the global `timeout` (`ollama` defaults to `300`)
1080
1144
  - `stats` -- opt in to local-only usage analytics (`true`/`false`,
1081
1145
  default `false`). When enabled, every generation appends one row to
1082
1146
  `~/.local/share/git-cai/stats.db` capturing kind (`commit`, `amend`,
@@ -1234,6 +1298,12 @@ Override the provider for a single invocation:
1234
1298
  git cai -P anthropic
1235
1299
  ----
1236
1300
 
1301
+ Use a custom OpenAI compatible provider defined in the config:
1302
+
1303
+ ----
1304
+ git cai -P lmstudio
1305
+ ----
1306
+
1237
1307
  Override both provider and model:
1238
1308
 
1239
1309
  ----