gac 1.12.0__tar.gz → 1.12.1__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.
- {gac-1.12.0 → gac-1.12.1}/PKG-INFO +1 -1
- {gac-1.12.0 → gac-1.12.1}/src/gac/__version__.py +1 -1
- {gac-1.12.0 → gac-1.12.1}/src/gac/providers/gemini.py +35 -22
- {gac-1.12.0 → gac-1.12.1}/.gitignore +0 -0
- {gac-1.12.0 → gac-1.12.1}/LICENSE +0 -0
- {gac-1.12.0 → gac-1.12.1}/README.md +0 -0
- {gac-1.12.0 → gac-1.12.1}/pyproject.toml +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/__init__.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/ai.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/ai_utils.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/cli.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/config.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/config_cli.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/constants.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/diff_cli.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/errors.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/git.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/init_cli.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/main.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/preprocess.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/prompt.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/providers/__init__.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/providers/anthropic.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/providers/cerebras.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/providers/chutes.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/providers/deepseek.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/providers/fireworks.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/providers/groq.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/providers/lmstudio.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/providers/minimax.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/providers/ollama.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/providers/openai.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/providers/openrouter.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/providers/streamlake.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/providers/synthetic.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/providers/together.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/providers/zai.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/security.py +0 -0
- {gac-1.12.0 → gac-1.12.1}/src/gac/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gac
|
|
3
|
-
Version: 1.12.
|
|
3
|
+
Version: 1.12.1
|
|
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
|
|
@@ -16,32 +16,37 @@ def call_gemini_api(model: str, messages: list[dict[str, Any]], temperature: flo
|
|
|
16
16
|
|
|
17
17
|
url = f"https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent"
|
|
18
18
|
|
|
19
|
-
# Build
|
|
20
|
-
contents = []
|
|
19
|
+
# Build Gemini request payload, converting roles to supported values.
|
|
20
|
+
contents: list[dict[str, Any]] = []
|
|
21
|
+
system_instruction_parts: list[dict[str, str]] = []
|
|
21
22
|
|
|
22
|
-
# Add system instruction as first content with role "system" (2025 format)
|
|
23
23
|
for msg in messages:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
role = msg.get("role")
|
|
25
|
+
content_value = msg.get("content")
|
|
26
|
+
content = "" if content_value is None else str(content_value)
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
)
|
|
28
|
+
if role == "system":
|
|
29
|
+
if content.strip():
|
|
30
|
+
system_instruction_parts.append({"text": content})
|
|
31
|
+
continue
|
|
32
|
+
|
|
33
|
+
if role == "assistant":
|
|
34
|
+
gemini_role = "model"
|
|
35
|
+
elif role == "user":
|
|
36
|
+
gemini_role = "user"
|
|
37
|
+
else:
|
|
38
|
+
raise AIError.model_error(f"Unsupported message role for Gemini API: {role}")
|
|
39
|
+
|
|
40
|
+
contents.append({"role": gemini_role, "parts": [{"text": content}]})
|
|
39
41
|
|
|
40
42
|
payload: dict[str, Any] = {
|
|
41
43
|
"contents": contents,
|
|
42
44
|
"generationConfig": {"temperature": temperature, "maxOutputTokens": max_tokens},
|
|
43
45
|
}
|
|
44
46
|
|
|
47
|
+
if system_instruction_parts:
|
|
48
|
+
payload["systemInstruction"] = {"role": "system", "parts": system_instruction_parts}
|
|
49
|
+
|
|
45
50
|
headers = {"x-goog-api-key": api_key, "Content-Type": "application/json"}
|
|
46
51
|
|
|
47
52
|
try:
|
|
@@ -50,18 +55,26 @@ def call_gemini_api(model: str, messages: list[dict[str, Any]], temperature: flo
|
|
|
50
55
|
response_data = response.json()
|
|
51
56
|
|
|
52
57
|
# Check for candidates and proper response structure
|
|
53
|
-
|
|
58
|
+
candidates = response_data.get("candidates")
|
|
59
|
+
if not candidates:
|
|
54
60
|
raise AIError.model_error("Gemini API response missing candidates")
|
|
55
61
|
|
|
56
|
-
candidate =
|
|
62
|
+
candidate = candidates[0]
|
|
57
63
|
if "content" not in candidate or "parts" not in candidate["content"] or not candidate["content"]["parts"]:
|
|
58
64
|
raise AIError.model_error("Gemini API response has invalid content structure")
|
|
59
65
|
|
|
60
|
-
|
|
61
|
-
|
|
66
|
+
parts = candidate["content"]["parts"]
|
|
67
|
+
content_text: str | None = None
|
|
68
|
+
for part in parts:
|
|
69
|
+
if isinstance(part, dict):
|
|
70
|
+
part_text = part.get("text")
|
|
71
|
+
if isinstance(part_text, str) and part_text:
|
|
72
|
+
content_text = part_text
|
|
73
|
+
break
|
|
74
|
+
if content_text is None:
|
|
62
75
|
raise AIError.model_error("Gemini API response missing text content")
|
|
63
76
|
|
|
64
|
-
return
|
|
77
|
+
return content_text
|
|
65
78
|
except AIError:
|
|
66
79
|
raise
|
|
67
80
|
except httpx.HTTPStatusError as 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
|
|
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
|