gac 3.10.3__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/__init__.py +15 -0
- gac/__version__.py +3 -0
- gac/ai.py +109 -0
- gac/ai_utils.py +246 -0
- gac/auth_cli.py +214 -0
- gac/cli.py +218 -0
- gac/commit_executor.py +62 -0
- gac/config.py +125 -0
- gac/config_cli.py +95 -0
- gac/constants.py +328 -0
- gac/diff_cli.py +159 -0
- gac/errors.py +231 -0
- gac/git.py +372 -0
- gac/git_state_validator.py +184 -0
- gac/grouped_commit_workflow.py +423 -0
- gac/init_cli.py +70 -0
- gac/interactive_mode.py +182 -0
- gac/language_cli.py +377 -0
- gac/main.py +476 -0
- gac/model_cli.py +430 -0
- gac/oauth/__init__.py +27 -0
- gac/oauth/claude_code.py +464 -0
- gac/oauth/qwen_oauth.py +327 -0
- gac/oauth/token_store.py +81 -0
- gac/preprocess.py +511 -0
- gac/prompt.py +878 -0
- gac/prompt_builder.py +88 -0
- gac/providers/README.md +437 -0
- gac/providers/__init__.py +80 -0
- gac/providers/anthropic.py +17 -0
- gac/providers/azure_openai.py +57 -0
- gac/providers/base.py +329 -0
- gac/providers/cerebras.py +15 -0
- gac/providers/chutes.py +25 -0
- gac/providers/claude_code.py +79 -0
- gac/providers/custom_anthropic.py +103 -0
- gac/providers/custom_openai.py +44 -0
- gac/providers/deepseek.py +15 -0
- gac/providers/error_handler.py +139 -0
- gac/providers/fireworks.py +15 -0
- gac/providers/gemini.py +90 -0
- gac/providers/groq.py +15 -0
- gac/providers/kimi_coding.py +27 -0
- gac/providers/lmstudio.py +80 -0
- gac/providers/minimax.py +15 -0
- gac/providers/mistral.py +15 -0
- gac/providers/moonshot.py +15 -0
- gac/providers/ollama.py +73 -0
- gac/providers/openai.py +32 -0
- gac/providers/openrouter.py +21 -0
- gac/providers/protocol.py +71 -0
- gac/providers/qwen.py +64 -0
- gac/providers/registry.py +58 -0
- gac/providers/replicate.py +156 -0
- gac/providers/streamlake.py +31 -0
- gac/providers/synthetic.py +40 -0
- gac/providers/together.py +15 -0
- gac/providers/zai.py +31 -0
- gac/py.typed +0 -0
- gac/security.py +293 -0
- gac/utils.py +401 -0
- gac/workflow_utils.py +217 -0
- gac-3.10.3.dist-info/METADATA +283 -0
- gac-3.10.3.dist-info/RECORD +67 -0
- gac-3.10.3.dist-info/WHEEL +4 -0
- gac-3.10.3.dist-info/entry_points.txt +2 -0
- gac-3.10.3.dist-info/licenses/LICENSE +16 -0
gac/main.py
ADDED
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Business logic for gac: orchestrates the commit workflow, including git state, formatting,
|
|
3
|
+
prompt building, AI generation, and commit/push operations. This module contains no CLI wiring.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import logging
|
|
7
|
+
import sys
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from rich.console import Console
|
|
11
|
+
|
|
12
|
+
from gac.ai import generate_commit_message
|
|
13
|
+
from gac.ai_utils import count_tokens
|
|
14
|
+
from gac.commit_executor import CommitExecutor
|
|
15
|
+
from gac.config import GACConfig, load_config
|
|
16
|
+
from gac.constants import EnvDefaults
|
|
17
|
+
from gac.errors import AIError, ConfigError, handle_error
|
|
18
|
+
from gac.git import run_lefthook_hooks, run_pre_commit_hooks
|
|
19
|
+
from gac.git_state_validator import GitState, GitStateValidator
|
|
20
|
+
from gac.grouped_commit_workflow import GroupedCommitWorkflow
|
|
21
|
+
from gac.interactive_mode import InteractiveMode
|
|
22
|
+
from gac.prompt import clean_commit_message
|
|
23
|
+
from gac.prompt_builder import PromptBuilder
|
|
24
|
+
|
|
25
|
+
logger = logging.getLogger(__name__)
|
|
26
|
+
|
|
27
|
+
config: GACConfig = load_config()
|
|
28
|
+
console = Console() # Initialize console globally to prevent undefined access
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _parse_model_identifier(model: str) -> tuple[str, str]:
|
|
32
|
+
"""Validate and split model identifier into provider and model name."""
|
|
33
|
+
normalized = model.strip()
|
|
34
|
+
if ":" not in normalized:
|
|
35
|
+
message = (
|
|
36
|
+
f"Invalid model format: '{model}'. Expected 'provider:model', e.g. 'openai:gpt-4o-mini'. "
|
|
37
|
+
"Use 'gac config set model <provider:model>' to update your configuration."
|
|
38
|
+
)
|
|
39
|
+
logger.error(message)
|
|
40
|
+
console.print(f"[red]{message}[/red]")
|
|
41
|
+
sys.exit(1)
|
|
42
|
+
|
|
43
|
+
provider, model_name = normalized.split(":", 1)
|
|
44
|
+
if not provider or not model_name:
|
|
45
|
+
message = (
|
|
46
|
+
f"Invalid model format: '{model}'. Both provider and model name are required "
|
|
47
|
+
"(example: 'anthropic:claude-haiku-4-5')."
|
|
48
|
+
)
|
|
49
|
+
logger.error(message)
|
|
50
|
+
console.print(f"[red]{message}[/red]")
|
|
51
|
+
sys.exit(1)
|
|
52
|
+
|
|
53
|
+
return provider, model_name
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _execute_single_commit_workflow(
|
|
57
|
+
*,
|
|
58
|
+
system_prompt: str,
|
|
59
|
+
user_prompt: str,
|
|
60
|
+
model: str,
|
|
61
|
+
temperature: float,
|
|
62
|
+
max_output_tokens: int,
|
|
63
|
+
max_retries: int,
|
|
64
|
+
require_confirmation: bool,
|
|
65
|
+
quiet: bool,
|
|
66
|
+
no_verify: bool,
|
|
67
|
+
dry_run: bool,
|
|
68
|
+
message_only: bool = False,
|
|
69
|
+
push: bool,
|
|
70
|
+
show_prompt: bool,
|
|
71
|
+
hook_timeout: int = 120,
|
|
72
|
+
interactive: bool = False,
|
|
73
|
+
commit_executor: CommitExecutor,
|
|
74
|
+
interactive_mode: InteractiveMode,
|
|
75
|
+
git_state: GitState,
|
|
76
|
+
hint: str,
|
|
77
|
+
) -> None:
|
|
78
|
+
"""Execute single commit workflow using extracted components."""
|
|
79
|
+
conversation_messages: list[dict[str, str]] = []
|
|
80
|
+
if system_prompt:
|
|
81
|
+
conversation_messages.append({"role": "system", "content": system_prompt})
|
|
82
|
+
conversation_messages.append({"role": "user", "content": user_prompt})
|
|
83
|
+
|
|
84
|
+
# Handle interactive questions if enabled
|
|
85
|
+
if interactive and not message_only:
|
|
86
|
+
interactive_mode.handle_interactive_flow(
|
|
87
|
+
model=model,
|
|
88
|
+
user_prompt=user_prompt,
|
|
89
|
+
git_state=git_state,
|
|
90
|
+
hint=hint,
|
|
91
|
+
conversation_messages=conversation_messages,
|
|
92
|
+
temperature=temperature,
|
|
93
|
+
max_tokens=max_output_tokens,
|
|
94
|
+
max_retries=max_retries,
|
|
95
|
+
quiet=quiet,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
# Generate commit message
|
|
99
|
+
first_iteration = True
|
|
100
|
+
while True:
|
|
101
|
+
prompt_tokens = count_tokens(conversation_messages, model)
|
|
102
|
+
if first_iteration:
|
|
103
|
+
warning_limit_val = config.get("warning_limit_tokens", EnvDefaults.WARNING_LIMIT_TOKENS)
|
|
104
|
+
if warning_limit_val is None:
|
|
105
|
+
raise ConfigError("warning_limit_tokens configuration missing")
|
|
106
|
+
warning_limit = int(warning_limit_val)
|
|
107
|
+
from gac.workflow_utils import check_token_warning
|
|
108
|
+
|
|
109
|
+
if not check_token_warning(prompt_tokens, warning_limit, require_confirmation):
|
|
110
|
+
sys.exit(0)
|
|
111
|
+
first_iteration = False
|
|
112
|
+
|
|
113
|
+
raw_commit_message = generate_commit_message(
|
|
114
|
+
model=model,
|
|
115
|
+
prompt=conversation_messages,
|
|
116
|
+
temperature=temperature,
|
|
117
|
+
max_tokens=max_output_tokens,
|
|
118
|
+
max_retries=max_retries,
|
|
119
|
+
quiet=quiet or message_only,
|
|
120
|
+
)
|
|
121
|
+
commit_message = clean_commit_message(raw_commit_message)
|
|
122
|
+
logger.info("Generated commit message:")
|
|
123
|
+
logger.info(commit_message)
|
|
124
|
+
conversation_messages.append({"role": "assistant", "content": commit_message})
|
|
125
|
+
|
|
126
|
+
if message_only:
|
|
127
|
+
# Output only the commit message without any formatting
|
|
128
|
+
print(commit_message)
|
|
129
|
+
sys.exit(0)
|
|
130
|
+
|
|
131
|
+
# Display commit message panel (always show, regardless of confirmation mode)
|
|
132
|
+
if not quiet:
|
|
133
|
+
from gac.workflow_utils import display_commit_message
|
|
134
|
+
|
|
135
|
+
display_commit_message(commit_message, prompt_tokens, model, quiet)
|
|
136
|
+
|
|
137
|
+
# Handle confirmation
|
|
138
|
+
if require_confirmation:
|
|
139
|
+
final_message, decision = interactive_mode.handle_single_commit_confirmation(
|
|
140
|
+
model=model,
|
|
141
|
+
commit_message=commit_message,
|
|
142
|
+
conversation_messages=conversation_messages,
|
|
143
|
+
quiet=quiet,
|
|
144
|
+
)
|
|
145
|
+
if decision == "yes":
|
|
146
|
+
commit_message = final_message
|
|
147
|
+
break
|
|
148
|
+
elif decision == "no":
|
|
149
|
+
console.print("[yellow]Commit aborted.[/yellow]")
|
|
150
|
+
sys.exit(0)
|
|
151
|
+
# decision == "regenerate": continue the loop
|
|
152
|
+
else:
|
|
153
|
+
break
|
|
154
|
+
|
|
155
|
+
# Execute the commit
|
|
156
|
+
commit_executor.create_commit(commit_message)
|
|
157
|
+
|
|
158
|
+
# Push if requested
|
|
159
|
+
if push:
|
|
160
|
+
commit_executor.push_to_remote()
|
|
161
|
+
|
|
162
|
+
if not quiet:
|
|
163
|
+
logger.info("Successfully committed changes with message:")
|
|
164
|
+
logger.info(commit_message)
|
|
165
|
+
if push:
|
|
166
|
+
logger.info("Changes pushed to remote.")
|
|
167
|
+
sys.exit(0)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def _handle_oauth_retry(
|
|
171
|
+
e: AIError,
|
|
172
|
+
prompts: Any,
|
|
173
|
+
model: str,
|
|
174
|
+
temperature: float,
|
|
175
|
+
max_output_tokens: int,
|
|
176
|
+
max_retries: int,
|
|
177
|
+
require_confirmation: bool,
|
|
178
|
+
quiet: bool,
|
|
179
|
+
no_verify: bool,
|
|
180
|
+
dry_run: bool,
|
|
181
|
+
message_only: bool,
|
|
182
|
+
push: bool,
|
|
183
|
+
show_prompt: bool,
|
|
184
|
+
hook_timeout: int,
|
|
185
|
+
interactive: bool,
|
|
186
|
+
commit_executor: CommitExecutor,
|
|
187
|
+
interactive_mode: InteractiveMode,
|
|
188
|
+
git_state: GitState,
|
|
189
|
+
hint: str,
|
|
190
|
+
) -> None:
|
|
191
|
+
"""Handle OAuth retry logic for expired tokens."""
|
|
192
|
+
logger.error(str(e))
|
|
193
|
+
|
|
194
|
+
# Check if this is a Claude Code OAuth token expiration
|
|
195
|
+
if (
|
|
196
|
+
e.error_type == "authentication"
|
|
197
|
+
and model.startswith("claude-code:")
|
|
198
|
+
and ("expired" in str(e).lower() or "oauth" in str(e).lower())
|
|
199
|
+
):
|
|
200
|
+
console.print("[yellow]⚠ Claude Code OAuth token has expired[/yellow]")
|
|
201
|
+
console.print("[cyan]🔐 Starting automatic re-authentication...[/cyan]")
|
|
202
|
+
|
|
203
|
+
try:
|
|
204
|
+
from gac.oauth.claude_code import authenticate_and_save
|
|
205
|
+
|
|
206
|
+
if authenticate_and_save(quiet=quiet):
|
|
207
|
+
console.print("[green]✓ Re-authentication successful![/green]")
|
|
208
|
+
console.print("[cyan]Retrying commit...[/cyan]\n")
|
|
209
|
+
|
|
210
|
+
# Retry the commit workflow
|
|
211
|
+
_execute_single_commit_workflow(
|
|
212
|
+
system_prompt=prompts.system_prompt,
|
|
213
|
+
user_prompt=prompts.user_prompt,
|
|
214
|
+
model=model,
|
|
215
|
+
temperature=temperature,
|
|
216
|
+
max_output_tokens=max_output_tokens,
|
|
217
|
+
max_retries=max_retries,
|
|
218
|
+
require_confirmation=require_confirmation,
|
|
219
|
+
quiet=quiet,
|
|
220
|
+
no_verify=no_verify,
|
|
221
|
+
dry_run=dry_run,
|
|
222
|
+
message_only=message_only,
|
|
223
|
+
push=push,
|
|
224
|
+
show_prompt=show_prompt,
|
|
225
|
+
hook_timeout=hook_timeout,
|
|
226
|
+
interactive=interactive,
|
|
227
|
+
commit_executor=commit_executor,
|
|
228
|
+
interactive_mode=interactive_mode,
|
|
229
|
+
git_state=git_state,
|
|
230
|
+
hint=hint,
|
|
231
|
+
)
|
|
232
|
+
else:
|
|
233
|
+
console.print("[red]Re-authentication failed.[/red]")
|
|
234
|
+
console.print("[yellow]Run 'gac model' to re-authenticate manually.[/yellow]")
|
|
235
|
+
sys.exit(1)
|
|
236
|
+
except (AIError, ConfigError, OSError) as auth_error:
|
|
237
|
+
console.print(f"[red]Re-authentication error: {auth_error}[/red]")
|
|
238
|
+
console.print("[yellow]Run 'gac model' to re-authenticate manually.[/yellow]")
|
|
239
|
+
sys.exit(1)
|
|
240
|
+
# Check if this is a Qwen OAuth token expiration
|
|
241
|
+
elif e.error_type == "authentication" and model.startswith("qwen:"):
|
|
242
|
+
console.print("[yellow]⚠ Qwen authentication failed[/yellow]")
|
|
243
|
+
console.print("[cyan]🔐 Starting automatic re-authentication...[/cyan]")
|
|
244
|
+
|
|
245
|
+
try:
|
|
246
|
+
from gac.oauth import QwenOAuthProvider, TokenStore
|
|
247
|
+
|
|
248
|
+
oauth_provider = QwenOAuthProvider(TokenStore())
|
|
249
|
+
oauth_provider.initiate_auth(open_browser=True)
|
|
250
|
+
console.print("[green]✓ Re-authentication successful![/green]")
|
|
251
|
+
console.print("[cyan]Retrying commit...[/cyan]\n")
|
|
252
|
+
|
|
253
|
+
# Retry the commit workflow
|
|
254
|
+
_execute_single_commit_workflow(
|
|
255
|
+
system_prompt=prompts.system_prompt,
|
|
256
|
+
user_prompt=prompts.user_prompt,
|
|
257
|
+
model=model,
|
|
258
|
+
temperature=temperature,
|
|
259
|
+
max_output_tokens=max_output_tokens,
|
|
260
|
+
max_retries=max_retries,
|
|
261
|
+
require_confirmation=require_confirmation,
|
|
262
|
+
quiet=quiet,
|
|
263
|
+
no_verify=no_verify,
|
|
264
|
+
dry_run=dry_run,
|
|
265
|
+
message_only=message_only,
|
|
266
|
+
push=push,
|
|
267
|
+
show_prompt=show_prompt,
|
|
268
|
+
hook_timeout=hook_timeout,
|
|
269
|
+
interactive=interactive,
|
|
270
|
+
commit_executor=commit_executor,
|
|
271
|
+
interactive_mode=interactive_mode,
|
|
272
|
+
git_state=git_state,
|
|
273
|
+
hint=hint,
|
|
274
|
+
)
|
|
275
|
+
except (AIError, ConfigError, OSError) as auth_error:
|
|
276
|
+
console.print(f"[red]Re-authentication error: {auth_error}[/red]")
|
|
277
|
+
console.print("[yellow]Run 'gac auth qwen login' to re-authenticate manually.[/yellow]")
|
|
278
|
+
sys.exit(1)
|
|
279
|
+
else:
|
|
280
|
+
# Non-Claude Code/Qwen error or non-auth error
|
|
281
|
+
console.print(f"[red]Failed to generate commit message: {str(e)}[/red]")
|
|
282
|
+
sys.exit(1)
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
def main(
|
|
286
|
+
stage_all: bool = False,
|
|
287
|
+
group: bool = False,
|
|
288
|
+
interactive: bool = False,
|
|
289
|
+
model: str | None = None,
|
|
290
|
+
hint: str = "",
|
|
291
|
+
one_liner: bool = False,
|
|
292
|
+
show_prompt: bool = False,
|
|
293
|
+
infer_scope: bool = False,
|
|
294
|
+
require_confirmation: bool = True,
|
|
295
|
+
push: bool = False,
|
|
296
|
+
quiet: bool = False,
|
|
297
|
+
dry_run: bool = False,
|
|
298
|
+
message_only: bool = False,
|
|
299
|
+
verbose: bool = False,
|
|
300
|
+
no_verify: bool = False,
|
|
301
|
+
skip_secret_scan: bool = False,
|
|
302
|
+
language: str | None = None,
|
|
303
|
+
hook_timeout: int = 120,
|
|
304
|
+
) -> None:
|
|
305
|
+
"""Main application logic for gac."""
|
|
306
|
+
# Initialize components
|
|
307
|
+
git_validator = GitStateValidator(config)
|
|
308
|
+
prompt_builder = PromptBuilder(config)
|
|
309
|
+
commit_executor = CommitExecutor(dry_run=dry_run, quiet=quiet, no_verify=no_verify, hook_timeout=hook_timeout)
|
|
310
|
+
interactive_mode = InteractiveMode(config)
|
|
311
|
+
grouped_workflow = GroupedCommitWorkflow(config)
|
|
312
|
+
|
|
313
|
+
# Validate and get model configuration
|
|
314
|
+
if model is None:
|
|
315
|
+
model_from_config = config["model"]
|
|
316
|
+
if model_from_config is None:
|
|
317
|
+
handle_error(
|
|
318
|
+
AIError.model_error(
|
|
319
|
+
"gac init hasn't been run yet. Please run 'gac init' to set up your configuration, then try again."
|
|
320
|
+
),
|
|
321
|
+
exit_program=True,
|
|
322
|
+
)
|
|
323
|
+
model = str(model_from_config)
|
|
324
|
+
|
|
325
|
+
temperature_val = config["temperature"]
|
|
326
|
+
if temperature_val is None:
|
|
327
|
+
raise ConfigError("temperature configuration missing")
|
|
328
|
+
temperature = float(temperature_val)
|
|
329
|
+
|
|
330
|
+
max_tokens_val = config["max_output_tokens"]
|
|
331
|
+
if max_tokens_val is None:
|
|
332
|
+
raise ConfigError("max_output_tokens configuration missing")
|
|
333
|
+
max_output_tokens = int(max_tokens_val)
|
|
334
|
+
|
|
335
|
+
max_retries_val = config["max_retries"]
|
|
336
|
+
if max_retries_val is None:
|
|
337
|
+
raise ConfigError("max_retries configuration missing")
|
|
338
|
+
max_retries = int(max_retries_val)
|
|
339
|
+
|
|
340
|
+
# Get git state and handle hooks
|
|
341
|
+
git_state = git_validator.get_git_state(
|
|
342
|
+
stage_all=stage_all,
|
|
343
|
+
dry_run=dry_run,
|
|
344
|
+
skip_secret_scan=skip_secret_scan,
|
|
345
|
+
quiet=quiet,
|
|
346
|
+
model=model,
|
|
347
|
+
hint=hint,
|
|
348
|
+
one_liner=one_liner,
|
|
349
|
+
infer_scope=infer_scope,
|
|
350
|
+
verbose=verbose,
|
|
351
|
+
language=language,
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
# Run pre-commit hooks
|
|
355
|
+
if not no_verify and not dry_run:
|
|
356
|
+
if not run_lefthook_hooks(hook_timeout):
|
|
357
|
+
console.print("[red]Lefthook hooks failed. Please fix the issues and try again.[/red]")
|
|
358
|
+
console.print("[yellow]You can use --no-verify to skip pre-commit and lefthook hooks.[/yellow]")
|
|
359
|
+
sys.exit(1)
|
|
360
|
+
|
|
361
|
+
if not run_pre_commit_hooks(hook_timeout):
|
|
362
|
+
console.print("[red]Pre-commit hooks failed. Please fix the issues and try again.[/red]")
|
|
363
|
+
console.print("[yellow]You can use --no-verify to skip pre-commit and lefthook hooks.[/yellow]")
|
|
364
|
+
sys.exit(1)
|
|
365
|
+
|
|
366
|
+
# Handle secret detection
|
|
367
|
+
if git_state.has_secrets:
|
|
368
|
+
should_continue = git_validator.handle_secret_detection(git_state.secrets, quiet)
|
|
369
|
+
if not should_continue:
|
|
370
|
+
# If secrets were removed, we need to refresh the git state
|
|
371
|
+
git_state = git_validator.get_git_state(
|
|
372
|
+
stage_all=False,
|
|
373
|
+
dry_run=dry_run,
|
|
374
|
+
skip_secret_scan=True, # Skip secret scan this time
|
|
375
|
+
quiet=quiet,
|
|
376
|
+
model=model,
|
|
377
|
+
hint=hint,
|
|
378
|
+
one_liner=one_liner,
|
|
379
|
+
infer_scope=infer_scope,
|
|
380
|
+
verbose=verbose,
|
|
381
|
+
language=language,
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
# Adjust max_output_tokens for grouped mode
|
|
385
|
+
if group:
|
|
386
|
+
num_files = len(git_state.staged_files)
|
|
387
|
+
multiplier = min(5, 2 + (num_files // 10))
|
|
388
|
+
max_output_tokens *= multiplier
|
|
389
|
+
logger.debug(f"Grouped mode: scaling max_output_tokens by {multiplier}x for {num_files} files")
|
|
390
|
+
|
|
391
|
+
# Build prompts
|
|
392
|
+
prompts = prompt_builder.build_prompts(
|
|
393
|
+
git_state=git_state,
|
|
394
|
+
group=group,
|
|
395
|
+
one_liner=one_liner,
|
|
396
|
+
hint=hint,
|
|
397
|
+
infer_scope=infer_scope,
|
|
398
|
+
verbose=verbose,
|
|
399
|
+
language=language,
|
|
400
|
+
)
|
|
401
|
+
|
|
402
|
+
# Display prompts if requested
|
|
403
|
+
if show_prompt:
|
|
404
|
+
prompt_builder.display_prompts(prompts.system_prompt, prompts.user_prompt)
|
|
405
|
+
|
|
406
|
+
try:
|
|
407
|
+
if group:
|
|
408
|
+
# Execute grouped workflow
|
|
409
|
+
grouped_workflow.execute_workflow(
|
|
410
|
+
system_prompt=prompts.system_prompt,
|
|
411
|
+
user_prompt=prompts.user_prompt,
|
|
412
|
+
model=model,
|
|
413
|
+
temperature=temperature,
|
|
414
|
+
max_output_tokens=max_output_tokens,
|
|
415
|
+
max_retries=max_retries,
|
|
416
|
+
require_confirmation=require_confirmation,
|
|
417
|
+
quiet=quiet,
|
|
418
|
+
no_verify=no_verify,
|
|
419
|
+
dry_run=dry_run,
|
|
420
|
+
push=push,
|
|
421
|
+
show_prompt=show_prompt,
|
|
422
|
+
interactive=interactive,
|
|
423
|
+
message_only=message_only,
|
|
424
|
+
hook_timeout=hook_timeout,
|
|
425
|
+
git_state=git_state,
|
|
426
|
+
hint=hint,
|
|
427
|
+
)
|
|
428
|
+
else:
|
|
429
|
+
# Execute single commit workflow
|
|
430
|
+
_execute_single_commit_workflow(
|
|
431
|
+
system_prompt=prompts.system_prompt,
|
|
432
|
+
user_prompt=prompts.user_prompt,
|
|
433
|
+
model=model,
|
|
434
|
+
temperature=temperature,
|
|
435
|
+
max_output_tokens=max_output_tokens,
|
|
436
|
+
max_retries=max_retries,
|
|
437
|
+
require_confirmation=require_confirmation,
|
|
438
|
+
quiet=quiet,
|
|
439
|
+
no_verify=no_verify,
|
|
440
|
+
dry_run=dry_run,
|
|
441
|
+
message_only=message_only,
|
|
442
|
+
push=push,
|
|
443
|
+
show_prompt=show_prompt,
|
|
444
|
+
hook_timeout=hook_timeout,
|
|
445
|
+
interactive=interactive,
|
|
446
|
+
commit_executor=commit_executor,
|
|
447
|
+
interactive_mode=interactive_mode,
|
|
448
|
+
git_state=git_state,
|
|
449
|
+
hint=hint,
|
|
450
|
+
)
|
|
451
|
+
except AIError as e:
|
|
452
|
+
_handle_oauth_retry(
|
|
453
|
+
e,
|
|
454
|
+
prompts,
|
|
455
|
+
model,
|
|
456
|
+
temperature,
|
|
457
|
+
max_output_tokens,
|
|
458
|
+
max_retries,
|
|
459
|
+
require_confirmation,
|
|
460
|
+
quiet,
|
|
461
|
+
no_verify,
|
|
462
|
+
dry_run,
|
|
463
|
+
message_only,
|
|
464
|
+
push,
|
|
465
|
+
show_prompt,
|
|
466
|
+
hook_timeout,
|
|
467
|
+
interactive,
|
|
468
|
+
commit_executor,
|
|
469
|
+
interactive_mode,
|
|
470
|
+
git_state,
|
|
471
|
+
hint,
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
if __name__ == "__main__":
|
|
476
|
+
main()
|