gac 2.0.0__py3-none-any.whl → 2.2.0__py3-none-any.whl

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.

gac/__version__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """Version information for gac package."""
2
2
 
3
- __version__ = "2.0.0"
3
+ __version__ = "2.2.0"
gac/ai.py CHANGED
@@ -21,6 +21,7 @@ from gac.providers import (
21
21
  call_groq_api,
22
22
  call_lmstudio_api,
23
23
  call_minimax_api,
24
+ call_mistral_api,
24
25
  call_ollama_api,
25
26
  call_openai_api,
26
27
  call_openrouter_api,
@@ -94,6 +95,7 @@ def generate_commit_message(
94
95
  "groq": call_groq_api,
95
96
  "lm-studio": call_lmstudio_api,
96
97
  "minimax": call_minimax_api,
98
+ "mistral": call_mistral_api,
97
99
  "ollama": call_ollama_api,
98
100
  "openai": call_openai_api,
99
101
  "openrouter": call_openrouter_api,
gac/ai_utils.py CHANGED
@@ -102,6 +102,7 @@ def generate_with_retries(
102
102
  "groq",
103
103
  "lm-studio",
104
104
  "minimax",
105
+ "mistral",
105
106
  "ollama",
106
107
  "openai",
107
108
  "openrouter",
gac/cli.py CHANGED
@@ -154,5 +154,15 @@ cli.add_command(init_cli)
154
154
  cli.add_command(language_cli)
155
155
  cli.add_command(diff_cli)
156
156
 
157
+
158
+ @click.command(context_settings=language_cli.context_settings)
159
+ @click.pass_context
160
+ def lang(ctx):
161
+ """Set the language for commit messages interactively. (Alias for 'language')"""
162
+ ctx.forward(language_cli)
163
+
164
+
165
+ cli.add_command(lang) # Add the lang alias
166
+
157
167
  if __name__ == "__main__":
158
168
  cli()
gac/constants.py CHANGED
@@ -21,7 +21,7 @@ class EnvDefaults:
21
21
  MAX_RETRIES: int = 3
22
22
  TEMPERATURE: float = 1
23
23
  MAX_OUTPUT_TOKENS: int = 1024 # includes reasoning tokens
24
- WARNING_LIMIT_TOKENS: int = 16384
24
+ WARNING_LIMIT_TOKENS: int = 32768
25
25
  ALWAYS_INCLUDE_SCOPE: bool = False
26
26
  SKIP_SECRET_SCAN: bool = False
27
27
  VERBOSE: bool = False
@@ -214,6 +214,37 @@ class Languages:
214
214
  "fi": "Finnish",
215
215
  }
216
216
 
217
+ # List of languages with display names and English names for CLI selection
218
+ # Format: (display_name, english_name)
219
+ LANGUAGES: list[tuple[str, str]] = [
220
+ ("English", "English"),
221
+ ("简体中文", "Simplified Chinese"),
222
+ ("繁體中文", "Traditional Chinese"),
223
+ ("日本語", "Japanese"),
224
+ ("한국어", "Korean"),
225
+ ("Español", "Spanish"),
226
+ ("Português", "Portuguese"),
227
+ ("Français", "French"),
228
+ ("Deutsch", "German"),
229
+ ("Русский", "Russian"),
230
+ ("हिन्दी", "Hindi"),
231
+ ("Italiano", "Italian"),
232
+ ("Polski", "Polish"),
233
+ ("Türkçe", "Turkish"),
234
+ ("Nederlands", "Dutch"),
235
+ ("Tiếng Việt", "Vietnamese"),
236
+ ("ไทย", "Thai"),
237
+ ("Bahasa Indonesia", "Indonesian"),
238
+ ("Svenska", "Swedish"),
239
+ ("العربية", "Arabic"),
240
+ ("עברית", "Hebrew"),
241
+ ("Ελληνικά", "Greek"),
242
+ ("Dansk", "Danish"),
243
+ ("Norsk", "Norwegian"),
244
+ ("Suomi", "Finnish"),
245
+ ("Custom", "Custom"),
246
+ ]
247
+
217
248
  @staticmethod
218
249
  def resolve_code(language: str) -> str:
219
250
  """Resolve a language code to its full name.
gac/init_cli.py CHANGED
@@ -6,6 +6,8 @@ import click
6
6
  import questionary
7
7
  from dotenv import set_key
8
8
 
9
+ from gac.constants import Languages
10
+
9
11
  GAC_ENV_PATH = Path.home() / ".gac.env"
10
12
 
11
13
 
@@ -33,7 +35,7 @@ def init() -> None:
33
35
 
34
36
  providers = [
35
37
  ("Anthropic", "claude-haiku-4-5"),
36
- ("Cerebras", "qwen-3-coder-480b"),
38
+ ("Cerebras", "zai-glm-4.6"),
37
39
  ("Chutes", "zai-org/GLM-4.6-FP8"),
38
40
  ("Custom (Anthropic)", ""),
39
41
  ("Custom (OpenAI)", ""),
@@ -43,6 +45,7 @@ def init() -> None:
43
45
  ("Groq", "meta-llama/llama-4-maverick-17b-128e-instruct"),
44
46
  ("LM Studio", "gemma3"),
45
47
  ("MiniMax", "MiniMax-M2"),
48
+ ("Mistral", "mistral-small-latest"),
46
49
  ("Ollama", "gemma3"),
47
50
  ("OpenAI", "gpt-4.1-mini"),
48
51
  ("OpenRouter", "openrouter/auto"),
@@ -153,36 +156,7 @@ def init() -> None:
153
156
 
154
157
  # Language selection
155
158
  click.echo("\n")
156
- languages = [
157
- ("English", "English"),
158
- ("简体中文", "Simplified Chinese"),
159
- ("繁體中文", "Traditional Chinese"),
160
- ("日本語", "Japanese"),
161
- ("한국어", "Korean"),
162
- ("Español", "Spanish"),
163
- ("Português", "Portuguese"),
164
- ("Français", "French"),
165
- ("Deutsch", "German"),
166
- ("Русский", "Russian"),
167
- ("हिन्दी", "Hindi"),
168
- ("Italiano", "Italian"),
169
- ("Polski", "Polish"),
170
- ("Türkçe", "Turkish"),
171
- ("Nederlands", "Dutch"),
172
- ("Tiếng Việt", "Vietnamese"),
173
- ("ไทย", "Thai"),
174
- ("Bahasa Indonesia", "Indonesian"),
175
- ("Svenska", "Swedish"),
176
- ("العربية", "Arabic"),
177
- ("עברית", "Hebrew"),
178
- ("Ελληνικά", "Greek"),
179
- ("Dansk", "Danish"),
180
- ("Norsk", "Norwegian"),
181
- ("Suomi", "Finnish"),
182
- ("Custom", "Custom"),
183
- ]
184
-
185
- display_names = [lang[0] for lang in languages]
159
+ display_names = [lang[0] for lang in Languages.LANGUAGES]
186
160
  language_selection = questionary.select(
187
161
  "Select a language for commit messages:", choices=display_names, use_shortcuts=True, use_arrow_keys=True
188
162
  ).ask()
@@ -202,7 +176,7 @@ def init() -> None:
202
176
  language_value = custom_language.strip()
203
177
  else:
204
178
  # Find the English name for the selected language
205
- language_value = next(lang[1] for lang in languages if lang[0] == language_selection)
179
+ language_value = next(lang[1] for lang in Languages.LANGUAGES if lang[0] == language_selection)
206
180
 
207
181
  if language_value:
208
182
  # Ask about prefix translation
gac/language_cli.py CHANGED
@@ -6,6 +6,8 @@ import click
6
6
  import questionary
7
7
  from dotenv import set_key, unset_key
8
8
 
9
+ from gac.constants import Languages
10
+
9
11
  GAC_ENV_PATH = Path.home() / ".gac.env"
10
12
 
11
13
 
@@ -14,38 +16,7 @@ def language() -> None:
14
16
  """Set the language for commit messages interactively."""
15
17
  click.echo("Select a language for your commit messages:\n")
16
18
 
17
- # Languages sorted by programmer population likelihood
18
- # Based on GitHub statistics and global developer demographics
19
- languages = [
20
- ("English", "English"),
21
- ("简体中文", "Simplified Chinese"),
22
- ("繁體中文", "Traditional Chinese"),
23
- ("日本語", "Japanese"),
24
- ("한국어", "Korean"),
25
- ("Español", "Spanish"),
26
- ("Português", "Portuguese"),
27
- ("Français", "French"),
28
- ("Deutsch", "German"),
29
- ("Русский", "Russian"),
30
- ("हिन्दी", "Hindi"),
31
- ("Italiano", "Italian"),
32
- ("Polski", "Polish"),
33
- ("Türkçe", "Turkish"),
34
- ("Nederlands", "Dutch"),
35
- ("Tiếng Việt", "Vietnamese"),
36
- ("ไทย", "Thai"),
37
- ("Bahasa Indonesia", "Indonesian"),
38
- ("Svenska", "Swedish"),
39
- ("العربية", "Arabic"),
40
- ("עברית", "Hebrew"),
41
- ("Ελληνικά", "Greek"),
42
- ("Dansk", "Danish"),
43
- ("Norsk", "Norwegian"),
44
- ("Suomi", "Finnish"),
45
- ("Custom", "Custom"),
46
- ]
47
-
48
- display_names = [lang[0] for lang in languages]
19
+ display_names = [lang[0] for lang in Languages.LANGUAGES]
49
20
  selection = questionary.select(
50
21
  "Choose your language:", choices=display_names, use_shortcuts=True, use_arrow_keys=True
51
22
  ).ask()
@@ -78,7 +49,7 @@ def language() -> None:
78
49
  language_value = custom_language.strip()
79
50
  else:
80
51
  # Find the English name for the selected language
81
- language_value = next(lang[1] for lang in languages if lang[0] == selection)
52
+ language_value = next(lang[1] for lang in Languages.LANGUAGES if lang[0] == selection)
82
53
 
83
54
  # Ask about prefix translation
84
55
  click.echo() # Blank line for spacing
gac/main.py CHANGED
@@ -25,6 +25,7 @@ from gac.git import (
25
25
  from gac.preprocess import preprocess_diff
26
26
  from gac.prompt import build_prompt, clean_commit_message
27
27
  from gac.security import get_affected_files, scan_staged_diff
28
+ from gac.utils import edit_commit_message_inplace
28
29
 
29
30
  logger = logging.getLogger(__name__)
30
31
 
@@ -277,7 +278,7 @@ def main(
277
278
  if require_confirmation:
278
279
  while True:
279
280
  response = click.prompt(
280
- "Proceed with commit above? [y/n/r/<feedback>]",
281
+ "Proceed with commit above? [y/n/r/e/<feedback>]",
281
282
  type=str,
282
283
  show_default=False,
283
284
  ).strip()
@@ -290,6 +291,18 @@ def main(
290
291
  sys.exit(0)
291
292
  if response == "":
292
293
  continue
294
+ if response_lower in ["e", "edit"]:
295
+ edited_message = edit_commit_message_inplace(commit_message)
296
+ if edited_message:
297
+ commit_message = edited_message
298
+ conversation_messages[-1] = {"role": "assistant", "content": commit_message}
299
+ logger.info("Commit message edited by user")
300
+ console.print("\n[bold green]Edited commit message:[/bold green]")
301
+ console.print(Panel(commit_message, title="Commit Message", border_style="cyan"))
302
+ else:
303
+ console.print("[yellow]Using previous message.[/yellow]")
304
+ console.print(Panel(commit_message, title="Commit Message", border_style="cyan"))
305
+ continue
293
306
  if response_lower in ["r", "reroll"]:
294
307
  feedback_message = (
295
308
  "Please provide an alternative commit message using the same repository context."
gac/providers/__init__.py CHANGED
@@ -11,6 +11,7 @@ from .gemini import call_gemini_api
11
11
  from .groq import call_groq_api
12
12
  from .lmstudio import call_lmstudio_api
13
13
  from .minimax import call_minimax_api
14
+ from .mistral import call_mistral_api
14
15
  from .ollama import call_ollama_api
15
16
  from .openai import call_openai_api
16
17
  from .openrouter import call_openrouter_api
@@ -31,6 +32,7 @@ __all__ = [
31
32
  "call_groq_api",
32
33
  "call_lmstudio_api",
33
34
  "call_minimax_api",
35
+ "call_mistral_api",
34
36
  "call_ollama_api",
35
37
  "call_openai_api",
36
38
  "call_openrouter_api",
@@ -0,0 +1,38 @@
1
+ """Mistral API provider for gac."""
2
+
3
+ import os
4
+
5
+ import httpx
6
+
7
+ from gac.errors import AIError
8
+
9
+
10
+ def call_mistral_api(model: str, messages: list[dict], temperature: float, max_tokens: int) -> str:
11
+ """Call Mistral API directly."""
12
+ api_key = os.getenv("MISTRAL_API_KEY")
13
+ if not api_key:
14
+ raise AIError.authentication_error("MISTRAL_API_KEY not found in environment variables")
15
+
16
+ url = "https://api.mistral.ai/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("Mistral API returned null content")
28
+ if content == "":
29
+ raise AIError.model_error("Mistral 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"Mistral API rate limit exceeded: {e.response.text}") from e
34
+ raise AIError.model_error(f"Mistral API error: {e.response.status_code} - {e.response.text}") from e
35
+ except httpx.TimeoutException as e:
36
+ raise AIError.timeout_error(f"Mistral API request timed out: {str(e)}") from e
37
+ except Exception as e:
38
+ raise AIError.model_error(f"Error calling Mistral API: {str(e)}") from e
gac/utils.py CHANGED
@@ -130,3 +130,141 @@ def run_subprocess(
130
130
  # Convert generic exceptions to CalledProcessError for consistency
131
131
  raise subprocess.CalledProcessError(1, command, "", str(e)) from e
132
132
  return ""
133
+
134
+
135
+ def edit_commit_message_inplace(message: str) -> str | None:
136
+ """Edit commit message in-place using rich terminal editing.
137
+
138
+ Uses prompt_toolkit to provide a rich editing experience with:
139
+ - Multi-line editing
140
+ - Vi/Emacs key bindings
141
+ - Line editing capabilities
142
+ - Esc+Enter or Ctrl+S to submit
143
+ - Ctrl+C to cancel
144
+
145
+ Args:
146
+ message: The initial commit message
147
+
148
+ Returns:
149
+ The edited commit message, or None if editing was cancelled
150
+
151
+ Example:
152
+ >>> edited = edit_commit_message_inplace("feat: add feature")
153
+ >>> # User can edit the message using vi/emacs key bindings
154
+ >>> # Press Esc+Enter or Ctrl+S to submit
155
+ """
156
+ from prompt_toolkit import Application
157
+ from prompt_toolkit.buffer import Buffer
158
+ from prompt_toolkit.document import Document
159
+ from prompt_toolkit.enums import EditingMode
160
+ from prompt_toolkit.key_binding import KeyBindings
161
+ from prompt_toolkit.layout import HSplit, Layout, Window
162
+ from prompt_toolkit.layout.controls import BufferControl, FormattedTextControl
163
+ from prompt_toolkit.layout.margins import ScrollbarMargin
164
+ from prompt_toolkit.styles import Style
165
+
166
+ try:
167
+ console.print("\n[info]Edit commit message:[/info]")
168
+ console.print()
169
+
170
+ # Create buffer for text editing
171
+ text_buffer = Buffer(
172
+ document=Document(text=message, cursor_position=0),
173
+ multiline=True,
174
+ enable_history_search=False,
175
+ )
176
+
177
+ # Track submission state
178
+ cancelled = {"value": False}
179
+ submitted = {"value": False}
180
+
181
+ # Create text editor window
182
+ text_window = Window(
183
+ content=BufferControl(
184
+ buffer=text_buffer,
185
+ focus_on_click=True,
186
+ ),
187
+ height=lambda: max(5, message.count("\n") + 3),
188
+ wrap_lines=True,
189
+ right_margins=[ScrollbarMargin()],
190
+ )
191
+
192
+ # Create hint window
193
+ hint_window = Window(
194
+ content=FormattedTextControl(
195
+ text=[("class:hint", " Esc+Enter or Ctrl+S to submit | Ctrl+C to cancel ")],
196
+ ),
197
+ height=1,
198
+ dont_extend_height=True,
199
+ )
200
+
201
+ # Create layout
202
+ root_container = HSplit(
203
+ [
204
+ text_window,
205
+ hint_window,
206
+ ]
207
+ )
208
+
209
+ layout = Layout(root_container, focused_element=text_window)
210
+
211
+ # Create key bindings
212
+ kb = KeyBindings()
213
+
214
+ @kb.add("c-s")
215
+ def _(event):
216
+ """Submit with Ctrl+S."""
217
+ submitted["value"] = True
218
+ event.app.exit()
219
+
220
+ @kb.add("c-c")
221
+ def _(event):
222
+ """Cancel editing."""
223
+ cancelled["value"] = True
224
+ event.app.exit()
225
+
226
+ @kb.add("escape", "enter")
227
+ def _(event):
228
+ """Submit with Esc+Enter."""
229
+ submitted["value"] = True
230
+ event.app.exit()
231
+
232
+ # Create and run application
233
+ custom_style = Style.from_dict(
234
+ {
235
+ "hint": "#888888",
236
+ }
237
+ )
238
+
239
+ app: Application[None] = Application(
240
+ layout=layout,
241
+ key_bindings=kb,
242
+ full_screen=False,
243
+ mouse_support=False,
244
+ editing_mode=EditingMode.VI, # Enable vi key bindings
245
+ style=custom_style,
246
+ )
247
+
248
+ app.run()
249
+
250
+ # Handle result
251
+ if cancelled["value"]:
252
+ console.print("\n[yellow]Edit cancelled.[/yellow]")
253
+ return None
254
+
255
+ if submitted["value"]:
256
+ edited_message = text_buffer.text.strip()
257
+ if not edited_message:
258
+ console.print("[yellow]Commit message cannot be empty. Edit cancelled.[/yellow]")
259
+ return None
260
+ return edited_message
261
+
262
+ return None
263
+
264
+ except (EOFError, KeyboardInterrupt):
265
+ console.print("\n[yellow]Edit cancelled.[/yellow]")
266
+ return None
267
+ except Exception as e:
268
+ logger.error(f"Error during in-place editing: {e}")
269
+ console.print(f"[error]Failed to edit commit message: {e}[/error]")
270
+ return None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gac
3
- Version: 2.0.0
3
+ Version: 2.2.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
@@ -25,6 +25,7 @@ Requires-Dist: click>=8.3.0
25
25
  Requires-Dist: halo
26
26
  Requires-Dist: httpcore>=1.0.9
27
27
  Requires-Dist: httpx>=0.28.0
28
+ Requires-Dist: prompt-toolkit>=3.0.36
28
29
  Requires-Dist: pydantic>=2.12.0
29
30
  Requires-Dist: python-dotenv>=1.1.1
30
31
  Requires-Dist: questionary
@@ -52,9 +53,9 @@ Description-Content-Type: text/markdown
52
53
  [![Contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg)](docs/CONTRIBUTING.md)
53
54
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
54
55
 
55
- **LLM-powered commit messages that understand your code.**
56
+ **LLM-powered commit messages that understand your code!**
56
57
 
57
- **Tired of writing commit messages?** Replace `git commit -m "..."` with `gac` for contextual, well-formatted commit messages generated by large language models.
58
+ **Automate your commits!** Replace `git commit -m "..."` with `gac` for contextual, well-formatted commit messages generated by large language models!
58
59
 
59
60
  ---
60
61
 
@@ -68,7 +69,7 @@ Intelligent, contextual messages that explain the **why** behind your changes:
68
69
 
69
70
  ## Quick Start
70
71
 
71
- ### Use without installing
72
+ ### Use gac without installing
72
73
 
73
74
  ```bash
74
75
  uvx gac init # Configure your LLM provider
@@ -77,7 +78,7 @@ uvx gac # Generate and commit with LLM
77
78
 
78
79
  That's it! Review the generated message and confirm with `y`.
79
80
 
80
- ### Install gac globally
81
+ ### Install and use gac
81
82
 
82
83
  ```bash
83
84
  uv tool install gac
@@ -85,6 +86,12 @@ gac init
85
86
  gac
86
87
  ```
87
88
 
89
+ ### Upgrade installed gac
90
+
91
+ ```bash
92
+ uv tool upgrade gac
93
+ ```
94
+
88
95
  ---
89
96
 
90
97
  ## Key Features
@@ -92,7 +99,7 @@ gac
92
99
  ### 🌐 **Supported Providers**
93
100
 
94
101
  - **Anthropic** • **Cerebras** • **Chutes.ai** • **DeepSeek** • **Fireworks**
95
- - **Gemini** • **Groq** • **LM Studio** • **MiniMax** • **Ollama** • **OpenAI**
102
+ - **Gemini** • **Groq** • **LM Studio** • **MiniMax** • **Mistral** • **Ollama** • **OpenAI**
96
103
  - **OpenRouter** • **Streamlake** • **Synthetic.new** • **Together AI**
97
104
  - **Z.AI** • **Z.AI Coding** • **Custom Endpoints (Anthropic/OpenAI)**
98
105
 
@@ -117,7 +124,7 @@ gac
117
124
 
118
125
  ### 💻 **Developer Experience**
119
126
 
120
- - **Interactive feedback**: Type `r` to reroll, or directly type your feedback like `make it shorter` or `focus on the bug fix`
127
+ - **Interactive feedback**: Type `r` to reroll, `e` to edit in-place with vi/emacs keybindings, or directly type your feedback like `make it shorter` or `focus on the bug fix`
121
128
  - **One-command workflows**: Complete workflows with flags like `gac -ayp` (stage all, auto-confirm, push)
122
129
  - **Git integration**: Respects pre-commit and lefthook hooks, running them before expensive LLM operations
123
130
 
@@ -140,7 +147,7 @@ git add .
140
147
  # Generate and commit with LLM
141
148
  gac
142
149
 
143
- # Review → y (commit) | n (cancel) | r (reroll) | or type feedback
150
+ # Review → y (commit) | n (cancel) | r (reroll) | e (edit) | or type feedback
144
151
  ```
145
152
 
146
153
  ### Common Commands
@@ -177,13 +184,18 @@ gac --skip-secret-scan
177
184
 
178
185
  ### Interactive Feedback System
179
186
 
180
- Not happy with the result? You have two options:
187
+ Not happy with the result? You have several options:
181
188
 
182
189
  ```bash
183
190
  # Simple reroll (no feedback)
184
191
  r
185
192
 
186
- # Or just type your feedback directly - no prefix needed!
193
+ # Edit in-place with rich terminal editing
194
+ e
195
+ # Uses prompt_toolkit for multi-line editing with vi/emacs keybindings
196
+ # Press Esc+Enter or Ctrl+S to submit, Ctrl+C to cancel
197
+
198
+ # Or just type your feedback directly!
187
199
  make it shorter and focus on the performance improvement
188
200
  use conventional commit format with scope
189
201
  explain the security implications
@@ -191,6 +203,13 @@ explain the security implications
191
203
  # Press Enter on empty input to see the prompt again
192
204
  ```
193
205
 
206
+ The edit feature (`e`) provides rich in-place terminal editing, allowing you to:
207
+
208
+ - **Edit naturally**: Multi-line editing with familiar vi/emacs key bindings
209
+ - **Make quick fixes**: Correct typos, adjust wording, or refine formatting
210
+ - **Add details**: Include information the LLM might have missed
211
+ - **Restructure**: Reorganize bullet points or change the message structure
212
+
194
213
  ---
195
214
 
196
215
  ## Configuration
@@ -1,22 +1,22 @@
1
1
  gac/__init__.py,sha256=z9yGInqtycFIT3g1ca24r-A3699hKVaRqGUI79wsmMc,415
2
- gac/__version__.py,sha256=sXY5h9N-vjDIgAsvaFio9v3KucauBzZ9AFdd_Oe8M28,66
3
- gac/ai.py,sha256=fg642la4yMecOwfZHQ7Ixl6z-5_qj9Q1SxwVMnPDCcY,4244
4
- gac/ai_utils.py,sha256=EDkw0nnwnV5Ba2CLEo2HC15-L5BZtGJATin5Az0ZHkg,7426
5
- gac/cli.py,sha256=TV1IWwcRmEfbqXLlfGmTms5NCEqaJXUGIdFxmOg0tC0,5546
2
+ gac/__version__.py,sha256=r4l_6jWyV87srDy0RVRKwXgzwJscJzmR4SM825CjGh0,66
3
+ gac/ai.py,sha256=iBHeLsqe6iyFj86wbvEosyy4vkjAN1BlLQeqtb_rfmo,4303
4
+ gac/ai_utils.py,sha256=094ujZVlbDnHM3HPxiBSCbGi_5MD6bOKCj2SjKVDDK0,7445
5
+ gac/cli.py,sha256=SOrSfrlku99O7O8zev5hRVmADAmJ7AIkM7Z0dquuCbQ,5807
6
6
  gac/config.py,sha256=O9n09-sFOqlkf47vieEP7fI5I7uhu1cXn9PUZ5yiYkw,1974
7
7
  gac/config_cli.py,sha256=v9nFHZO1RvK9fzHyuUS6SG-BCLHMsdOMDwWamBhVVh4,1608
8
- gac/constants.py,sha256=-VYqL1M99RAmEwQHTe6lMYVkPHSSYQJUvzYvBp8Bmck,8494
8
+ gac/constants.py,sha256=zgylsiKnpBunoNzVT6RpAVe9m8cgxZrZ55kRN6ZP_cM,9586
9
9
  gac/diff_cli.py,sha256=wnVQ9OFGnM0d2Pj9WVjWbo0jxqIuRHVAwmb8wU9Pa3E,5676
10
10
  gac/errors.py,sha256=ysDIVRCd0YQVTOW3Q6YzdolxCdtkoQCAFf3_jrqbjUY,7916
11
11
  gac/git.py,sha256=g6tvph50zV-wrTWrxARYXEpl0NeI8-ffFwHoqhp3fSE,8033
12
- gac/init_cli.py,sha256=wyyPNjO47IcwFrO-jrqJ5rs1SsKdDJnhuRO83heh1tw,9700
13
- gac/language_cli.py,sha256=xmmIonIhOR83VtRFj5Dy8JDtpa5qCNbNxSEZt-1T0a8,4040
14
- gac/main.py,sha256=LJhONOP_w09TE7HOd4T_NiAzmiqemY2N7EZ6biqwVQE,15221
12
+ gac/init_cli.py,sha256=KvFOvjjyMpdJ3MhJFvXSuYjdfulPA6hCP11YXwjHrqw,8849
13
+ gac/language_cli.py,sha256=J4xZNNrMvHamsjK4TCsOVj0lrjYDtLMuHlnTqN0-N_w,3024
14
+ gac/main.py,sha256=fK48fGHeJ4qGsttbKDoMXs4Gj3NncFHz_F_cJZI70IQ,16159
15
15
  gac/preprocess.py,sha256=hk2p2X4-xVDvuy-T1VMzMa9k5fTUbhlWDyw89DCf81Q,15379
16
16
  gac/prompt.py,sha256=HLvsW3YQLdTfw2N9UgjZ0jWckUc1x76V7Kcqjcl8Fsk,28633
17
17
  gac/security.py,sha256=15Yp6YR8QC4eECJi1BUCkMteh_veZXUbLL6W8qGcDm4,9920
18
- gac/utils.py,sha256=nV42-brIHW_fBg7x855GM8nRrqEBbRzTSweg-GTyGE8,3971
19
- gac/providers/__init__.py,sha256=3WTzh3ngAdvR40eezpMMFD7Zibb-LxexDYUcSm4axQI,1305
18
+ gac/utils.py,sha256=owkUzwJBX8mi0VrP3HKxku5vJj_JlaShzTYwjjsHn-4,8126
19
+ gac/providers/__init__.py,sha256=pT1xcKoZkPm6BWaxcAQ299-Ca5zZ31kf4DeQYAim9Tw,1367
20
20
  gac/providers/anthropic.py,sha256=VK5d1s1PmBNDwh_x7illQ2CIZIHNIYU28btVfizwQPs,2036
21
21
  gac/providers/cerebras.py,sha256=Ik8lhlsliGJVkgDgqlThfpra9tqbdYQZkaC4eNxRd9w,1648
22
22
  gac/providers/chutes.py,sha256=cclJOLuGVIiiaF-9Bs1kH6SSOhEmduGB2zZ86KIaXKw,2617
@@ -28,6 +28,7 @@ gac/providers/gemini.py,sha256=kl9WKdPm_ANYk0hsrUyMdACzR0cm8Eui9M1IwObYW-4,3348
28
28
  gac/providers/groq.py,sha256=9v2fAjDa_iRNHFptiUBN8Vt7ZDKkW_JOmIBeYvycD1M,2806
29
29
  gac/providers/lmstudio.py,sha256=R82-f0tWdFfGQxLT6o3Q2tfvYguF7ESUg9DEUHNyrDk,2146
30
30
  gac/providers/minimax.py,sha256=oI5rEVlkcYenNUNH53zS00X8NqpcZ1gMsTGzQCsmes4,1630
31
+ gac/providers/mistral.py,sha256=b2Du1nJutKjmJXmsXz4Ne43Yn52OSS0q6BKGoZnfH8Q,1630
31
32
  gac/providers/ollama.py,sha256=hPkagbhEiAoH9RTET4EQe9-lTL0YmMRCbQ5dVbRQw6Q,2095
32
33
  gac/providers/openai.py,sha256=iHVD6bHf57W-QmW7u1Ee5vOpev7XZ-K75NcolLfebOk,1630
33
34
  gac/providers/openrouter.py,sha256=H3ce8JcRUYq1I30lOjGESdX7jfoPkW3mKAYnc2aYfBw,2204
@@ -35,8 +36,8 @@ gac/providers/streamlake.py,sha256=KAA2ZnpuEI5imzvdWVWUhEBHSP0BMnprKXte6CbwBWY,2
35
36
  gac/providers/synthetic.py,sha256=sRMIJTS9LpcXd9A7qp_ZjZxdqtTKRn9fl1W4YwJZP4c,1855
36
37
  gac/providers/together.py,sha256=1bUIVHfYzcEDw4hQPE8qV6hjc2JNHPv_khVgpk2IJxI,1667
37
38
  gac/providers/zai.py,sha256=kywhhrCfPBu0rElZyb-iENxQxxpVGykvePuL4xrXlaU,2739
38
- gac-2.0.0.dist-info/METADATA,sha256=X4MCo_VM2qkYzwREOCmOZSpV5YC_NZbTH9o4yHOyuHg,8909
39
- gac-2.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
40
- gac-2.0.0.dist-info/entry_points.txt,sha256=tdjN-XMmcWfL92swuRAjT62bFLOAwk9bTMRLGP5Z4aI,36
41
- gac-2.0.0.dist-info/licenses/LICENSE,sha256=vOab37NouL1PNs5BswnPayrMCqaN2sqLfMQfqPDrpZg,1103
42
- gac-2.0.0.dist-info/RECORD,,
39
+ gac-2.2.0.dist-info/METADATA,sha256=Z5Vv7oBzqWKVr7lDmk_HFjq3kF13DNnCkMnXKZDKRtA,9609
40
+ gac-2.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
41
+ gac-2.2.0.dist-info/entry_points.txt,sha256=tdjN-XMmcWfL92swuRAjT62bFLOAwk9bTMRLGP5Z4aI,36
42
+ gac-2.2.0.dist-info/licenses/LICENSE,sha256=vOab37NouL1PNs5BswnPayrMCqaN2sqLfMQfqPDrpZg,1103
43
+ gac-2.2.0.dist-info/RECORD,,
File without changes