gac 1.10.2__tar.gz → 1.11.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.

Potentially problematic release.


This version of gac might be problematic. Click here for more details.

Files changed (38) hide show
  1. {gac-1.10.2 → gac-1.11.0}/PKG-INFO +15 -15
  2. {gac-1.10.2 → gac-1.11.0}/README.md +14 -14
  3. {gac-1.10.2 → gac-1.11.0}/src/gac/__version__.py +1 -1
  4. {gac-1.10.2 → gac-1.11.0}/src/gac/ai.py +4 -0
  5. {gac-1.10.2 → gac-1.11.0}/src/gac/ai_utils.py +2 -0
  6. {gac-1.10.2 → gac-1.11.0}/src/gac/init_cli.py +1 -0
  7. {gac-1.10.2 → gac-1.11.0}/src/gac/providers/__init__.py +4 -0
  8. gac-1.11.0/src/gac/providers/minimax.py +38 -0
  9. gac-1.11.0/src/gac/providers/together.py +38 -0
  10. {gac-1.10.2 → gac-1.11.0}/.gitignore +0 -0
  11. {gac-1.10.2 → gac-1.11.0}/LICENSE +0 -0
  12. {gac-1.10.2 → gac-1.11.0}/pyproject.toml +0 -0
  13. {gac-1.10.2 → gac-1.11.0}/src/gac/__init__.py +0 -0
  14. {gac-1.10.2 → gac-1.11.0}/src/gac/cli.py +0 -0
  15. {gac-1.10.2 → gac-1.11.0}/src/gac/config.py +0 -0
  16. {gac-1.10.2 → gac-1.11.0}/src/gac/config_cli.py +0 -0
  17. {gac-1.10.2 → gac-1.11.0}/src/gac/constants.py +0 -0
  18. {gac-1.10.2 → gac-1.11.0}/src/gac/diff_cli.py +0 -0
  19. {gac-1.10.2 → gac-1.11.0}/src/gac/errors.py +0 -0
  20. {gac-1.10.2 → gac-1.11.0}/src/gac/git.py +0 -0
  21. {gac-1.10.2 → gac-1.11.0}/src/gac/main.py +0 -0
  22. {gac-1.10.2 → gac-1.11.0}/src/gac/preprocess.py +0 -0
  23. {gac-1.10.2 → gac-1.11.0}/src/gac/prompt.py +0 -0
  24. {gac-1.10.2 → gac-1.11.0}/src/gac/providers/anthropic.py +0 -0
  25. {gac-1.10.2 → gac-1.11.0}/src/gac/providers/cerebras.py +0 -0
  26. {gac-1.10.2 → gac-1.11.0}/src/gac/providers/chutes.py +0 -0
  27. {gac-1.10.2 → gac-1.11.0}/src/gac/providers/fireworks.py +0 -0
  28. {gac-1.10.2 → gac-1.11.0}/src/gac/providers/gemini.py +0 -0
  29. {gac-1.10.2 → gac-1.11.0}/src/gac/providers/groq.py +0 -0
  30. {gac-1.10.2 → gac-1.11.0}/src/gac/providers/lmstudio.py +0 -0
  31. {gac-1.10.2 → gac-1.11.0}/src/gac/providers/ollama.py +0 -0
  32. {gac-1.10.2 → gac-1.11.0}/src/gac/providers/openai.py +0 -0
  33. {gac-1.10.2 → gac-1.11.0}/src/gac/providers/openrouter.py +0 -0
  34. {gac-1.10.2 → gac-1.11.0}/src/gac/providers/streamlake.py +0 -0
  35. {gac-1.10.2 → gac-1.11.0}/src/gac/providers/synthetic.py +0 -0
  36. {gac-1.10.2 → gac-1.11.0}/src/gac/providers/zai.py +0 -0
  37. {gac-1.10.2 → gac-1.11.0}/src/gac/security.py +0 -0
  38. {gac-1.10.2 → gac-1.11.0}/src/gac/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gac
3
- Version: 1.10.2
3
+ Version: 1.11.0
4
4
  Summary: LLM-powered Git commit message generator with multi-provider support
5
5
  Project-URL: Homepage, https://github.com/cellwebb/gac
6
6
  Project-URL: Documentation, https://github.com/cellwebb/gac#readme
@@ -60,7 +60,7 @@ Description-Content-Type: text/markdown
60
60
 
61
61
  ## What You Get
62
62
 
63
- Instead of generic messages like `"update stuff"`, `"fix bug"`, or `"add feature"`, you get intelligent, contextual messages that explain the **why** behind your changes:
63
+ Intelligent, contextual messages that explain the **why** behind your changes:
64
64
 
65
65
  ![GAC generating a contextual commit message](assets/gac-simple-usage.png)
66
66
 
@@ -92,8 +92,8 @@ gac
92
92
  ### 🌐 **Supported Providers**
93
93
 
94
94
  - **Anthropic** • **Cerebras** • **Chutes.ai** • **Fireworks** • **Gemini**
95
- - **Groq** • **LM Studio** • **Ollama** • **OpenAI** • **OpenRouter**
96
- - **Streamlake** • **Synthetic.new** • **Z.AI** • **Z.AI Coding**
95
+ - **Groq** • **LM Studio** • **Minimax** • **Ollama** • **OpenAI** • **OpenRouter**
96
+ - **Streamlake** • **Synthetic.new** • **Together AI** • **Z.AI** • **Z.AI Coding**
97
97
 
98
98
  ### 🧠 **Smart LLM Analysis**
99
99
 
@@ -137,16 +137,16 @@ gac
137
137
 
138
138
  ### Common Commands
139
139
 
140
- | Command | Description |
141
- | --------------- | ---------------------------------------------- |
142
- | `gac` | Generate commit message |
143
- | `gac -y` | Auto-confirm (no review needed) |
144
- | `gac -a` | Stage all + commit |
145
- | `gac -o` | One-line message only |
146
- | `gac -v` | Detailed verbose format |
147
- | `gac -h "hint"` | Add context for LLM (e.g., `gac -h "bug fix"`) |
148
- | `gac -s` | Include scope (e.g., feat(auth):) |
149
- | `gac -p` | Commit and push |
140
+ | Command | Description |
141
+ | --------------- | ----------------------------------------------------------------------- |
142
+ | `gac` | Generate commit message |
143
+ | `gac -y` | Auto-confirm (no review needed) |
144
+ | `gac -a` | Stage all before generating commit message |
145
+ | `gac -o` | One-line message for trivial changes |
146
+ | `gac -v` | Verbose format with Motivation, Technical Approach, and Impact Analysis |
147
+ | `gac -h "hint"` | Add context for LLM (e.g., `gac -h "bug fix"`) |
148
+ | `gac -s` | Include scope (e.g., feat(auth):) |
149
+ | `gac -p` | Commit and push |
150
150
 
151
151
  ### Power User Examples
152
152
 
@@ -172,7 +172,7 @@ gac --skip-secret-scan
172
172
  Not happy with the result? Use the reroll feature for intelligent regeneration:
173
173
 
174
174
  ```bash
175
- # Simple regeneration (uses previous context)
175
+ # Simple reroll
176
176
  r
177
177
 
178
178
  # With specific feedback
@@ -19,7 +19,7 @@
19
19
 
20
20
  ## What You Get
21
21
 
22
- Instead of generic messages like `"update stuff"`, `"fix bug"`, or `"add feature"`, you get intelligent, contextual messages that explain the **why** behind your changes:
22
+ Intelligent, contextual messages that explain the **why** behind your changes:
23
23
 
24
24
  ![GAC generating a contextual commit message](assets/gac-simple-usage.png)
25
25
 
@@ -51,8 +51,8 @@ gac
51
51
  ### 🌐 **Supported Providers**
52
52
 
53
53
  - **Anthropic** • **Cerebras** • **Chutes.ai** • **Fireworks** • **Gemini**
54
- - **Groq** • **LM Studio** • **Ollama** • **OpenAI** • **OpenRouter**
55
- - **Streamlake** • **Synthetic.new** • **Z.AI** • **Z.AI Coding**
54
+ - **Groq** • **LM Studio** • **Minimax** • **Ollama** • **OpenAI** • **OpenRouter**
55
+ - **Streamlake** • **Synthetic.new** • **Together AI** • **Z.AI** • **Z.AI Coding**
56
56
 
57
57
  ### 🧠 **Smart LLM Analysis**
58
58
 
@@ -96,16 +96,16 @@ gac
96
96
 
97
97
  ### Common Commands
98
98
 
99
- | Command | Description |
100
- | --------------- | ---------------------------------------------- |
101
- | `gac` | Generate commit message |
102
- | `gac -y` | Auto-confirm (no review needed) |
103
- | `gac -a` | Stage all + commit |
104
- | `gac -o` | One-line message only |
105
- | `gac -v` | Detailed verbose format |
106
- | `gac -h "hint"` | Add context for LLM (e.g., `gac -h "bug fix"`) |
107
- | `gac -s` | Include scope (e.g., feat(auth):) |
108
- | `gac -p` | Commit and push |
99
+ | Command | Description |
100
+ | --------------- | ----------------------------------------------------------------------- |
101
+ | `gac` | Generate commit message |
102
+ | `gac -y` | Auto-confirm (no review needed) |
103
+ | `gac -a` | Stage all before generating commit message |
104
+ | `gac -o` | One-line message for trivial changes |
105
+ | `gac -v` | Verbose format with Motivation, Technical Approach, and Impact Analysis |
106
+ | `gac -h "hint"` | Add context for LLM (e.g., `gac -h "bug fix"`) |
107
+ | `gac -s` | Include scope (e.g., feat(auth):) |
108
+ | `gac -p` | Commit and push |
109
109
 
110
110
  ### Power User Examples
111
111
 
@@ -131,7 +131,7 @@ gac --skip-secret-scan
131
131
  Not happy with the result? Use the reroll feature for intelligent regeneration:
132
132
 
133
133
  ```bash
134
- # Simple regeneration (uses previous context)
134
+ # Simple reroll
135
135
  r
136
136
 
137
137
  # With specific feedback
@@ -1,3 +1,3 @@
1
1
  """Version information for gac package."""
2
2
 
3
- __version__ = "1.10.2"
3
+ __version__ = "1.11.0"
@@ -17,11 +17,13 @@ from gac.providers import (
17
17
  call_gemini_api,
18
18
  call_groq_api,
19
19
  call_lmstudio_api,
20
+ call_minimax_api,
20
21
  call_ollama_api,
21
22
  call_openai_api,
22
23
  call_openrouter_api,
23
24
  call_streamlake_api,
24
25
  call_synthetic_api,
26
+ call_together_api,
25
27
  call_zai_api,
26
28
  call_zai_coding_api,
27
29
  )
@@ -85,11 +87,13 @@ def generate_commit_message(
85
87
  "gemini": call_gemini_api,
86
88
  "groq": call_groq_api,
87
89
  "lm-studio": call_lmstudio_api,
90
+ "minimax": call_minimax_api,
88
91
  "ollama": call_ollama_api,
89
92
  "openai": call_openai_api,
90
93
  "openrouter": call_openrouter_api,
91
94
  "streamlake": call_streamlake_api,
92
95
  "synthetic": call_synthetic_api,
96
+ "together": call_together_api,
93
97
  "zai": call_zai_api,
94
98
  "zai-coding": call_zai_coding_api,
95
99
  }
@@ -100,11 +100,13 @@ def generate_with_retries(
100
100
  "gemini",
101
101
  "groq",
102
102
  "lm-studio",
103
+ "minimax",
103
104
  "ollama",
104
105
  "openai",
105
106
  "openrouter",
106
107
  "streamlake",
107
108
  "synthetic",
109
+ "together",
108
110
  "zai",
109
111
  "zai-coding",
110
112
  ]
@@ -39,6 +39,7 @@ def init() -> None:
39
39
  ("Gemini", "gemini-2.5-flash"),
40
40
  ("Groq", "meta-llama/llama-4-maverick-17b-128e-instruct"),
41
41
  ("LM Studio", "gemma3"),
42
+ ("Minimax", "MiniMax-M2"),
42
43
  ("Ollama", "gemma3"),
43
44
  ("OpenAI", "gpt-4.1-mini"),
44
45
  ("OpenRouter", "openrouter/auto"),
@@ -7,11 +7,13 @@ from .fireworks import call_fireworks_api
7
7
  from .gemini import call_gemini_api
8
8
  from .groq import call_groq_api
9
9
  from .lmstudio import call_lmstudio_api
10
+ from .minimax import call_minimax_api
10
11
  from .ollama import call_ollama_api
11
12
  from .openai import call_openai_api
12
13
  from .openrouter import call_openrouter_api
13
14
  from .streamlake import call_streamlake_api
14
15
  from .synthetic import call_synthetic_api
16
+ from .together import call_together_api
15
17
  from .zai import call_zai_api, call_zai_coding_api
16
18
 
17
19
  __all__ = [
@@ -22,11 +24,13 @@ __all__ = [
22
24
  "call_gemini_api",
23
25
  "call_groq_api",
24
26
  "call_lmstudio_api",
27
+ "call_minimax_api",
25
28
  "call_ollama_api",
26
29
  "call_openai_api",
27
30
  "call_openrouter_api",
28
31
  "call_streamlake_api",
29
32
  "call_synthetic_api",
33
+ "call_together_api",
30
34
  "call_zai_api",
31
35
  "call_zai_coding_api",
32
36
  ]
@@ -0,0 +1,38 @@
1
+ """Minimax API provider for gac."""
2
+
3
+ import os
4
+
5
+ import httpx
6
+
7
+ from gac.errors import AIError
8
+
9
+
10
+ def call_minimax_api(model: str, messages: list[dict], temperature: float, max_tokens: int) -> str:
11
+ """Call Minimax API directly."""
12
+ api_key = os.getenv("MINIMAX_API_KEY")
13
+ if not api_key:
14
+ raise AIError.authentication_error("MINIMAX_API_KEY not found in environment variables")
15
+
16
+ url = "https://api.minimax.io/v1/chat/completions"
17
+ headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
18
+
19
+ data = {"model": model, "messages": messages, "temperature": temperature, "max_tokens": max_tokens}
20
+
21
+ try:
22
+ response = httpx.post(url, headers=headers, json=data, timeout=120)
23
+ response.raise_for_status()
24
+ response_data = response.json()
25
+ content = response_data["choices"][0]["message"]["content"]
26
+ if content is None:
27
+ raise AIError.model_error("Minimax API returned null content")
28
+ if content == "":
29
+ raise AIError.model_error("Minimax API returned empty content")
30
+ return content
31
+ except httpx.HTTPStatusError as e:
32
+ if e.response.status_code == 429:
33
+ raise AIError.rate_limit_error(f"Minimax API rate limit exceeded: {e.response.text}") from e
34
+ raise AIError.model_error(f"Minimax API error: {e.response.status_code} - {e.response.text}") from e
35
+ except httpx.TimeoutException as e:
36
+ raise AIError.timeout_error(f"Minimax API request timed out: {str(e)}") from e
37
+ except Exception as e:
38
+ raise AIError.model_error(f"Error calling Minimax API: {str(e)}") from e
@@ -0,0 +1,38 @@
1
+ """Together AI API provider for gac."""
2
+
3
+ import os
4
+
5
+ import httpx
6
+
7
+ from gac.errors import AIError
8
+
9
+
10
+ def call_together_api(model: str, messages: list[dict], temperature: float, max_tokens: int) -> str:
11
+ """Call Together AI API directly."""
12
+ api_key = os.getenv("TOGETHER_API_KEY")
13
+ if not api_key:
14
+ raise AIError.authentication_error("TOGETHER_API_KEY not found in environment variables")
15
+
16
+ url = "https://api.together.xyz/v1/chat/completions"
17
+ headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
18
+
19
+ data = {"model": model, "messages": messages, "temperature": temperature, "max_tokens": max_tokens}
20
+
21
+ try:
22
+ response = httpx.post(url, headers=headers, json=data, timeout=120)
23
+ response.raise_for_status()
24
+ response_data = response.json()
25
+ content = response_data["choices"][0]["message"]["content"]
26
+ if content is None:
27
+ raise AIError.model_error("Together AI API returned null content")
28
+ if content == "":
29
+ raise AIError.model_error("Together AI API returned empty content")
30
+ return content
31
+ except httpx.HTTPStatusError as e:
32
+ if e.response.status_code == 429:
33
+ raise AIError.rate_limit_error(f"Together AI API rate limit exceeded: {e.response.text}") from e
34
+ raise AIError.model_error(f"Together AI API error: {e.response.status_code} - {e.response.text}") from e
35
+ except httpx.TimeoutException as e:
36
+ raise AIError.timeout_error(f"Together AI API request timed out: {str(e)}") from e
37
+ except Exception as e:
38
+ raise AIError.model_error(f"Error calling Together AI API: {str(e)}") from e
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes