Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(llamabot)🚀: Enhance llamabot with new git reporting features #97

Merged
merged 5 commits into from
Sep 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 57 additions & 56 deletions docs/cli/git.md
Original file line number Diff line number Diff line change
@@ -1,73 +1,74 @@
# LlamaBot Git CLI Tutorial
---
intents:
- Provide a diataxis framework-style tutorial on how to use the LlamaBot Git CLI.
Covers comprehensively all commands and possible options.
- Show how to use each of the commands in the `llamabot git` CLI.
linked_files:
- llamabot/cli/git.py
- llamabot/prompt_library/git.py
---

In this tutorial, we will explore the Git subcommand for the LlamaBot CLI.
This command-line interface (CLI) provides a set of tools
to automate and enhance your Git workflow,
in particular, the ability to automatically generate commit messages.
## LlamaBot Git CLI Documentation

## Setup
Welcome to the LlamaBot Git CLI documentation. This guide provides a comprehensive tutorial on how to use the various commands available in the LlamaBot Git CLI, designed to enhance your Git experience with automated commit messages, release notes, and activity reports.

The `llamabot` prepare message hook requires that you have `llamabot >=0.0.77`.
You will also need an OpenAI API key
(unless you have Ollama for local LLMs or other API provider that LiteLLM supports).
Be sure to setup and configure LlamaBot
by executing the following two configuration commands
and following the instructions there.
### Getting Started

Before you begin, ensure that you have the LlamaBot CLI installed on your system. You will also need to have Git installed and be within a Git repository to use most of the commands.

### Commands Overview

The LlamaBot Git CLI includes several commands, each tailored for specific Git-related tasks:

#### 1. `hooks`

**Purpose:** Installs a commit message hook that automatically generates commit messages using a structured bot.

**Usage:**

```bash
llamabot configure api-key
llamabot git hooks
```

and
This command sets up a Git hook in your repository that triggers the LlamaBot to compose commit messages if none are provided during commits.

#### 2. `compose`

**Purpose:** Automatically generates a commit message based on the current Git diff.

**Usage:**

```bash
llamabot configure default-model
llamabot git compose
```

For the default model, we suggest using a GPT-4 variant.
It is generally of higher quality than GPT-3.5.
If you are concerned with cost,
the GPT-3.5-turbo variant with 16K context window
has anecdotally worked well.
Use this command to autogenerate a commit message which you can then review and edit as needed. This is particularly useful for ensuring commit messages are consistent and informative.

#### 3. `write_release_notes`

## Install the Commit Message Hook
**Purpose:** Generates release notes for the latest tags in your repository.

Once you have configured `llamabot`,
the next thing you need to do is
install the `prepare-msg-hook` within your `git` repository.
This is a `git` hook that allows you to run commands
after the `pre-commit` hooks are run
but before your editor of the commit message is opened.
To install the hook, simply run:
**Usage:**

```bash
llamabot git hooks
llamabot git write_release_notes
```

This command will create a markdown file in the specified directory containing release notes based on the commits between the last two tags.

#### 4. `report`

**Purpose:** Generates a report based on Git commit logs for a specified time frame.

**Usage:**

```bash
llamabot git report --hours 24
llamabot git report --start-date 2023-01-01 --end-date 2023-01-02
```

This command will check if the current directory is a Git repository root.
If it is not, it raises a `RuntimeError`.
If it is, it writes a script to the `prepare-commit-msg` file
in the `.git/hooks` directory
and changes the file's permissions to make it executable.

## Auto-Compose a Commit Message

The `llamabot git compose-commit` command autowrites a commit message based on the diff.
It first gets the diff using the `get_git_diff` function.
It then generates a commit message using the `commitbot`, which is a LlamaBot SimpleBot.
If any error occurs during this process,
it prints the error message and prompts the user to write their own commit message,
allowing for a graceful fallback to default behaviour.
This can be useful, for example, if you don't have an internet connection
and cannot connect to the OpenAI API,
but still need to commit code.

This command never needs to be explicitly called.
Rather, it is called behind-the-scenes within the `prepare-msg-hook`.

## Conclusion

The `llamabot git` CLI provides a set of tools
to automate and enhance your Git workflow.
It provides an automatic commit message writer based on your repo's `git diff`.
By using `llamabot git`, you can streamline your Git workflow and focus on writing code.
This command can be used to generate a detailed report of activities, highlighting key changes and features implemented within the specified period.

### Conclusion

The LlamaBot Git CLI is a powerful tool for automating and enhancing your Git workflow. By understanding and utilizing these commands, you can significantly improve the efficiency and consistency of your version control practices.
6 changes: 6 additions & 0 deletions llamabot/bot/ollama_model_names.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
qwen2.5-coder
solar-pro
nemotron-mini
qwen2.5
bespoke-minicheck
mistral-small
reader-lm
minicpm-v
deepseek-v2.5
Expand Down
87 changes: 77 additions & 10 deletions llamabot/cli/git.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
"""Git subcommand for LlamaBot CLI."""

from pathlib import Path
import os
from datetime import datetime, timedelta
from enum import Enum
from pathlib import Path
from typing import Optional

import git
import pyperclip
import typer
from pydantic import BaseModel, Field, model_validator
from pyprojroot import here
from typer import Typer, echo
from rich.console import Console

from llamabot import SimpleBot, prompt
from llamabot.bot.structuredbot import StructuredBot
from llamabot.code_manipulation import get_git_diff
from llamabot.prompt_library.git import (
compose_git_activity_report,
compose_release_notes,
)
from pydantic import BaseModel, Field, model_validator
from enum import Enum

gitapp = Typer()
gitapp = typer.Typer()


class CommitType(str, Enum):
Expand Down Expand Up @@ -213,7 +218,7 @@ def hooks(model_name: str = "gpt-4-turbo"):
"""
f.write(contents)
os.chmod(".git/hooks/prepare-commit-msg", 0o755)
echo("Commit message hook successfully installed! 🎉")
typer.echo("Commit message hook successfully installed! 🎉")


@gitapp.command()
Expand All @@ -227,8 +232,8 @@ def compose(model_name: str = "groq/llama-3.1-70b-versatile"):
with open(".git/COMMIT_EDITMSG", "w") as f:
f.write(response.format())
except Exception as e:
echo(f"Error encountered: {e}", err=True)
echo("Please write your own commit message.", err=True)
typer.echo(f"Error encountered: {e}", err=True)
typer.echo("Please write your own commit message.", err=True)


@gitapp.command()
Expand All @@ -252,14 +257,16 @@ def write_release_notes(release_notes_dir: Path = Path("./docs/releases")):
tag1, tag2 = tags[-2], tags[-1]
log_info = repo.git.log(f"{tag1.commit.hexsha}..{tag2.commit.hexsha}")

console = Console()
bot = SimpleBot(
"You are an expert software developer "
"who knows how to write excellent release notes based on git commit logs.",
model_name="mistral/mistral-medium",
api_key=os.environ["MISTRAL_API_KEY"],
stream_target="stdout",
stream_target="none",
)
notes = bot(compose_release_notes(log_info))
with console.status("[bold green]Generating release notes...", spinner="dots"):
notes = bot(compose_release_notes(log_info))

# Create release_notes_dir if it doesn't exist:
release_notes_dir.mkdir(parents=True, exist_ok=True)
Expand All @@ -269,3 +276,63 @@ def write_release_notes(release_notes_dir: Path = Path("./docs/releases")):
# Write release notes to the file
with open(release_notes_dir / f"{tag2.name}.md", "w+") as f:
f.write(trimmed_notes)


@gitapp.command()
def report(
hours: Optional[int] = typer.Option(None, help="The number of hours to report on."),
start_date: Optional[str] = typer.Option(
None, help="The start date to report on. Format: YYYY-MM-DD"
),
end_date: Optional[str] = typer.Option(
None, help="The end date to report on. Format: YYYY-MM-DD"
),
model_name: str = "gpt-4-turbo",
):
"""
Write a report on the work done based on git commit logs.

If hours is provided, it reports on the last specified hours.
If start_date and end_date are provided, it reports on that date range.
If neither is provided, it raises an error.

:param hours: The number of hours to report on.
:param start_date: The start date to report on.
:param end_date: The end date to report on.
:param model_name: The model name to use.
Consult LiteLLM's documentation for options.
"""
repo = git.Repo(here())

if hours is not None:
now = datetime.now()
time_ago = now - timedelta(hours=hours)
now_str = now.strftime("%Y-%m-%dT%H:%M:%S")
time_ago_str = time_ago.strftime("%Y-%m-%dT%H:%M:%S")
elif start_date and end_date:
time_ago_str = start_date
now_str = end_date
else:
raise ValueError(
"Either 'hours' or both 'start_date' and 'end_date' must be provided."
)

log_info = repo.git.log(f"--since={time_ago_str}", f"--until={now_str}")
bot = SimpleBot(
"You are an expert software developer who writes excellent reports based on git commit logs.",
model_name=model_name,
stream_target="none",
)

console = Console()
with console.status("[bold green]Generating report...", spinner="dots"):
report = bot(
compose_git_activity_report(
log_info, str(hours) or f"from {start_date} to {end_date}"
)
)

print(report.content)
# Copy report content to clipboard
pyperclip.copy(report.content)
typer.echo("Report copied to clipboard. Paste it wherever you need!")
53 changes: 52 additions & 1 deletion llamabot/prompt_library/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,58 @@ def write_commit_message(diff: str):


@prompt
def compose_release_notes(commit_log):
def compose_git_activity_report(log_info: str, hours: int) -> str:
"""Given the following git log information for the last {{ hours }} hours,
please write a concise report summarizing the work done during this period.
Highlight key changes, features, or fixes.
Use markdown formatting.

[[GIT LOG BEGIN]]
{{ log_info }}
[[GIT LOG END]]

Please format your report as follows:

1. Start with a brief summary of the overall work done in the specified time period.
2. Use the following sections, omitting any that are not applicable:
- New Features
- Bug Fixes
- Improvements
- Documentation
- Other Changes
3. Under each section, use bullet points to list the relevant changes.
4. For each bullet point, include:
- A concise description of the change
- The commit hash (first 7 characters)
- The author's name (if available)
5. If there are many similar changes, group them together and provide a summary.
6. Highlight any significant or breaking changes.
7. End with a brief conclusion or outlook, if appropriate.

Example format:

# Work Summary for the Last {{ hours }} Hours

## Overview
[Brief summary of overall work]

## New Features
- Implemented user authentication system (abc1234) (Jane Doe)
- Added export functionality for reports (def5678) (John Smith)

## Bug Fixes
- Fixed crash in data processing module (ghi9101) (Alice Johnson)

## Improvements
- Optimized database queries for faster performance (jkl1121) (Bob Wilson)

## Conclusion
[Brief conclusion or future outlook]
"""


@prompt
def compose_release_notes(commit_log: str) -> str:
"""Here is a commit log:

# noqa: DAR101
Expand Down
4 changes: 2 additions & 2 deletions pixi.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading