diff --git a/README.md b/README.md index 6698bd1..fda600e 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,10 @@ gh extension install prdlk/gh-commit ### Requirements - [uv](https://docs.astral.sh/uv) — Python package runner (handles dependencies automatically) -- [Crush](https://github.com/charmbracelet/crush) — configured with an authenticated model provider +- [Crush](https://github.com/charmbracelet/crush) — non-interactive AI runner +- `GROQ_API_KEY` — authenticates the default Groq model -By default, gh-commit uses `openrouter/qwen/qwen3.6-27b`. Configure OpenRouter in Crush or override the model with `GH_COMMIT_CRUSH_MODEL`. +By default, gh-commit uses Groq's `openai/gpt-oss-120b`. Override the model with `GH_COMMIT_CRUSH_MODEL`. ## Usage @@ -77,7 +78,7 @@ The former Mods roles now live directly in `smartcommit.py`, so gh-commit no lon | `GH_COMMIT_PUSH=1` | Auto-push after commits | | `GH_COMMIT_NO_AUTO_REFRESH=1` | Don't auto-regenerate scopes when `.gitignore` changes | | `GH_COMMIT_CRUSH_CMD` | Override the Crush command (default `crush`) | -| `GH_COMMIT_CRUSH_MODEL` | Override the Crush model (default `openrouter/qwen/qwen3.6-27b`) | +| `GH_COMMIT_CRUSH_MODEL` | Override the Crush model (default `groq/openai/gpt-oss-120b`) | | `GH_COMMIT_CRUSH_TIMEOUT` | Per-prompt timeout in seconds (default `120`) | | `GH_COMMIT_DEBUG=1` | Show scope-response parse diagnostics | diff --git a/crush-provider/crush.json b/crush-provider/crush.json new file mode 100644 index 0000000..67a528a --- /dev/null +++ b/crush-provider/crush.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://charm.land/crush.json", + "providers": { + "groq": { + "type": "openai-compat", + "base_url": "https://api.groq.com/openai/v1", + "api_key": "$GROQ_API_KEY", + "models": [ + { + "id": "openai/gpt-oss-120b", + "name": "GPT-OSS 120B on Groq", + "context_window": 131072, + "default_max_tokens": 8192 + } + ] + } + } +} diff --git a/gh-commit.tar.gz b/gh-commit.tar.gz index 0ec1df6..0f12509 100644 Binary files a/gh-commit.tar.gz and b/gh-commit.tar.gz differ diff --git a/smartcommit.py b/smartcommit.py index 1d0acd5..d08f306 100644 --- a/smartcommit.py +++ b/smartcommit.py @@ -44,7 +44,9 @@ DB_PATH = DB_DIR / "gh-commit.db" # Crush handles both AI steps in non-interactive mode. The instructions formerly # stored as mods roles are embedded below so this tool is self-contained. CRUSH_CMD = os.environ.get("GH_COMMIT_CRUSH_CMD", "crush").split() -CRUSH_MODEL = os.environ.get("GH_COMMIT_CRUSH_MODEL", "openrouter/qwen/qwen3.6-27b") +DEFAULT_CRUSH_MODEL = "groq/openai/gpt-oss-120b" +CRUSH_MODEL = os.environ.get("GH_COMMIT_CRUSH_MODEL", DEFAULT_CRUSH_MODEL) +CRUSH_CONFIG_DIR = Path(__file__).with_name("crush-provider") CRUSH_TIMEOUT = int(os.environ.get("GH_COMMIT_CRUSH_TIMEOUT", "120")) AUTO_CONFIRM = os.environ.get("GH_COMMIT_AUTO", "0") == "1" @@ -115,9 +117,12 @@ def crush_prompt(text: str, cwd: Path) -> str: cmd = [*CRUSH_CMD, "run", "--quiet"] if CRUSH_MODEL: cmd += ["--model", CRUSH_MODEL] + env = os.environ.copy() + if CRUSH_MODEL == DEFAULT_CRUSH_MODEL: + env.setdefault("CRUSH_GLOBAL_CONFIG", str(CRUSH_CONFIG_DIR)) try: result = subprocess.run( - cmd, input=text, capture_output=True, text=True, + cmd, input=text, capture_output=True, text=True, env=env, cwd=str(cwd), timeout=CRUSH_TIMEOUT, ) except FileNotFoundError as e: @@ -672,7 +677,7 @@ def cmd_help(): console.print(" GH_COMMIT_PUSH=1 Auto-push after commits") console.print(" GH_COMMIT_NO_AUTO_REFRESH=1 Don't auto-regenerate scopes on .gitignore change") console.print(" GH_COMMIT_CRUSH_CMD=... Override the Crush command") - console.print(" GH_COMMIT_CRUSH_MODEL=... Override the Crush model (default: openrouter/qwen/qwen3.6-27b)") + console.print(f" GH_COMMIT_CRUSH_MODEL=... Override the Crush model (default: {DEFAULT_CRUSH_MODEL})") console.print(" GH_COMMIT_CRUSH_TIMEOUT=... Per-prompt timeout in seconds (default: 120)") console.print(" GH_COMMIT_DEBUG=1 Show parse diagnostics\n") console.print("[cyan]Scopes auto-refresh whenever .gitignore changes.[/]")