gac 1.7.0__py3-none-any.whl → 1.9.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__ = "1.7.0"
3
+ __version__ = "1.9.0"
gac/ai.py CHANGED
@@ -12,6 +12,7 @@ from gac.errors import AIError
12
12
  from gac.providers import (
13
13
  call_anthropic_api,
14
14
  call_cerebras_api,
15
+ call_chutes_api,
15
16
  call_gemini_api,
16
17
  call_groq_api,
17
18
  call_lmstudio_api,
@@ -69,6 +70,7 @@ def generate_commit_message(
69
70
  provider_funcs = {
70
71
  "anthropic": call_anthropic_api,
71
72
  "cerebras": call_cerebras_api,
73
+ "chutes": call_chutes_api,
72
74
  "gemini": call_gemini_api,
73
75
  "groq": call_groq_api,
74
76
  "lmstudio": call_lmstudio_api,
gac/ai_utils.py CHANGED
@@ -98,7 +98,7 @@ def generate_with_retries(
98
98
  "cerebras",
99
99
  "gemini",
100
100
  "groq",
101
- "lmstudio",
101
+ "lm-studio",
102
102
  "ollama",
103
103
  "openai",
104
104
  "openrouter",
gac/cli.py CHANGED
@@ -45,7 +45,12 @@ logger = logging.getLogger(__name__)
45
45
  @click.option("--model", "-m", help="Override the default model (format: 'provider:model_name')")
46
46
  # Output options
47
47
  @click.option("--quiet", "-q", is_flag=True, help="Suppress non-error output")
48
- @click.option("--verbose", "-v", is_flag=True, help="Increase output verbosity to INFO")
48
+ @click.option(
49
+ "--verbose",
50
+ "-v",
51
+ is_flag=True,
52
+ help="Generate detailed commit messages with motivation, architecture, and impact sections",
53
+ )
49
54
  @click.option(
50
55
  "--log-level",
51
56
  default=config["log_level"],
@@ -82,8 +87,6 @@ def cli(
82
87
  print(f"Git Auto Commit (gac) version: {__version__}")
83
88
  sys.exit(0)
84
89
  effective_log_level = log_level
85
- if verbose and log_level not in ("DEBUG", "INFO"):
86
- effective_log_level = "INFO"
87
90
  if quiet:
88
91
  effective_log_level = "ERROR"
89
92
  setup_logging(effective_log_level)
@@ -92,6 +95,9 @@ def cli(
92
95
  # Determine if we should infer scope based on -s flag or always_include_scope setting
93
96
  infer_scope = bool(scope or config.get("always_include_scope", False))
94
97
 
98
+ # Determine if verbose mode should be enabled based on -v flag or verbose config setting
99
+ use_verbose = bool(verbose or config.get("verbose", False))
100
+
95
101
  try:
96
102
  main(
97
103
  stage_all=add_all,
@@ -104,6 +110,7 @@ def cli(
104
110
  push=push,
105
111
  quiet=quiet,
106
112
  dry_run=dry_run,
113
+ verbose=use_verbose,
107
114
  no_verify=no_verify,
108
115
  skip_secret_scan=skip_secret_scan or bool(config.get("skip_secret_scan", False)),
109
116
  )
gac/config.py CHANGED
@@ -37,6 +37,7 @@ def load_config() -> dict[str, str | int | float | bool]:
37
37
  in ("true", "1", "yes", "on"),
38
38
  "skip_secret_scan": os.getenv("GAC_SKIP_SECRET_SCAN", str(EnvDefaults.SKIP_SECRET_SCAN)).lower()
39
39
  in ("true", "1", "yes", "on"),
40
+ "verbose": os.getenv("GAC_VERBOSE", str(EnvDefaults.VERBOSE)).lower() in ("true", "1", "yes", "on"),
40
41
  }
41
42
 
42
43
  return config
gac/constants.py CHANGED
@@ -25,6 +25,7 @@ class EnvDefaults:
25
25
  WARNING_LIMIT_TOKENS: int = 16384
26
26
  ALWAYS_INCLUDE_SCOPE: bool = False
27
27
  SKIP_SECRET_SCAN: bool = False
28
+ VERBOSE: bool = False
28
29
 
29
30
 
30
31
  class Logging:
gac/init_cli.py CHANGED
@@ -32,8 +32,9 @@ def init() -> None:
32
32
  click.echo(f"Created $HOME/.gac.env at {GAC_ENV_PATH}.")
33
33
 
34
34
  providers = [
35
- ("Anthropic", "claude-3-5-haiku-latest"),
35
+ ("Anthropic", "claude-haiku-4-5"),
36
36
  ("Cerebras", "qwen-3-coder-480b"),
37
+ ("Chutes.ai", "zai-org/GLM-4.6-FP8"),
37
38
  ("Gemini", "gemini-2.5-flash"),
38
39
  ("Groq", "meta-llama/llama-4-maverick-17b-128e-instruct"),
39
40
  ("LM Studio", "gemma3"),
gac/main.py CHANGED
@@ -43,6 +43,7 @@ def main(
43
43
  push: bool = False,
44
44
  quiet: bool = False,
45
45
  dry_run: bool = False,
46
+ verbose: bool = False,
46
47
  no_verify: bool = False,
47
48
  skip_secret_scan: bool = False,
48
49
  ) -> None:
@@ -178,6 +179,7 @@ def main(
178
179
  one_liner=one_liner,
179
180
  hint=hint,
180
181
  infer_scope=infer_scope,
182
+ verbose=verbose,
181
183
  )
182
184
 
183
185
  if show_prompt:
@@ -275,6 +277,7 @@ def main(
275
277
  one_liner=one_liner,
276
278
  hint=combined_hint,
277
279
  infer_scope=infer_scope,
280
+ verbose=verbose,
278
281
  )
279
282
  else:
280
283
  # No hint given, just reroll with same prompts
gac/prompt.py CHANGED
@@ -43,7 +43,43 @@ When changes span multiple areas:
43
43
  - Detailed body with multiple bullet points explaining the key changes
44
44
  - Focus on WHY changes were made, not just WHAT was changed
45
45
  - Order points from most important to least important
46
- </multi_line>
46
+ </multi_line><verbose>
47
+ IMPORTANT: You MUST create a MULTI-PARAGRAPH commit message with detailed sections.
48
+ DO NOT create a single-line commit message.
49
+
50
+ Your commit message MUST follow this structure:
51
+
52
+ Line 1: A concise summary (up to ~72 characters) with conventional commit prefix
53
+ Line 2: BLANK LINE (required)
54
+ Lines 3+: Detailed multi-paragraph body with the following sections:
55
+
56
+ ## Motivation
57
+ Explain why this commit exists in 2-3 sentences. What problem does it solve? What need does it address?
58
+
59
+ ## Architecture / Approach
60
+ Describe how it was implemented in 2-4 sentences. Include key design decisions and any rejected alternatives.
61
+ Reference specific modules, functions, or classes when relevant.
62
+
63
+ ## Affected Components
64
+ List the main modules, subsystems, or directories impacted by this change.
65
+
66
+ OPTIONAL sections (include only if relevant):
67
+
68
+ ## Performance / Security Impact
69
+ Describe any performance improvements, trade-offs, or security considerations.
70
+ Include concrete data such as benchmark results if available.
71
+
72
+ ## Compatibility / Testing
73
+ Mention any compatibility considerations, known limitations, testing performed, or next steps for validation.
74
+
75
+ REQUIREMENTS:
76
+ - Your response MUST be at least 10 lines long with multiple paragraphs
77
+ - Use active voice and present tense ("Implements", "Adds", "Refactors")
78
+ - Provide concrete, specific information rather than vague descriptions
79
+ - Keep the tone professional and technical
80
+ - Focus on intent and reasoning, not just code changes
81
+ - Use markdown headers (##) for section organization
82
+ </verbose>
47
83
  </format>
48
84
 
49
85
  <conventions_no_scope>
@@ -158,8 +194,50 @@ Bad commit messages:
158
194
  [ERROR] Changes
159
195
  </examples_no_scope>
160
196
 
197
+ <examples_verbose_no_scope>
198
+ Example of a good VERBOSE commit message (without scope):
199
+
200
+ feat: add verbose mode for detailed commit message generation
201
+
202
+ ## Motivation
203
+ Users need the ability to generate comprehensive commit messages that follow best practices for code review and documentation. The existing one-liner and multi-line modes don't provide sufficient structure for complex changes that require detailed explanations of motivation, architecture decisions, and impact.
204
+
205
+ ## Architecture / Approach
206
+ Adds a new --verbose/-v flag to the CLI that modifies the prompt generation in build_prompt(). When enabled, the prompt instructs the AI to generate commit messages with structured sections including Motivation, Architecture/Approach, Affected Components, and optional Performance/Testing sections. The implementation uses the existing format selection logic with verbose taking priority over one_liner and multi_line modes.
207
+
208
+ ## Affected Components
209
+ - src/gac/cli.py: Added --verbose flag and parameter passing
210
+ - src/gac/main.py: Extended main() to accept and pass verbose parameter
211
+ - src/gac/prompt.py: Added <verbose> template section with detailed instructions
212
+ - tests/test_prompt.py: Added test coverage for verbose mode
213
+
214
+ ## Compatibility / Testing
215
+ Added new test test_build_prompt_verbose_mode to verify the verbose template generation. All existing tests pass. The verbose mode is opt-in via the -v flag, maintaining backward compatibility.
216
+ </examples_verbose_no_scope>
217
+
218
+ <examples_verbose_with_scope>
219
+ Example of a good VERBOSE commit message (with scope):
220
+
221
+ feat(cli): add verbose mode for detailed commit message generation
222
+
223
+ ## Motivation
224
+ Users need the ability to generate comprehensive commit messages that follow best practices for code review and documentation. The existing one-liner and multi-line modes don't provide sufficient structure for complex changes that require detailed explanations of motivation, architecture decisions, and impact.
225
+
226
+ ## Architecture / Approach
227
+ Adds a new --verbose/-v flag to the CLI that modifies the prompt generation in build_prompt(). When enabled, the prompt instructs the AI to generate commit messages with structured sections including Motivation, Architecture/Approach, Affected Components, and optional Performance/Testing sections. The implementation uses the existing format selection logic with verbose taking priority over one_liner and multi_line modes.
228
+
229
+ ## Affected Components
230
+ - src/gac/cli.py: Added --verbose flag and parameter passing
231
+ - src/gac/main.py: Extended main() to accept and pass verbose parameter
232
+ - src/gac/prompt.py: Added <verbose> template section with detailed instructions
233
+ - tests/test_prompt.py: Added test coverage for verbose mode
234
+
235
+ ## Compatibility / Testing
236
+ Added new test test_build_prompt_verbose_mode to verify the verbose template generation. All existing tests pass. The verbose mode is opt-in via the -v flag, maintaining backward compatibility.
237
+ </examples_verbose_with_scope>
238
+
161
239
  <examples_with_scope>
162
- Good commit messages (with scope):
240
+ Good commit message top lines (with scope):
163
241
  [OK] feat(auth): add OAuth2 integration with Google and GitHub
164
242
  [OK] fix(api): resolve race condition in user session management
165
243
  [OK] docs(readme): add troubleshooting section for common installation issues
@@ -201,6 +279,7 @@ def build_prompt(
201
279
  one_liner: bool = False,
202
280
  infer_scope: bool = False,
203
281
  hint: str = "",
282
+ verbose: bool = False,
204
283
  ) -> tuple[str, str]:
205
284
  """Build system and user prompts for the AI model using the provided template and git information.
206
285
 
@@ -211,6 +290,7 @@ def build_prompt(
211
290
  one_liner: Whether to request a one-line commit message
212
291
  infer_scope: Whether to infer scope for the commit message
213
292
  hint: Optional hint to guide the AI
293
+ verbose: Whether to generate detailed commit messages with motivation, architecture, and impact sections
214
294
 
215
295
  Returns:
216
296
  Tuple of (system_prompt, user_prompt) ready to be sent to an AI model
@@ -251,21 +331,60 @@ def build_prompt(
251
331
  template = re.sub(r"<hint>.*?</hint>", "", template, flags=re.DOTALL)
252
332
  logger.debug("No hint provided")
253
333
 
254
- # Process format options (one-liner vs multi-line)
255
- if one_liner:
334
+ # Process format options (verbose, one-liner, or multi-line)
335
+ # Priority: verbose > one_liner > multi_line
336
+ if verbose:
337
+ # Verbose mode: remove one_liner and multi_line, keep verbose
338
+ template = re.sub(r"<one_liner>.*?</one_liner>", "", template, flags=re.DOTALL)
339
+ template = re.sub(r"<multi_line>.*?</multi_line>", "", template, flags=re.DOTALL)
340
+ elif one_liner:
341
+ # One-liner mode: remove multi_line and verbose
256
342
  template = re.sub(r"<multi_line>.*?</multi_line>", "", template, flags=re.DOTALL)
343
+ template = re.sub(r"<verbose>.*?</verbose>", "", template, flags=re.DOTALL)
257
344
  else:
345
+ # Multi-line mode (default): remove one_liner and verbose
258
346
  template = re.sub(r"<one_liner>.*?</one_liner>", "", template, flags=re.DOTALL)
347
+ template = re.sub(r"<verbose>.*?</verbose>", "", template, flags=re.DOTALL)
259
348
 
260
- # Clean up examples sections based on infer_scope settings
261
- if infer_scope:
262
- # With scope (inferred) - keep scope examples, remove no_scope examples
349
+ # Clean up examples sections based on verbose and infer_scope settings
350
+ if verbose and infer_scope:
351
+ # Verbose mode with scope - keep verbose_with_scope examples
352
+ template = re.sub(r"<examples_no_scope>.*?</examples_no_scope>\n?", "", template, flags=re.DOTALL)
353
+ template = re.sub(r"<examples_with_scope>.*?</examples_with_scope>\n?", "", template, flags=re.DOTALL)
354
+ template = re.sub(
355
+ r"<examples_verbose_no_scope>.*?</examples_verbose_no_scope>\n?", "", template, flags=re.DOTALL
356
+ )
357
+ template = template.replace("<examples_verbose_with_scope>", "<examples>")
358
+ template = template.replace("</examples_verbose_with_scope>", "</examples>")
359
+ elif verbose:
360
+ # Verbose mode without scope - keep verbose_no_scope examples
361
+ template = re.sub(r"<examples_no_scope>.*?</examples_no_scope>\n?", "", template, flags=re.DOTALL)
362
+ template = re.sub(r"<examples_with_scope>.*?</examples_with_scope>\n?", "", template, flags=re.DOTALL)
363
+ template = re.sub(
364
+ r"<examples_verbose_with_scope>.*?</examples_verbose_with_scope>\n?", "", template, flags=re.DOTALL
365
+ )
366
+ template = template.replace("<examples_verbose_no_scope>", "<examples>")
367
+ template = template.replace("</examples_verbose_no_scope>", "</examples>")
368
+ elif infer_scope:
369
+ # With scope (inferred) - keep scope examples, remove all others
263
370
  template = re.sub(r"<examples_no_scope>.*?</examples_no_scope>\n?", "", template, flags=re.DOTALL)
371
+ template = re.sub(
372
+ r"<examples_verbose_no_scope>.*?</examples_verbose_no_scope>\n?", "", template, flags=re.DOTALL
373
+ )
374
+ template = re.sub(
375
+ r"<examples_verbose_with_scope>.*?</examples_verbose_with_scope>\n?", "", template, flags=re.DOTALL
376
+ )
264
377
  template = template.replace("<examples_with_scope>", "<examples>")
265
378
  template = template.replace("</examples_with_scope>", "</examples>")
266
379
  else:
267
- # No scope - keep no_scope examples, remove scope examples
380
+ # No scope - keep no_scope examples, remove all others
268
381
  template = re.sub(r"<examples_with_scope>.*?</examples_with_scope>\n?", "", template, flags=re.DOTALL)
382
+ template = re.sub(
383
+ r"<examples_verbose_no_scope>.*?</examples_verbose_no_scope>\n?", "", template, flags=re.DOTALL
384
+ )
385
+ template = re.sub(
386
+ r"<examples_verbose_with_scope>.*?</examples_verbose_with_scope>\n?", "", template, flags=re.DOTALL
387
+ )
269
388
  template = template.replace("<examples_no_scope>", "<examples>")
270
389
  template = template.replace("</examples_no_scope>", "</examples>")
271
390
 
gac/providers/__init__.py CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  from .anthropic import call_anthropic_api
4
4
  from .cerebras import call_cerebras_api
5
+ from .chutes import call_chutes_api
5
6
  from .gemini import call_gemini_api
6
7
  from .groq import call_groq_api
7
8
  from .lmstudio import call_lmstudio_api
@@ -15,6 +16,7 @@ from .zai import call_zai_api, call_zai_coding_api
15
16
  __all__ = [
16
17
  "call_anthropic_api",
17
18
  "call_cerebras_api",
19
+ "call_chutes_api",
18
20
  "call_gemini_api",
19
21
  "call_groq_api",
20
22
  "call_lmstudio_api",
@@ -0,0 +1,71 @@
1
+ """Chutes.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_chutes_api(model: str, messages: list[dict], temperature: float, max_tokens: int) -> str:
11
+ """Call Chutes.ai API directly.
12
+
13
+ Chutes.ai provides an OpenAI-compatible API for serverless, decentralized AI compute.
14
+
15
+ Args:
16
+ model: The model to use (e.g., 'deepseek-ai/DeepSeek-V3-0324')
17
+ messages: List of message dictionaries with 'role' and 'content' keys
18
+ temperature: Controls randomness (0.0-1.0)
19
+ max_tokens: Maximum tokens in the response
20
+
21
+ Returns:
22
+ The generated commit message
23
+
24
+ Raises:
25
+ AIError: If authentication fails, API errors occur, or response is invalid
26
+ """
27
+ api_key = os.getenv("CHUTES_API_KEY")
28
+ if not api_key:
29
+ raise AIError.authentication_error("CHUTES_API_KEY environment variable not set")
30
+
31
+ base_url = os.getenv("CHUTES_BASE_URL", "https://llm.chutes.ai")
32
+ url = f"{base_url}/v1/chat/completions"
33
+
34
+ headers = {
35
+ "Content-Type": "application/json",
36
+ "Authorization": f"Bearer {api_key}",
37
+ }
38
+
39
+ data = {
40
+ "model": model,
41
+ "messages": messages,
42
+ "temperature": temperature,
43
+ "max_tokens": max_tokens,
44
+ }
45
+
46
+ try:
47
+ response = httpx.post(url, headers=headers, json=data, timeout=120)
48
+ response.raise_for_status()
49
+ response_data = response.json()
50
+ content = response_data["choices"][0]["message"]["content"]
51
+ if content is None:
52
+ raise AIError.model_error("Chutes.ai API returned null content")
53
+ if content == "":
54
+ raise AIError.model_error("Chutes.ai API returned empty content")
55
+ return content
56
+ except httpx.HTTPStatusError as e:
57
+ status_code = e.response.status_code
58
+ error_text = e.response.text
59
+
60
+ if status_code == 429:
61
+ raise AIError.rate_limit_error(f"Chutes.ai API rate limit exceeded: {error_text}") from e
62
+ elif status_code in (502, 503):
63
+ raise AIError.connection_error(f"Chutes.ai API service unavailable: {status_code} - {error_text}") from e
64
+ else:
65
+ raise AIError.model_error(f"Chutes.ai API error: {status_code} - {error_text}") from e
66
+ except httpx.ConnectError as e:
67
+ raise AIError.connection_error(f"Chutes.ai API connection error: {str(e)}") from e
68
+ except httpx.TimeoutException as e:
69
+ raise AIError.timeout_error(f"Chutes.ai API request timed out: {str(e)}") from e
70
+ except Exception as e:
71
+ raise AIError.model_error(f"Error calling Chutes.ai API: {str(e)}") from e
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gac
3
- Version: 1.7.0
3
+ Version: 1.9.0
4
4
  Summary: AI-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
@@ -58,7 +58,7 @@ Description-Content-Type: text/markdown
58
58
 
59
59
  - **LLM-Powered Commit Messages:** Automatically generates clear, concise, and context-aware commit messages using large language models.
60
60
  - **Deep Contextual Analysis:** Understands your code by analyzing staged changes, repository structure, and recent commit history to provide highly relevant suggestions.
61
- - **Multi-Provider & Model Support:** Flexibly works with leading AI providers (Anthropic, Cerebras, Gemini, Groq, OpenAI, OpenRouter, Streamlake/Vanchin, Z.AI) and local providers (LM Studio, Ollama), easily configured through an interactive setup or environment variables.
61
+ - **Multi-Provider & Model Support:** Flexibly works with leading AI providers (Anthropic, Cerebras, Chutes.ai, Gemini, Groq, OpenAI, OpenRouter, Streamlake/Vanchin, Synthetic.new, & Z.AI) and local providers (LM Studio & Ollama), easily configured through an interactive setup or environment variables.
62
62
  - **Seamless Git Workflow:** Integrates smoothly into your existing Git routine as a simple drop-in replacement for `git commit`.
63
63
  - **Extensive Customization:** Tailor commit messages to your needs with a rich set of flags, including one-liners (`-o`), AI hints (`-h`), scope inference (`-s`), and specific model selection (`-m`).
64
64
  - **Streamlined Workflow Commands:** Boost your productivity with convenient options to stage all changes (`-a`), auto-confirm commits (`-y`), and push to your remote repository (`-p`) in a single step.
@@ -70,12 +70,6 @@ Description-Content-Type: text/markdown
70
70
 
71
71
  gac analyzes your staged changes to generate high-quality commit messages with the help of large language models. The tool uses a sophisticated prompt architecture that separates system instructions from user data, enabling better AI understanding and more consistent results.
72
72
 
73
- ### Technical Architecture
74
-
75
- - **Dual-Prompt System**: GAC uses a separated prompt architecture where system instructions (role definition, conventions, examples) are sent as system messages, while git data (diffs, status) are sent as user messages. This follows AI best practices for improved model performance.
76
- - **Smart Context Analysis**: The tool examines your repository structure, recent commit history, and README files to understand the broader context of your changes.
77
- - **Intelligent Diff Processing**: Large diffs are automatically preprocessed to focus on the most important changes while staying within token limits.
78
-
79
73
  ## How to Use
80
74
 
81
75
  ```sh
@@ -1,23 +1,24 @@
1
1
  gac/__init__.py,sha256=z9yGInqtycFIT3g1ca24r-A3699hKVaRqGUI79wsmMc,415
2
- gac/__version__.py,sha256=L6MpQn4MvY1iBqe5JKHqziZ_4QZ8oM9bg0eQA4ifKS0,66
3
- gac/ai.py,sha256=zl9-rmESKTHP2KNstS4sBqMGvGNC-KYcEsPPCpshaUE,3456
4
- gac/ai_utils.py,sha256=6iSz2q8MohNf2M3CNmF_9eNRDuACLB2kuh_Q9bRrvdE,7252
5
- gac/cli.py,sha256=nvJW_FmS0xA8Vs7x-JdIu4mW9Ze7IelYP8bnZYVFB4E,4885
6
- gac/config.py,sha256=N62phuLUyVj54eLDiDL6VN8-2_Zt6yB5zsnimFavU3I,1630
2
+ gac/__version__.py,sha256=zx56S8Cph899tDG2N3UNLWVQmQA7PjQIrC2aqkbXgww,66
3
+ gac/ai.py,sha256=T8o7ZenWDB94ILMvt5hp8mp_J6BbMJ3h5Y_0y2kRrX8,3512
4
+ gac/ai_utils.py,sha256=kz_ROoJjFZGPXxiyy225MuvMv9DikiqJBXOqKVlLVlc,7253
5
+ gac/cli.py,sha256=15Io35xSvoZ7_q9ADgely1un0tAprNuLRPdghGaIQTg,5058
6
+ gac/config.py,sha256=nVEnjCPmobspQl9NEcFLBYcIeUi2J9cui8CEzqIHnFY,1739
7
7
  gac/config_cli.py,sha256=v9nFHZO1RvK9fzHyuUS6SG-BCLHMsdOMDwWamBhVVh4,1608
8
- gac/constants.py,sha256=hGzmLGhVDB2KPIqwtl6tHMNuSwHj-2P1RK0cGm4pyNA,4962
8
+ gac/constants.py,sha256=R3oUwPLk_uWnBkg-J7Or-vomRr-iVKeLf1xljJeKclo,4988
9
9
  gac/diff_cli.py,sha256=wnVQ9OFGnM0d2Pj9WVjWbo0jxqIuRHVAwmb8wU9Pa3E,5676
10
10
  gac/errors.py,sha256=ysDIVRCd0YQVTOW3Q6YzdolxCdtkoQCAFf3_jrqbjUY,7916
11
11
  gac/git.py,sha256=_Co25XA1Nku03h50C_HiEf4ugEz6rK5j_IYi-rr5gco,8005
12
- gac/init_cli.py,sha256=_0FAdJCgrdV61bUVmQm5ykX5TlCsOUcyKKlRY6zav5A,4638
13
- gac/main.py,sha256=ot1DEbJHsZ0SzdZUuRXIm9pz1xbm4hxARzUjwytGdfc,15670
12
+ gac/init_cli.py,sha256=LEw26g-tb6GZdN3DaUuLx3OFvZPKPOIFKnqgDRe6Y8s,4677
13
+ gac/main.py,sha256=odWu_1Z0KVr--3duc4iFOE9ix0SGqykgzRDz-JY482c,15771
14
14
  gac/preprocess.py,sha256=krrLPHsccYMdn_YAtUrppBJIoRgevxGWusDwhE40LEo,15366
15
- gac/prompt.py,sha256=K6r9q2cAlyPu1fud6-jJsZ4zeweEo3yt6_WeYv8a_SQ,17087
15
+ gac/prompt.py,sha256=d_kBXmhf3bDVLyDj8J7AS7GBAxF2jlc8lXoHX3Dzi5k,24255
16
16
  gac/security.py,sha256=M1MZm6BLOeKl6rH_-UdXsSKol39FnA5fIP3YP394yZE,9898
17
17
  gac/utils.py,sha256=W3ladtmsH01MNLdckQYTzYrYbTGEdzCKI36he9C-y_E,3945
18
- gac/providers/__init__.py,sha256=MB0c9utV3grWKRX4mtPLRwxC138m2W_N4up12pZMZi0,817
18
+ gac/providers/__init__.py,sha256=ejIM5vvmfTp7vfJSNeQQPIEJusOkKTUZpUE7OeWBc9Y,876
19
19
  gac/providers/anthropic.py,sha256=VK5d1s1PmBNDwh_x7illQ2CIZIHNIYU28btVfizwQPs,2036
20
20
  gac/providers/cerebras.py,sha256=Ik8lhlsliGJVkgDgqlThfpra9tqbdYQZkaC4eNxRd9w,1648
21
+ gac/providers/chutes.py,sha256=cclJOLuGVIiiaF-9Bs1kH6SSOhEmduGB2zZ86KIaXKw,2617
21
22
  gac/providers/gemini.py,sha256=GZQz6Y9fd5-xk-U4pXn9bXLeBowxDXOYDyWyrtjFurM,2909
22
23
  gac/providers/groq.py,sha256=9v2fAjDa_iRNHFptiUBN8Vt7ZDKkW_JOmIBeYvycD1M,2806
23
24
  gac/providers/lmstudio.py,sha256=R82-f0tWdFfGQxLT6o3Q2tfvYguF7ESUg9DEUHNyrDk,2146
@@ -27,8 +28,8 @@ gac/providers/openrouter.py,sha256=H3ce8JcRUYq1I30lOjGESdX7jfoPkW3mKAYnc2aYfBw,2
27
28
  gac/providers/streamlake.py,sha256=KAA2ZnpuEI5imzvdWVWUhEBHSP0BMnprKXte6CbwBWY,2047
28
29
  gac/providers/synthetic.py,sha256=sRMIJTS9LpcXd9A7qp_ZjZxdqtTKRn9fl1W4YwJZP4c,1855
29
30
  gac/providers/zai.py,sha256=kywhhrCfPBu0rElZyb-iENxQxxpVGykvePuL4xrXlaU,2739
30
- gac-1.7.0.dist-info/METADATA,sha256=XOzizYkY74pU6HBlPUTWTmyE6ZMhRVTkTwqBsVugTNg,9847
31
- gac-1.7.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
32
- gac-1.7.0.dist-info/entry_points.txt,sha256=tdjN-XMmcWfL92swuRAjT62bFLOAwk9bTMRLGP5Z4aI,36
33
- gac-1.7.0.dist-info/licenses/LICENSE,sha256=vOab37NouL1PNs5BswnPayrMCqaN2sqLfMQfqPDrpZg,1103
34
- gac-1.7.0.dist-info/RECORD,,
31
+ gac-1.9.0.dist-info/METADATA,sha256=misyfIDv8wpdT0X51j2bwAIOpvcrEh5XZXtTyvqKmYM,9245
32
+ gac-1.9.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
33
+ gac-1.9.0.dist-info/entry_points.txt,sha256=tdjN-XMmcWfL92swuRAjT62bFLOAwk9bTMRLGP5Z4aI,36
34
+ gac-1.9.0.dist-info/licenses/LICENSE,sha256=vOab37NouL1PNs5BswnPayrMCqaN2sqLfMQfqPDrpZg,1103
35
+ gac-1.9.0.dist-info/RECORD,,
File without changes