gac 1.3.1__py3-none-any.whl → 1.4.1__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.3.1"
3
+ __version__ = "1.4.1"
gac/ai.py CHANGED
@@ -17,6 +17,7 @@ from gac.providers import (
17
17
  call_openai_api,
18
18
  call_openrouter_api,
19
19
  call_zai_api,
20
+ call_zai_coding_api,
20
21
  )
21
22
 
22
23
  logger = logging.getLogger(__name__)
@@ -69,6 +70,7 @@ def generate_commit_message(
69
70
  "ollama": call_ollama_api,
70
71
  "openrouter": call_openrouter_api,
71
72
  "zai": call_zai_api,
73
+ "zai-coding": call_zai_coding_api,
72
74
  }
73
75
 
74
76
  # Generate the commit message using centralized retry logic
gac/ai_utils.py CHANGED
@@ -93,7 +93,7 @@ def generate_with_retries(
93
93
  provider, model_name = model.split(":", 1)
94
94
 
95
95
  # Validate provider
96
- supported_providers = ["anthropic", "openai", "groq", "cerebras", "ollama", "openrouter", "zai"]
96
+ supported_providers = ["anthropic", "openai", "groq", "cerebras", "ollama", "openrouter", "zai", "zai-coding"]
97
97
  if provider not in supported_providers:
98
98
  raise AIError.model_error(f"Unsupported provider: {provider}. Supported providers: {supported_providers}")
99
99
 
gac/init_cli.py CHANGED
@@ -26,14 +26,15 @@ def init() -> None:
26
26
  ("Ollama", "gemma3"),
27
27
  ("OpenAI", "gpt-4.1-mini"),
28
28
  ("OpenRouter", "openrouter/auto"),
29
- ("Z.AI", "glm-4.6"),
29
+ ("Z.AI", "glm-4.5-air"),
30
+ ("Z.AI Coding", "glm-4.6"),
30
31
  ]
31
32
  provider_names = [p[0] for p in providers]
32
33
  provider = questionary.select("Select your provider:", choices=provider_names).ask()
33
34
  if not provider:
34
35
  click.echo("Provider selection cancelled. Exiting.")
35
36
  return
36
- provider_key = provider.lower().replace(".", "")
37
+ provider_key = provider.lower().replace(".", "").replace(" ", "-")
37
38
  model_suggestion = dict(providers)[provider]
38
39
  model = questionary.text(f"Enter the model (default: {model_suggestion}):", default=model_suggestion).ask()
39
40
  model_to_save = model.strip() if model.strip() else model_suggestion
@@ -42,17 +43,9 @@ def init() -> None:
42
43
 
43
44
  api_key = questionary.password("Enter your API key (input hidden, can be set later):").ask()
44
45
  if api_key:
45
- set_key(str(GAC_ENV_PATH), f"{provider_key.upper()}_API_KEY", api_key)
46
- click.echo(f"Set {provider_key.upper()}_API_KEY (hidden)")
47
-
48
- # Ask about ZAI coding plan if Z.AI provider was selected
49
- if provider_key == "zai":
50
- use_coding_api = questionary.confirm(
51
- "Are you using a Z.AI coding plan? (uses different API endpoint)",
52
- default=False,
53
- ).ask()
54
- if use_coding_api:
55
- set_key(str(GAC_ENV_PATH), "GAC_ZAI_USE_CODING_PLAN", "true")
56
- click.echo("Set GAC_ZAI_USE_CODING_PLAN=true")
46
+ # Z.AI and Z.AI Coding both use the same API key
47
+ api_key_name = "ZAI_API_KEY" if provider_key in ["zai", "zai-coding"] else f"{provider_key.upper()}_API_KEY"
48
+ set_key(str(GAC_ENV_PATH), api_key_name, api_key)
49
+ click.echo(f"Set {api_key_name} (hidden)")
57
50
 
58
51
  click.echo(f"\ngac environment setup complete. You can edit {GAC_ENV_PATH} to update values later.")
gac/providers/__init__.py CHANGED
@@ -6,7 +6,7 @@ from .groq import call_groq_api
6
6
  from .ollama import call_ollama_api
7
7
  from .openai import call_openai_api
8
8
  from .openrouter import call_openrouter_api
9
- from .zai import call_zai_api
9
+ from .zai import call_zai_api, call_zai_coding_api
10
10
 
11
11
  __all__ = [
12
12
  "call_anthropic_api",
@@ -16,4 +16,5 @@ __all__ = [
16
16
  "call_openai_api",
17
17
  "call_openrouter_api",
18
18
  "call_zai_api",
19
+ "call_zai_coding_api",
19
20
  ]
gac/providers/zai.py CHANGED
@@ -7,21 +7,15 @@ import httpx
7
7
  from gac.errors import AIError
8
8
 
9
9
 
10
- def call_zai_api(model: str, messages: list[dict], temperature: float, max_tokens: int) -> str:
11
- """Call Z.AI API directly."""
10
+ def _call_zai_api_impl(
11
+ url: str, api_name: str, model: str, messages: list[dict], temperature: float, max_tokens: int
12
+ ) -> str:
13
+ """Internal implementation for Z.AI API calls."""
12
14
  api_key = os.getenv("ZAI_API_KEY")
13
15
  if not api_key:
14
16
  raise AIError.model_error("ZAI_API_KEY not found in environment variables")
15
17
 
16
- # Support both regular and coding API endpoints
17
- use_coding_api = os.getenv("GAC_ZAI_USE_CODING_PLAN", "false").lower() in ("true", "1", "yes", "on")
18
- if use_coding_api:
19
- url = "https://api.z.ai/api/coding/paas/v4/chat/completions"
20
- else:
21
- url = "https://api.z.ai/api/paas/v4/chat/completions"
22
-
23
18
  headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
24
-
25
19
  data = {"model": model, "messages": messages, "temperature": temperature, "max_tokens": max_tokens}
26
20
 
27
21
  try:
@@ -35,15 +29,27 @@ def call_zai_api(model: str, messages: list[dict], temperature: float, max_token
35
29
  if "message" in choice and "content" in choice["message"]:
36
30
  content = choice["message"]["content"]
37
31
  if content is None:
38
- raise AIError.model_error("Z.AI API returned null content")
32
+ raise AIError.model_error(f"{api_name} API returned null content")
39
33
  if content == "":
40
- raise AIError.model_error("Z.AI API returned empty content")
34
+ raise AIError.model_error(f"{api_name} API returned empty content")
41
35
  return content
42
36
  else:
43
- raise AIError.model_error(f"Z.AI API response missing content: {response_data}")
37
+ raise AIError.model_error(f"{api_name} API response missing content: {response_data}")
44
38
  else:
45
- raise AIError.model_error(f"Z.AI API unexpected response structure: {response_data}")
39
+ raise AIError.model_error(f"{api_name} API unexpected response structure: {response_data}")
46
40
  except httpx.HTTPStatusError as e:
47
- raise AIError.model_error(f"Z.AI API error: {e.response.status_code} - {e.response.text}") from e
41
+ raise AIError.model_error(f"{api_name} API error: {e.response.status_code} - {e.response.text}") from e
48
42
  except Exception as e:
49
- raise AIError.model_error(f"Error calling Z.AI API: {str(e)}") from e
43
+ raise AIError.model_error(f"Error calling {api_name} API: {str(e)}") from e
44
+
45
+
46
+ def call_zai_api(model: str, messages: list[dict], temperature: float, max_tokens: int) -> str:
47
+ """Call Z.AI regular API directly."""
48
+ url = "https://api.z.ai/api/paas/v4/chat/completions"
49
+ return _call_zai_api_impl(url, "Z.AI", model, messages, temperature, max_tokens)
50
+
51
+
52
+ def call_zai_coding_api(model: str, messages: list[dict], temperature: float, max_tokens: int) -> str:
53
+ """Call Z.AI coding API directly."""
54
+ url = "https://api.z.ai/api/coding/paas/v4/chat/completions"
55
+ return _call_zai_api_impl(url, "Z.AI coding", model, messages, temperature, max_tokens)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gac
3
- Version: 1.3.1
3
+ Version: 1.4.1
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
@@ -1,7 +1,7 @@
1
1
  gac/__init__.py,sha256=HFWgSVNbTAFhgetCRWI1WrtyE7zC7IHvoBOrfDGUurM,989
2
- gac/__version__.py,sha256=HMucRcR7kcQZhE3vpMtxU0oneMqSyfDgbqk6dbmh7KA,66
3
- gac/ai.py,sha256=DRQ59U3-nf94qNCSqmOabRHEFaeV8gUU-4u_6iUyApo,3137
4
- gac/ai_utils.py,sha256=4h5KHZxUNGhKAi0OZoRd8JiCoA9oyFobWarsQrbJstw,7086
2
+ gac/__version__.py,sha256=ECklih1md5aHpXO55UJLzW7uO_jRivVyKU-saBV1Dis,66
3
+ gac/ai.py,sha256=RwA_4SuhUdl_ct1eZ-iiAY9UFWlncQ_OLGn3KC_CJbY,3205
4
+ gac/ai_utils.py,sha256=JXfAuDiIL9VBgAAoKFC_QGvD-mtLSybOlWDHMdKTGPo,7100
5
5
  gac/cli.py,sha256=nvz6l-wctfo3SMpC-zqtXyHMg8rtdzxw9cllbVMXJ0w,4872
6
6
  gac/config.py,sha256=N62phuLUyVj54eLDiDL6VN8-2_Zt6yB5zsnimFavU3I,1630
7
7
  gac/config_cli.py,sha256=v9nFHZO1RvK9fzHyuUS6SG-BCLHMsdOMDwWamBhVVh4,1608
@@ -9,22 +9,22 @@ gac/constants.py,sha256=hGzmLGhVDB2KPIqwtl6tHMNuSwHj-2P1RK0cGm4pyNA,4962
9
9
  gac/diff_cli.py,sha256=wnVQ9OFGnM0d2Pj9WVjWbo0jxqIuRHVAwmb8wU9Pa3E,5676
10
10
  gac/errors.py,sha256=ysDIVRCd0YQVTOW3Q6YzdolxCdtkoQCAFf3_jrqbjUY,7916
11
11
  gac/git.py,sha256=MS2m4fv8h4mau1djFG1aje9NXTmkGsjPO9w18LqNGX0,6031
12
- gac/init_cli.py,sha256=geuiAmfy8Pblyugt_nmb8lVJKtvGRTaoAfyMlcGz10E,2335
12
+ gac/init_cli.py,sha256=HAeoy7efjk3_imk7yIE2e1LunmnO-f8LvLEtv6rYuuI,2109
13
13
  gac/main.py,sha256=igiUnkdDG5akjcPHa2iCfqstziYifGmyGegP2k6g_c4,15273
14
14
  gac/preprocess.py,sha256=krrLPHsccYMdn_YAtUrppBJIoRgevxGWusDwhE40LEo,15366
15
15
  gac/prompt.py,sha256=_fv24XU3DZE_S72vcdUYnNkmy-_KXnr1Vlc-9okop7E,17263
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=FUtpU9oSxwv8-GQ7WBFHzV_cQMh3HjZ1vQfOPsZcRPs,506
18
+ gac/providers/__init__.py,sha256=pUKmPm8WMBbCRmOkhNbhIbS8fPL4ONvWmoKV35CflTc,554
19
19
  gac/providers/anthropic.py,sha256=esf6pq6nRdqD0mpKz_IQNXmXe5WnkoSA2b1isrrRB4o,1514
20
20
  gac/providers/cerebras.py,sha256=eE9lAjEzrATIo941vv97I2DSmpnXYBCJ9HkVIb-6Whg,1130
21
21
  gac/providers/groq.py,sha256=ILe1Qo8tK0mZ_b-fCPq25j76HfI9KcPnUi2Dginw0Ys,2529
22
22
  gac/providers/ollama.py,sha256=Bp94DvortQssDhekuNdJ7fKLeWpWASYXSssJNCuGszg,1383
23
23
  gac/providers/openai.py,sha256=RohHaQqttx0BTVzoJrmEA4eajxnFLN7zyfcFBE0aRyQ,1120
24
24
  gac/providers/openrouter.py,sha256=3PosNyAWgjsrSHiIOZ5PUp3KZbiK7NrGhw5SfPlQK6M,1828
25
- gac/providers/zai.py,sha256=iUDwO24Ydg_50KC9wgs1Y_Func8PEjDPpRhbOofAwNk,2092
26
- gac-1.3.1.dist-info/METADATA,sha256=0d2gi23LCCXkMTLa6RH0M5oitCpt6fWap9srMZhGWiU,9523
27
- gac-1.3.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
28
- gac-1.3.1.dist-info/entry_points.txt,sha256=tdjN-XMmcWfL92swuRAjT62bFLOAwk9bTMRLGP5Z4aI,36
29
- gac-1.3.1.dist-info/licenses/LICENSE,sha256=vOab37NouL1PNs5BswnPayrMCqaN2sqLfMQfqPDrpZg,1103
30
- gac-1.3.1.dist-info/RECORD,,
25
+ gac/providers/zai.py,sha256=J9SogoU-K-Gl3jgyWWJtVqqoUDXMUNodolf7Qrx3CBY,2450
26
+ gac-1.4.1.dist-info/METADATA,sha256=arS9XXGgS-yb9IjICH4biN4iLy2t3AuOnzCXNITgRqw,9523
27
+ gac-1.4.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
28
+ gac-1.4.1.dist-info/entry_points.txt,sha256=tdjN-XMmcWfL92swuRAjT62bFLOAwk9bTMRLGP5Z4aI,36
29
+ gac-1.4.1.dist-info/licenses/LICENSE,sha256=vOab37NouL1PNs5BswnPayrMCqaN2sqLfMQfqPDrpZg,1103
30
+ gac-1.4.1.dist-info/RECORD,,
File without changes