|
1 | 1 | from aicodebot.coder import Coder |
2 | 2 | from aicodebot.helpers import exec_and_get_output, logger |
3 | 3 | from aicodebot.lm import LanguageModelManager |
4 | | -from aicodebot.output import OurMarkdown, RichLiveCallbackHandler, get_console |
| 4 | +from aicodebot.output import OurMarkdown, get_console |
5 | 5 | from aicodebot.prompts import get_prompt |
6 | 6 | from pathlib import Path |
7 | | -from rich.live import Live |
| 7 | +from pydantic import BaseModel, Field |
| 8 | +from rich.panel import Panel |
8 | 9 | import click, os, shutil, subprocess, sys, tempfile |
9 | 10 |
|
10 | 11 |
|
| 12 | +class CommitMessage(BaseModel): |
| 13 | + # Important to put the detail first, as it improves the quality of the summary |
| 14 | + git_message_detail: str = Field(description="A detailed explanation of the changes made in this commit") |
| 15 | + git_message_summary: str = Field(description="A brief summary of the commit message") |
| 16 | + |
| 17 | + |
11 | 18 | @click.command() |
12 | 19 | @click.option("-t", "--response-token-size", type=int, default=250) |
13 | 20 | @click.option("-y", "--yes", is_flag=True, default=False, help="Don't ask for confirmation before committing.") |
@@ -84,26 +91,21 @@ def commit(response_token_size, yes, skip_pre_commit, files): # noqa: PLR0915 |
84 | 91 | lmm = LanguageModelManager() |
85 | 92 |
|
86 | 93 | console.print("Analyzing the differences and generating a commit message") |
87 | | - with Live(OurMarkdown(f"Talking to {lmm.model_name} via {lmm.provider}"), auto_refresh=True) as live: |
88 | | - llm = lmm.model_factory( |
89 | | - response_token_size=response_token_size, |
90 | | - streaming=True, |
91 | | - callbacks=[RichLiveCallbackHandler(live, console.bot_style)], |
92 | | - ) |
93 | | - chain = prompt | llm |
| 94 | + with console.status(f"Generating commit message with {lmm.model_name} via {lmm.provider}", spinner="dots"): |
| 95 | + llm = lmm.model_factory(response_token_size=response_token_size) |
| 96 | + structured_llm = llm.with_structured_output(CommitMessage) |
| 97 | + chain = prompt | structured_llm |
94 | 98 | response = chain.invoke({"diff_context": diff_context, "languages": languages}) |
95 | | - live.update(OurMarkdown(str(response))) |
| 99 | + |
| 100 | + console.print(Panel(OurMarkdown(f"{response.git_message_summary}\n\n{response.git_message_detail}"))) |
96 | 101 |
|
97 | 102 | commit_message_approved = not console.is_terminal or click.confirm( |
98 | 103 | "Would you like to use this generated commit message? Type 'n' to edit it.", default=True |
99 | 104 | ) |
100 | 105 |
|
101 | 106 | # Write the commit message to a temporary file |
102 | 107 | with tempfile.NamedTemporaryFile(mode="w", delete=False) as temp: |
103 | | - # For some reason the response often contains quotes around the summary, even if I tell it not to |
104 | | - # So we strip them here |
105 | | - commit_message = str(response.content).replace('"', "").strip() |
106 | | - |
| 108 | + commit_message = f"{response.git_message_summary}\n\n{response.git_message_detail}" |
107 | 109 | temp.write(commit_message) |
108 | 110 | temp_file_name = temp.name |
109 | 111 |
|
|
0 commit comments