git-cai-cli 0.17.1__tar.gz → 0.17.3__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.
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.github/ci/cai_config.ci.yml +5 -6
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.github/workflows/python-tests.yml +1 -1
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.mega-linter.yml +1 -1
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/Makefile +9 -15
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/PKG-INFO +1 -1
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/cai_config.yml +6 -6
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/docs/git-cai.txt +24 -21
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/docs/man/git-cai.1 +26 -23
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/_version.py +3 -3
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/config.py +18 -6
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/llm.py +2 -1
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli.egg-info/PKG-INFO +1 -1
- git_cai_cli-0.17.3/src/git_cai_cli.egg-info/scm_version.json +8 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_config.py +12 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_llm.py +8 -3
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_options.py +1 -1
- git_cai_cli-0.17.3/uv.lock +982 -0
- git_cai_cli-0.17.1/src/git_cai_cli.egg-info/scm_version.json +0 -8
- git_cai_cli-0.17.1/uv.lock +0 -898
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.caiignore +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.gitattributes +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.github/cd/.SRCINFO +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.github/cd/PKGBUILD +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.github/ci/_version.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.github/ci/tokens.ci.yml +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.github/workflows/release.yml +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.github/workflows/release_aur.yml +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.gitignore +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.linters/.bandit.yml +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.linters/.checkov.yml +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.linters/.flake8 +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.linters/.ls-lint.yml +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.linters/.markdownlint.json +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.linters/.proselintrc.json +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.linters/.pylintrc +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.linters/.yamllint.yml +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.linters/check_git_branch_name.sh +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.linters/lychee.toml +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.linters/pyrightconfig.json +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.markdownlintignore +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.semgrepignore +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/.trivyignore +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/CLAUDE.md +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/LICENSE +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/README.md +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/pyproject.toml +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/setup.cfg +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/__init__.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/cli/__init__.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/cli/cli.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/cli/helptext.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/cli/modes.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/__init__.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/changelog.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/completion.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/doctor.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/explain.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/generation.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/gitutils.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/init.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/languages.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/options.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/pr.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/prompts_fallback.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/release.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/secrets.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/spinner.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/split.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/squash.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/stats.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/core/validate.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli/main.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli.egg-info/SOURCES.txt +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli.egg-info/dependency_links.txt +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli.egg-info/entry_points.txt +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli.egg-info/requires.txt +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli.egg-info/scm_file_list.json +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/src/git_cai_cli.egg-info/top_level.txt +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/conftest.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/integration/test_cli_integration.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/integration/test_config_integration.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/integration/test_gitutils_integration.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/integration/test_modes_integration.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/integration/test_options_integration.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/integration/test_pr_integration.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/integration/test_squash_integration.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_amend.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_branch_context.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_changelog.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_classification.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_cli.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_completion.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_conventional.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_custom_provider.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_doctor.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_explain.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_generation.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_gitutils.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_helptext.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_init.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_main.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_modes.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_pr.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_print.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_prompt_loading.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_release.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_secrets.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_set_config.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_signoff.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_spinner.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_split.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_squash.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_stats.py +0 -0
- {git_cai_cli-0.17.1 → git_cai_cli-0.17.3}/tests/unit/test_validate.py +0 -0
|
@@ -6,14 +6,13 @@ load_tokens_from: /home/runner/work/.config/cai/tokens.yml
|
|
|
6
6
|
timeout: 30
|
|
7
7
|
full_files: false
|
|
8
8
|
anthropic:
|
|
9
|
-
model: claude-haiku-
|
|
10
|
-
temperature: 0
|
|
9
|
+
model: claude-haiku-5-5
|
|
11
10
|
max_tokens: 32768
|
|
12
11
|
deepseek:
|
|
13
|
-
model: deepseek-
|
|
12
|
+
model: deepseek-flash
|
|
14
13
|
temperature: 0
|
|
15
14
|
gemini:
|
|
16
|
-
model: gemini-3.
|
|
15
|
+
model: gemini-3.5-flash-lite
|
|
17
16
|
temperature: 0
|
|
18
17
|
groq:
|
|
19
18
|
model: openai/gpt-oss-20b
|
|
@@ -22,11 +21,11 @@ mistral:
|
|
|
22
21
|
model: codestral-2508
|
|
23
22
|
temperature: 0
|
|
24
23
|
ollama:
|
|
25
|
-
model:
|
|
24
|
+
model: gemma4:e2b
|
|
26
25
|
temperature: 0
|
|
27
26
|
timeout: 300
|
|
28
27
|
openai:
|
|
29
|
-
model: gpt-
|
|
28
|
+
model: gpt-6-luna
|
|
30
29
|
xai:
|
|
31
30
|
model: grok-4.3
|
|
32
31
|
temperature: 0
|
|
@@ -99,7 +99,7 @@ jobs:
|
|
|
99
99
|
|
|
100
100
|
# MegaLinter
|
|
101
101
|
- name: MegaLinter
|
|
102
|
-
uses: oxsecurity/megalinter@
|
|
102
|
+
uses: oxsecurity/megalinter@f2fe8c1cba37091848df3e524066c8c23ef353ed # v10.2.0
|
|
103
103
|
id: ml
|
|
104
104
|
env:
|
|
105
105
|
VALIDATE_ALL_CODEBASE: false
|
|
@@ -54,7 +54,7 @@ LINTER_RULES_PATH: .linters
|
|
|
54
54
|
LOG_LEVEL: INFO
|
|
55
55
|
MARKDOWN_DEFAULT_STYLE: markdownlint
|
|
56
56
|
# Pins the Docker image for local runs to the version the CI workflow pins.
|
|
57
|
-
MEGALINTER_VERSION: v10.
|
|
57
|
+
MEGALINTER_VERSION: v10.2.0
|
|
58
58
|
PARALLEL: true
|
|
59
59
|
PRINT_ALPACA: false
|
|
60
60
|
PYTHON_BANDIT_RULES_PATH: .linters
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/make -f
|
|
2
2
|
|
|
3
|
-
PIP := pipx
|
|
4
3
|
UV := uv
|
|
5
4
|
SHELL := /bin/bash
|
|
5
|
+
MEGALINTER_VERSION := $(shell sed -n 's/^MEGALINTER_VERSION: *//p' .mega-linter.yml)
|
|
6
|
+
MEGALINTER_IMAGE := ghcr.io/oxsecurity/megalinter:$(MEGALINTER_VERSION)
|
|
7
|
+
# --platform: the image is amd64 only. z: relabels the mount on SELinux hosts, ignored elsewhere.
|
|
8
|
+
MEGALINTER_RUN := docker run --rm --platform linux/amd64 -v "$(CURDIR):/tmp/lint:rw,z"
|
|
6
9
|
|
|
7
|
-
.PHONY: help lint check-docker
|
|
10
|
+
.PHONY: help lint check-docker lint-fix add-lint-hook clean test
|
|
8
11
|
|
|
9
12
|
help: ## Shows this help message
|
|
10
13
|
@echo "Available commands:"
|
|
@@ -27,25 +30,16 @@ check-docker: ## Checks if docker is installed
|
|
|
27
30
|
docker --version; \
|
|
28
31
|
fi
|
|
29
32
|
|
|
30
|
-
check-npx: ## Checks if npx is installed
|
|
31
|
-
@if ! command -v npx &> /dev/null; then \
|
|
32
|
-
echo "npx is not installed. Please install it."; \
|
|
33
|
-
exit 1; \
|
|
34
|
-
else \
|
|
35
|
-
echo "npx version:"; \
|
|
36
|
-
npx --version; \
|
|
37
|
-
fi
|
|
38
|
-
|
|
39
33
|
clean: ## Clean cache of uv and delete virtual environment
|
|
40
34
|
@$(UV) cache clean
|
|
41
35
|
@rm -rf .venv
|
|
42
36
|
|
|
43
|
-
lint:
|
|
37
|
+
lint: ## Checks the branch name and runs MegaLinter
|
|
44
38
|
@sh ./.linters/check_git_branch_name.sh
|
|
45
|
-
|
|
39
|
+
@$(MEGALINTER_RUN) $(MEGALINTER_IMAGE)
|
|
46
40
|
|
|
47
|
-
lint-fix: ##
|
|
48
|
-
|
|
41
|
+
lint-fix: ## Runs MegaLinter and applies its fixes
|
|
42
|
+
@$(MEGALINTER_RUN) -e APPLY_FIXES=all $(MEGALINTER_IMAGE)
|
|
49
43
|
|
|
50
44
|
test: ## Runs tests
|
|
51
45
|
@$(UV) run pytest
|
|
@@ -18,15 +18,15 @@ pr_prompt_file: "/home/thorsten/.config/cai/pr_prompt.md"
|
|
|
18
18
|
stats: true
|
|
19
19
|
signoff: true
|
|
20
20
|
anthropic:
|
|
21
|
-
model: claude-haiku-
|
|
22
|
-
temperature: 0
|
|
21
|
+
model: claude-haiku-5-5
|
|
23
22
|
max_tokens: 32768
|
|
24
23
|
deepseek:
|
|
25
|
-
model: deepseek-
|
|
24
|
+
model: deepseek-flash
|
|
26
25
|
temperature: 0
|
|
27
26
|
gemini:
|
|
28
|
-
model: gemini-3.
|
|
27
|
+
model: gemini-3.5-flash-lite
|
|
29
28
|
temperature: 0
|
|
29
|
+
timeout: 60
|
|
30
30
|
groq:
|
|
31
31
|
model: openai/gpt-oss-20b
|
|
32
32
|
temperature: 0
|
|
@@ -34,11 +34,11 @@ mistral:
|
|
|
34
34
|
model: codestral-2508
|
|
35
35
|
temperature: 0
|
|
36
36
|
ollama:
|
|
37
|
-
model:
|
|
37
|
+
model: gemma4:e2b
|
|
38
38
|
temperature: 0
|
|
39
39
|
timeout: 300
|
|
40
40
|
openai:
|
|
41
|
-
model: gpt-
|
|
41
|
+
model: gpt-6-luna
|
|
42
42
|
xai:
|
|
43
43
|
model: grok-4.3
|
|
44
44
|
temperature: 0
|
|
@@ -360,7 +360,7 @@ provider keys.
|
|
|
360
360
|
git cai -H language=de
|
|
361
361
|
git cai -H default=anthropic
|
|
362
362
|
git cai -H emoji=false
|
|
363
|
-
git cai -H groq.model=
|
|
363
|
+
git cai -H groq.model=openai/gpt-oss-120b
|
|
364
364
|
----
|
|
365
365
|
|
|
366
366
|
-h, --help::
|
|
@@ -455,7 +455,7 @@ identifier for that provider.
|
|
|
455
455
|
+
|
|
456
456
|
----
|
|
457
457
|
git cai -P openai -m gpt-4o
|
|
458
|
-
git cai -P anthropic -m claude-haiku-
|
|
458
|
+
git cai -P anthropic -m claude-haiku-5-5
|
|
459
459
|
git cai -P ollama -m mistral
|
|
460
460
|
----
|
|
461
461
|
|
|
@@ -528,7 +528,7 @@ both.
|
|
|
528
528
|
+
|
|
529
529
|
----
|
|
530
530
|
git cai -P anthropic
|
|
531
|
-
git cai -P groq -m
|
|
531
|
+
git cai -P groq -m openai/gpt-oss-120b
|
|
532
532
|
git cai -P openrouter
|
|
533
533
|
----
|
|
534
534
|
|
|
@@ -662,7 +662,7 @@ become integers or floats, everything else stays a string.
|
|
|
662
662
|
----
|
|
663
663
|
git cai -S default=anthropic
|
|
664
664
|
git cai -S emoji=false
|
|
665
|
-
git cai -S groq.model=
|
|
665
|
+
git cai -S groq.model=openai/gpt-oss-120b
|
|
666
666
|
git cai -S openai.temperature=0.7
|
|
667
667
|
git cai -S conventional=true
|
|
668
668
|
----
|
|
@@ -695,9 +695,10 @@ git cai -s a1b2c3d
|
|
|
695
695
|
|
|
696
696
|
-T, --timeout SECONDS::
|
|
697
697
|
Override the HTTP timeout for the LLM call in this invocation. The default
|
|
698
|
-
is 30 seconds for remote providers
|
|
699
|
-
|
|
700
|
-
|
|
698
|
+
is 30 seconds for remote providers, 60 seconds for Gemini (Flash Lite can queue
|
|
699
|
+
for up to 30 seconds) and 300 seconds for Ollama (since local generation can be
|
|
700
|
+
significantly slower). The override applies uniformly to whichever provider is
|
|
701
|
+
selected for this run, including those with their own `<provider>.timeout`.
|
|
701
702
|
+
|
|
702
703
|
To change the default permanently, set `timeout: <seconds>` in
|
|
703
704
|
`cai_config.yml` or the home config:
|
|
@@ -707,11 +708,12 @@ git cai -H timeout=60
|
|
|
707
708
|
git cai -S timeout=45
|
|
708
709
|
----
|
|
709
710
|
+
|
|
710
|
-
Ollama
|
|
711
|
-
|
|
711
|
+
Ollama and Gemini keep their own timeouts under `ollama.timeout` (default 300)
|
|
712
|
+
and `gemini.timeout` (default 60). Override them separately:
|
|
712
713
|
+
|
|
713
714
|
----
|
|
714
715
|
git cai -H ollama.timeout=600
|
|
716
|
+
git cai -H gemini.timeout=90
|
|
715
717
|
----
|
|
716
718
|
+
|
|
717
719
|
----
|
|
@@ -938,13 +940,13 @@ Example output:
|
|
|
938
940
|
----
|
|
939
941
|
Default models:
|
|
940
942
|
|
|
941
|
-
anthropic → claude-haiku-
|
|
942
|
-
deepseek → deepseek-
|
|
943
|
-
gemini → gemini-3.
|
|
943
|
+
anthropic → claude-haiku-5-5
|
|
944
|
+
deepseek → deepseek-flash
|
|
945
|
+
gemini → gemini-3.5-flash-lite
|
|
944
946
|
groq → openai/gpt-oss-20b
|
|
945
947
|
mistral → codestral-2508
|
|
946
|
-
ollama →
|
|
947
|
-
openai → gpt-
|
|
948
|
+
ollama → gemma4:e2b
|
|
949
|
+
openai → gpt-6-luna
|
|
948
950
|
xai → grok-4.3
|
|
949
951
|
----
|
|
950
952
|
|
|
@@ -1003,13 +1005,13 @@ Example output:
|
|
|
1003
1005
|
----
|
|
1004
1006
|
Supported providers:
|
|
1005
1007
|
|
|
1006
|
-
anthropic model: claude-haiku-
|
|
1007
|
-
deepseek model: deepseek-
|
|
1008
|
-
gemini model: gemini-3.
|
|
1008
|
+
anthropic model: claude-haiku-5-5 (token required)
|
|
1009
|
+
deepseek model: deepseek-flash (token required)
|
|
1010
|
+
gemini model: gemini-3.5-flash-lite (token required)
|
|
1009
1011
|
groq model: openai/gpt-oss-20b (token required)
|
|
1010
1012
|
mistral model: codestral-2508 (token required)
|
|
1011
|
-
ollama model:
|
|
1012
|
-
openai model: gpt-
|
|
1013
|
+
ollama model: gemma4:e2b (no token required)
|
|
1014
|
+
openai model: gpt-6-luna (token required)
|
|
1013
1015
|
xai model: grok-4.3 (token required)
|
|
1014
1016
|
|
|
1015
1017
|
Custom providers (OpenAI compatible, from config):
|
|
@@ -1141,7 +1143,8 @@ Available configuration keys:
|
|
|
1141
1143
|
`anthropic` the default is `32768` (`max_tokens` is still read as a legacy
|
|
1142
1144
|
alias). For OpenAI compatible providers it is only sent when set.
|
|
1143
1145
|
- `<provider>.timeout` -- HTTP timeout in seconds for one provider,
|
|
1144
|
-
overriding the global `timeout` (`ollama` defaults to `300`)
|
|
1146
|
+
overriding the global `timeout` (`ollama` defaults to `300`, `gemini` to `60`).
|
|
1147
|
+
The `--timeout` flag overrides both.
|
|
1145
1148
|
- `stats` -- opt in to local-only usage analytics (`true`/`false`,
|
|
1146
1149
|
default `false`). When enabled, every generation appends one row to
|
|
1147
1150
|
`~/.local/share/git-cai/stats.db` capturing kind (`commit`, `amend`,
|
|
@@ -1315,7 +1318,7 @@ Change a value in the repo config:
|
|
|
1315
1318
|
|
|
1316
1319
|
----
|
|
1317
1320
|
git cai -S default=anthropic
|
|
1318
|
-
git cai -S groq.model=
|
|
1321
|
+
git cai -S groq.model=openai/gpt-oss-120b
|
|
1319
1322
|
git cai -S emoji=false
|
|
1320
1323
|
----
|
|
1321
1324
|
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
.\" Title: git-cai
|
|
3
3
|
.\" Author: Thorsten Foltz
|
|
4
4
|
.\" Generator: Asciidoctor 2.0.26
|
|
5
|
-
.\" Date: 2026-
|
|
5
|
+
.\" Date: 2026-11-04
|
|
6
6
|
.\" Manual: \ \&
|
|
7
7
|
.\" Source: \ \&
|
|
8
8
|
.\" Language: English
|
|
9
9
|
.\"
|
|
10
|
-
.TH "GIT\-CAI" "1" "2026-
|
|
10
|
+
.TH "GIT\-CAI" "1" "2026-11-04" "\ \&" "\ \&"
|
|
11
11
|
.ie \n(.g .ds Aq \(aq
|
|
12
12
|
.el .ds Aq '
|
|
13
13
|
.ss \n[.ss] 0
|
|
@@ -656,7 +656,7 @@ provider keys.
|
|
|
656
656
|
git cai \-H language=de
|
|
657
657
|
git cai \-H default=anthropic
|
|
658
658
|
git cai \-H emoji=false
|
|
659
|
-
git cai \-H groq.model=
|
|
659
|
+
git cai \-H groq.model=openai/gpt\-oss\-120b
|
|
660
660
|
.fam
|
|
661
661
|
.fi
|
|
662
662
|
.if n .RE
|
|
@@ -789,7 +789,7 @@ identifier for that provider.
|
|
|
789
789
|
.nf
|
|
790
790
|
.fam C
|
|
791
791
|
git cai \-P openai \-m gpt\-4o
|
|
792
|
-
git cai \-P anthropic \-m claude\-haiku\-
|
|
792
|
+
git cai \-P anthropic \-m claude\-haiku\-5\-5
|
|
793
793
|
git cai \-P ollama \-m mistral
|
|
794
794
|
.fam
|
|
795
795
|
.fi
|
|
@@ -890,7 +890,7 @@ both.
|
|
|
890
890
|
.nf
|
|
891
891
|
.fam C
|
|
892
892
|
git cai \-P anthropic
|
|
893
|
-
git cai \-P groq \-m
|
|
893
|
+
git cai \-P groq \-m openai/gpt\-oss\-120b
|
|
894
894
|
git cai \-P openrouter
|
|
895
895
|
.fam
|
|
896
896
|
.fi
|
|
@@ -1066,7 +1066,7 @@ become integers or floats, everything else stays a string.
|
|
|
1066
1066
|
.fam C
|
|
1067
1067
|
git cai \-S default=anthropic
|
|
1068
1068
|
git cai \-S emoji=false
|
|
1069
|
-
git cai \-S groq.model=
|
|
1069
|
+
git cai \-S groq.model=openai/gpt\-oss\-120b
|
|
1070
1070
|
git cai \-S openai.temperature=0.7
|
|
1071
1071
|
git cai \-S conventional=true
|
|
1072
1072
|
.fam
|
|
@@ -1109,9 +1109,10 @@ git cai \-s a1b2c3d
|
|
|
1109
1109
|
\-T, \-\-timeout SECONDS
|
|
1110
1110
|
.RS 4
|
|
1111
1111
|
Override the HTTP timeout for the LLM call in this invocation. The default
|
|
1112
|
-
is 30 seconds for remote providers
|
|
1113
|
-
|
|
1114
|
-
|
|
1112
|
+
is 30 seconds for remote providers, 60 seconds for Gemini (Flash Lite can queue
|
|
1113
|
+
for up to 30 seconds) and 300 seconds for Ollama (since local generation can be
|
|
1114
|
+
significantly slower). The override applies uniformly to whichever provider is
|
|
1115
|
+
selected for this run, including those with their own \f(CR<provider>.timeout\fP.
|
|
1115
1116
|
.sp
|
|
1116
1117
|
To change the default permanently, set \f(CRtimeout: <seconds>\fP in
|
|
1117
1118
|
\f(CRcai_config.yml\fP or the home config:
|
|
@@ -1125,13 +1126,14 @@ git cai \-S timeout=45
|
|
|
1125
1126
|
.fi
|
|
1126
1127
|
.if n .RE
|
|
1127
1128
|
.sp
|
|
1128
|
-
Ollama
|
|
1129
|
-
|
|
1129
|
+
Ollama and Gemini keep their own timeouts under \f(CRollama.timeout\fP (default 300)
|
|
1130
|
+
and \f(CRgemini.timeout\fP (default 60). Override them separately:
|
|
1130
1131
|
.sp
|
|
1131
1132
|
.if n .RS 4
|
|
1132
1133
|
.nf
|
|
1133
1134
|
.fam C
|
|
1134
1135
|
git cai \-H ollama.timeout=600
|
|
1136
|
+
git cai \-H gemini.timeout=90
|
|
1135
1137
|
.fam
|
|
1136
1138
|
.fi
|
|
1137
1139
|
.if n .RE
|
|
@@ -1441,13 +1443,13 @@ Example output:
|
|
|
1441
1443
|
.fam C
|
|
1442
1444
|
Default models:
|
|
1443
1445
|
|
|
1444
|
-
anthropic\& → claude\-haiku\-
|
|
1445
|
-
deepseek\& → deepseek\-
|
|
1446
|
-
gemini\& → gemini\-3.
|
|
1446
|
+
anthropic\& → claude\-haiku\-5\-5
|
|
1447
|
+
deepseek\& → deepseek\-flash
|
|
1448
|
+
gemini\& → gemini\-3.5\-flash\-lite
|
|
1447
1449
|
groq\& → openai/gpt\-oss\-20b
|
|
1448
1450
|
mistral\& → codestral\-2508
|
|
1449
|
-
ollama\& →
|
|
1450
|
-
openai\& → gpt\-
|
|
1451
|
+
ollama\& → gemma4:e2b
|
|
1452
|
+
openai\& → gpt\-6\-luna
|
|
1451
1453
|
xai\& → grok\-4.3
|
|
1452
1454
|
.fam
|
|
1453
1455
|
.fi
|
|
@@ -1530,13 +1532,13 @@ Example output:
|
|
|
1530
1532
|
.fam C
|
|
1531
1533
|
Supported providers:
|
|
1532
1534
|
|
|
1533
|
-
anthropic\& model: claude\-haiku\-
|
|
1534
|
-
deepseek\& model: deepseek\-
|
|
1535
|
-
gemini\& model: gemini\-3.
|
|
1535
|
+
anthropic\& model: claude\-haiku\-5\-5\& (token required)
|
|
1536
|
+
deepseek\& model: deepseek\-flash\& (token required)
|
|
1537
|
+
gemini\& model: gemini\-3.5\-flash\-lite\& (token required)
|
|
1536
1538
|
groq\& model: openai/gpt\-oss\-20b\& (token required)
|
|
1537
1539
|
mistral\& model: codestral\-2508\& (token required)
|
|
1538
|
-
ollama\& model:
|
|
1539
|
-
openai\& model: gpt\-
|
|
1540
|
+
ollama\& model: gemma4:e2b\& (no token required)
|
|
1541
|
+
openai\& model: gpt\-6\-luna\& (token required)
|
|
1540
1542
|
xai\& model: grok\-4.3\& (token required)
|
|
1541
1543
|
|
|
1542
1544
|
Custom providers (OpenAI compatible, from config):
|
|
@@ -2021,7 +2023,8 @@ alias). For OpenAI compatible providers it is only sent when set.
|
|
|
2021
2023
|
. IP \(bu 2.3
|
|
2022
2024
|
.\}
|
|
2023
2025
|
\f(CR<provider>.timeout\fP \(em HTTP timeout in seconds for one provider,
|
|
2024
|
-
overriding the global \f(CRtimeout\fP (\f(CRollama\fP defaults to \f(CR300\fP)
|
|
2026
|
+
overriding the global \f(CRtimeout\fP (\f(CRollama\fP defaults to \f(CR300\fP, \f(CRgemini\fP to \f(CR60\fP).
|
|
2027
|
+
The \f(CR\-\-timeout\fP flag overrides both.
|
|
2025
2028
|
.RE
|
|
2026
2029
|
.sp
|
|
2027
2030
|
.RS 4
|
|
@@ -2310,7 +2313,7 @@ Change a value in the repo config:
|
|
|
2310
2313
|
.nf
|
|
2311
2314
|
.fam C
|
|
2312
2315
|
git cai \-S default=anthropic
|
|
2313
|
-
git cai \-S groq.model=
|
|
2316
|
+
git cai \-S groq.model=openai/gpt\-oss\-120b
|
|
2314
2317
|
git cai \-S emoji=false
|
|
2315
2318
|
.fam
|
|
2316
2319
|
.fi
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.17.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 17,
|
|
21
|
+
__version__ = version = '0.17.3'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 17, 3)
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'g4c48b7f68'
|
|
@@ -35,19 +35,26 @@ TOKENS_FILE = CONFIG_DIR / "tokens.yml"
|
|
|
35
35
|
|
|
36
36
|
DEFAULT_CONFIG: dict[str, Any] = {
|
|
37
37
|
"anthropic": {
|
|
38
|
-
"model": "claude-haiku-
|
|
39
|
-
"temperature": 0,
|
|
38
|
+
"model": "claude-haiku-5-5",
|
|
40
39
|
# ``max_tokens`` is still read as a legacy alias (see llm.py)
|
|
41
40
|
"max_output_tokens": 32768,
|
|
42
41
|
},
|
|
43
|
-
"openai": {"model": "gpt-
|
|
44
|
-
"deepseek": {"model": "deepseek-
|
|
45
|
-
"gemini": {
|
|
42
|
+
"openai": {"model": "gpt-6-luna"},
|
|
43
|
+
"deepseek": {"model": "deepseek-flash", "temperature": 0},
|
|
44
|
+
"gemini": {
|
|
45
|
+
"model": "gemini-3.5-flash-lite",
|
|
46
|
+
"temperature": 0,
|
|
47
|
+
# Flash Lite was measured taking up to 30 seconds server side, even for
|
|
48
|
+
# a single word reply, so the global 30 second timeout is too tight.
|
|
49
|
+
"timeout": 60,
|
|
50
|
+
},
|
|
46
51
|
"groq": {"model": "openai/gpt-oss-20b", "temperature": 0},
|
|
47
52
|
"xai": {"model": "grok-4.3", "temperature": 0},
|
|
53
|
+
# Not the cheapest on the list: ministral-3b wrapped messages in code
|
|
54
|
+
# fences and ministral-8b added a warning line, both unfit for a commit.
|
|
48
55
|
"mistral": {"model": "codestral-2508", "temperature": 0},
|
|
49
56
|
"ollama": {
|
|
50
|
-
"model": "
|
|
57
|
+
"model": "gemma4:e2b",
|
|
51
58
|
"temperature": 0,
|
|
52
59
|
"timeout": 300,
|
|
53
60
|
"startup_timeout": 8,
|
|
@@ -733,6 +740,11 @@ def apply_cli_overrides(
|
|
|
733
740
|
config["branch_context"] = branch_context
|
|
734
741
|
if timeout_override is not None:
|
|
735
742
|
config["timeout"] = timeout_override
|
|
743
|
+
# The flag outranks ``<provider>.timeout``, which is checked first when
|
|
744
|
+
# resolving. Rebuild instead of pop: blocks may be shared with DEFAULT_CONFIG.
|
|
745
|
+
for name, block in list(config.items()):
|
|
746
|
+
if isinstance(block, dict) and "timeout" in block:
|
|
747
|
+
config[name] = {k: v for k, v in block.items() if k != "timeout"}
|
|
736
748
|
if full_files_override is not None:
|
|
737
749
|
config["full_files"] = full_files_override
|
|
738
750
|
if sql_override is not None:
|
|
@@ -41,10 +41,11 @@ log = logging.getLogger(__name__)
|
|
|
41
41
|
# still handled — ``_http_post`` retries once without the field — so add
|
|
42
42
|
# an entry only when a warning shows up in practice.
|
|
43
43
|
_TEMPERATURE_UNSUPPORTED_PATTERNS = [
|
|
44
|
-
re.compile(r"^gpt-5", re.IGNORECASE), # OpenAI GPT-5
|
|
44
|
+
re.compile(r"^gpt-[5-9]", re.IGNORECASE), # OpenAI GPT-5+ (incl. mini/nano/luna)
|
|
45
45
|
re.compile(r"^o[134](-|$)", re.IGNORECASE), # OpenAI o1/o3/o4 reasoning series
|
|
46
46
|
re.compile(r"opus-4-[7-9]", re.IGNORECASE), # Anthropic Opus 4.7 / 4.8 / 4.9
|
|
47
47
|
re.compile(r"opus-[5-9]", re.IGNORECASE), # Anthropic Opus 5+
|
|
48
|
+
re.compile(r"haiku-[5-9]", re.IGNORECASE), # Anthropic Haiku 5+
|
|
48
49
|
]
|
|
49
50
|
|
|
50
51
|
|
|
@@ -494,6 +494,18 @@ def test_apply_cli_overrides_timeout_none_preserves_existing():
|
|
|
494
494
|
assert cfg["timeout"] == 45
|
|
495
495
|
|
|
496
496
|
|
|
497
|
+
def test_apply_cli_overrides_timeout_beats_provider_timeout():
|
|
498
|
+
"""--timeout must outrank <provider>.timeout without mutating shared blocks."""
|
|
499
|
+
from git_cai_cli.core.llm import CommitMessageGenerator
|
|
500
|
+
|
|
501
|
+
shared_block = {"model": "m", "timeout": 60}
|
|
502
|
+
cfg = {"timeout": 30, "gemini": shared_block}
|
|
503
|
+
apply_cli_overrides(cfg, timeout_override=7)
|
|
504
|
+
assert CommitMessageGenerator(None, cfg, "gemini")._timeout("gemini") == 7
|
|
505
|
+
assert cfg["gemini"]["model"] == "m"
|
|
506
|
+
assert shared_block["timeout"] == 60
|
|
507
|
+
|
|
508
|
+
|
|
497
509
|
def test_apply_cli_overrides_full_files_true_sets_true():
|
|
498
510
|
cfg = {"full_files": False}
|
|
499
511
|
apply_cli_overrides(cfg, full_files_override=True)
|
|
@@ -1447,6 +1447,7 @@ def test_http_post_does_not_retry_on_unrelated_400():
|
|
|
1447
1447
|
def test_model_rejects_temperature_openai_gpt5():
|
|
1448
1448
|
assert _model_rejects_temperature("gpt-5.4-mini") is True
|
|
1449
1449
|
assert _model_rejects_temperature("gpt-5.2") is True
|
|
1450
|
+
assert _model_rejects_temperature("gpt-6-luna") is True
|
|
1450
1451
|
assert _model_rejects_temperature("o3-mini") is True
|
|
1451
1452
|
|
|
1452
1453
|
|
|
@@ -1456,15 +1457,19 @@ def test_model_rejects_temperature_anthropic_opus_new():
|
|
|
1456
1457
|
assert _model_rejects_temperature("claude-opus-5-1") is True
|
|
1457
1458
|
|
|
1458
1459
|
|
|
1460
|
+
def test_model_rejects_temperature_anthropic_haiku_new():
|
|
1461
|
+
assert _model_rejects_temperature("claude-haiku-5-5") is True
|
|
1462
|
+
|
|
1463
|
+
|
|
1459
1464
|
def test_model_accepts_temperature_kept_models():
|
|
1460
1465
|
for m in (
|
|
1461
1466
|
"claude-haiku-4-5",
|
|
1462
1467
|
"openai/gpt-oss-20b",
|
|
1463
|
-
"gemini-3.
|
|
1468
|
+
"gemini-3.5-flash-lite",
|
|
1464
1469
|
"grok-4.3",
|
|
1465
|
-
"deepseek-
|
|
1470
|
+
"deepseek-flash",
|
|
1466
1471
|
"codestral-2508",
|
|
1467
|
-
"
|
|
1472
|
+
"gemma4:e2b",
|
|
1468
1473
|
):
|
|
1469
1474
|
assert _model_rejects_temperature(m) is False
|
|
1470
1475
|
|
|
@@ -249,7 +249,7 @@ def test_list_providers_shows_default_models() -> None:
|
|
|
249
249
|
"""
|
|
250
250
|
manager = CliManager()
|
|
251
251
|
output = manager.list_providers()
|
|
252
|
-
assert "
|
|
252
|
+
assert "gemma4:e2b" in output # ollama default model
|
|
253
253
|
|
|
254
254
|
|
|
255
255
|
def test_list_models_contains_all_providers() -> None:
|