git-copilot-commit 0.2.2__tar.gz → 0.3.0__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.
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: git-copilot-commit
3
- Version: 0.2.2
3
+ Version: 0.3.0
4
4
  Summary: Automatically generate and commit changes using copilot
5
5
  Author-email: Dheepak Krishnamurthy <1813121+kdheepak@users.noreply.github.com>
6
6
  License-File: LICENSE
7
7
  Requires-Python: >=3.12
8
+ Requires-Dist: litellm>=1.75.4
8
9
  Requires-Dist: platformdirs>=4.0.0
9
- Requires-Dist: pycopilot>=0.1.7
10
10
  Requires-Dist: rich>=14.0.0
11
11
  Requires-Dist: typer>=0.16.0
12
12
  Description-Content-Type: text/markdown
@@ -8,10 +8,10 @@ authors = [
8
8
  ]
9
9
  requires-python = ">=3.12"
10
10
  dependencies = [
11
- "pycopilot>=0.1.7",
12
11
  "rich>=14.0.0",
13
12
  "typer>=0.16.0",
14
13
  "platformdirs>=4.0.0",
14
+ "litellm>=1.75.4",
15
15
  ]
16
16
 
17
17
  [project.scripts]
@@ -12,8 +12,7 @@ from rich.table import Table
12
12
  import rich
13
13
  from pathlib import Path
14
14
 
15
- from pycopilot.copilot import Copilot, CopilotAPIError # type: ignore
16
- from pycopilot.auth import Authentication
15
+ from litellm import completion
17
16
  from .git import GitRepository, GitError, NotAGitRepositoryError
18
17
  from .settings import Settings
19
18
  from .version import __version__
@@ -87,6 +86,29 @@ def load_system_prompt() -> str:
87
86
  raise typer.Exit(1)
88
87
 
89
88
 
89
+ def ask(prompt, model) -> str:
90
+ response = completion(
91
+ model=model,
92
+ messages=[
93
+ {"role": "system", "content": load_system_prompt()},
94
+ {"role": "user", "content": prompt},
95
+ ],
96
+ extra_headers={
97
+ "editor-version": "vscode/1.85.1",
98
+ "Copilot-Integration-Id": "vscode-chat",
99
+ },
100
+ )
101
+ text = response.choices[0].message.content
102
+ text = text.strip()
103
+ # Remove triple backticks if they wrap the entire text
104
+ if text.startswith("```") and text.endswith("```"):
105
+ text = text[3:-3].strip()
106
+ # Otherwise remove single backticks if they wrap the entire text
107
+ elif text.startswith("`") and text.endswith("`"):
108
+ text = text[1:-1].strip()
109
+ return text
110
+
111
+
90
112
  def generate_commit_message(
91
113
  repo: GitRepository, model: str | None = None, context: str = ""
92
114
  ) -> str:
@@ -99,9 +121,6 @@ def generate_commit_message(
99
121
  console.print("[red]No staged changes to commit.[/red]")
100
122
  raise typer.Exit()
101
123
 
102
- system_prompt = load_system_prompt()
103
- client = Copilot(system_prompt=system_prompt)
104
-
105
124
  prompt_parts = [
106
125
  "`git status`:\n",
107
126
  f"```\n{status.get_porcelain_output()}\n```",
@@ -116,11 +135,19 @@ def generate_commit_message(
116
135
 
117
136
  prompt = "\n".join(prompt_parts)
118
137
 
138
+ if model is None:
139
+ model = "github_copilot/gpt-4"
140
+
141
+ if not model.startswith("github_copilot/"):
142
+ model = f"github_copilot/{model}"
143
+
119
144
  try:
120
- client.reset()
121
- response = client.ask(prompt, model=model) if model else client.ask(prompt)
122
- return response.content
145
+ return ask(prompt, model=model)
123
146
  except Exception as _:
147
+ console.print(
148
+ "Prompt failed, falling back to simpler commit message generation."
149
+ )
150
+
124
151
  fallback_prompt_parts = [
125
152
  "`git status`:\n",
126
153
  f"```\n{status.get_porcelain_output()}\n```",
@@ -137,13 +164,7 @@ def generate_commit_message(
137
164
 
138
165
  fallback_prompt = "\n".join(fallback_prompt_parts)
139
166
 
140
- client.reset()
141
- response = (
142
- client.ask(fallback_prompt, model=model)
143
- if model
144
- else client.ask(fallback_prompt)
145
- )
146
- return response.content
167
+ return ask(fallback_prompt, model=model)
147
168
 
148
169
 
149
170
  @app.command()
@@ -221,9 +242,7 @@ def commit(
221
242
  ):
222
243
  commit_message = generate_commit_message(repo, model, context=context)
223
244
 
224
- console.print(
225
- "[yellow]Generated commit message based on [bold]`git diff --staged`[/] ...[/yellow]"
226
- )
245
+ console.print("[yellow]Generated commit message.[/yellow]")
227
246
 
228
247
  # Display commit message
229
248
  console.print(
@@ -275,47 +294,6 @@ def commit(
275
294
  console.print(f"[green]✓ Successfully committed: {commit_sha[:8]}[/green]")
276
295
 
277
296
 
278
- @app.command()
279
- def authenticate():
280
- """Autheticate with GitHub Copilot."""
281
- Authentication().auth()
282
-
283
-
284
- @app.command()
285
- def models():
286
- """List models available for chat in a table."""
287
- models = Copilot().models
288
-
289
- console = Console()
290
- table = Table(title="Available Models")
291
-
292
- table.add_column("ID", style="cyan", no_wrap=True)
293
- table.add_column("Name", style="magenta")
294
- table.add_column("Vendor", style="green")
295
- table.add_column("Version", style="yellow")
296
- table.add_column("Family", style="white")
297
- table.add_column("Max Tokens", style="white")
298
- table.add_column("Streaming", style="white")
299
-
300
- for model in models:
301
- capabilities = model.get("capabilities", {})
302
- family = capabilities.get("family", "N/A")
303
- max_tokens = capabilities.get("limits", {}).get("max_output_tokens", "N/A")
304
- streaming = capabilities.get("supports", {}).get("streaming", False)
305
-
306
- table.add_row(
307
- model.get("id", "N/A"),
308
- model.get("name", "N/A"),
309
- model.get("vendor", "N/A"),
310
- model.get("version", "N/A"),
311
- family,
312
- str(max_tokens),
313
- str(streaming),
314
- )
315
-
316
- console.print(table)
317
-
318
-
319
297
  @app.command()
320
298
  def config(
321
299
  set_default_model: str | None = typer.Option(
@@ -347,51 +325,5 @@ def config(
347
325
  console.print(f"Config file: [dim]{settings.config_file}[/dim]")
348
326
 
349
327
 
350
- @app.command()
351
- def echo(
352
- model: str | None = typer.Option(
353
- None, "--model", "-m", help="Model to use for generating commit message"
354
- ),
355
- ):
356
- """
357
- Generate commit message from stdin input (useful for pipes).
358
- """
359
- # Read from stdin
360
- input_text = sys.stdin.read()
361
-
362
- if not input_text.strip():
363
- console.print("[red]Error: No input provided via stdin[/red]")
364
- raise typer.Exit(1)
365
-
366
- # Load settings and use default model if none provided
367
- settings = Settings()
368
- if model is None:
369
- model = settings.default_model
370
-
371
- # Load system prompt and create client
372
- system_prompt = load_system_prompt()
373
- client = Copilot(system_prompt=system_prompt)
374
-
375
- # Generate commit message from the input
376
- prompt = f"""
377
- `git diff --staged`:
378
-
379
- ```
380
- {input_text.strip()}
381
- ```
382
-
383
- Generate a conventional commit message based on the input above:"""
384
-
385
- try:
386
- response = client.ask(prompt, model=model) if model else client.ask(prompt)
387
- # Print the commit message directly to stdout (no rich formatting for pipes)
388
- import builtins
389
-
390
- builtins.print(response.content)
391
- except CopilotAPIError as e:
392
- console.print(f"[red]Error generating commit message: {e}[/red]")
393
- raise typer.Exit(1)
394
-
395
-
396
328
  if __name__ == "__main__":
397
329
  app()
@@ -7,7 +7,7 @@ You are a Git commit message assistant trained to write a single clear, structur
7
7
 
8
8
  Your task is to generate a **single-line commit message** in the [Conventional Commits](https://www.conventionalcommits.org/) format based on both inputs. If no context is provided, rely **only** on the diff.
9
9
 
10
- ## Output Format
10
+ ## Output Format
11
11
 
12
12
  ```
13
13
  <type>(<optional scope>): <description>
@@ -17,7 +17,7 @@ Your task is to generate a **single-line commit message** in the [Conventional C
17
17
  - Do not wrap the message in backticks or code blocks.
18
18
  - Keep the title line ≤72 characters.
19
19
 
20
- ## Valid Types
20
+ ## Valid Types
21
21
 
22
22
  - `feat`: New feature
23
23
  - `fix`: Bug fix
@@ -29,34 +29,35 @@ Your task is to generate a **single-line commit message** in the [Conventional C
29
29
  - `chore`: Maintenance tasks (e.g., CI/CD, dependencies)
30
30
  - `revert`: Revert of a previous commit
31
31
 
32
- ## Scope (Optional)
32
+ ## Scope (Optional)
33
33
 
34
34
  - Lowercase, single word or hyphenated phrase
35
35
  - Represents the affected area, module, or file
36
36
  - Use broad area if multiple related files are affected
37
37
 
38
- ## Subject Line
38
+ ## Subject Line
39
39
 
40
40
  - Use imperative mood ("remove" not "removed")
41
41
  - Focus on **what** changed, not why or how
42
42
  - Be concise and specific
43
43
  - Use abbreviations (e.g., "config" not "configuration")
44
44
 
45
- ## Using User-Provided Context
45
+ ## Using User-Provided Context
46
46
 
47
47
  - If additional context is provided by the user, you may **incorporate it** to clarify purpose (e.g., "remove duplicate entry").
48
48
  - If no such context is provided, **do not speculate or infer**.
49
49
  - Only use terms like "unused", "duplicate", or "deprecated" when explicitly stated by the user or clearly shown in the diff.
50
50
 
51
- ## Do Not
51
+ ## Do Not
52
52
 
53
53
  - Do not use vague phrases ("made changes", "updated code")
54
54
  - Do not use past tense ("added", "removed")
55
55
  - Do not explain implementation or reasoning ("to fix bug", "because of issue")
56
56
  - Do not guess purpose based on intuition or incomplete file context
57
+ - Do not wrap the response in single backticks.
57
58
 
58
59
  ---
59
60
 
60
61
  Given a Git diff, a list of modified files, or a short description of changes, generate a single, short, clear and structured Conventional Commit message following the above rules. If multiple changes are detected, prioritize the most important changes in a single commit message. Do not add any body or footer. You can only give one reply for each conversation.
61
62
 
62
- Do not wrap the response in triple backticks or single backticks. Return the commit message as the output without any additional text, explanations, or formatting markers.
63
+ Return the commit message as the output without any additional text, explanations, or formatting markers.