matrix-bot: Working openai integration

This commit is contained in:
Qubasa
2024-07-02 15:28:48 +02:00
parent 7a888fbbae
commit f6e77f3c1b
7 changed files with 334 additions and 26 deletions

View File

@@ -0,0 +1,148 @@
import asyncio
import datetime
import logging
import subprocess
from pathlib import Path
import json
import aiohttp
from nio import (
AsyncClient,
JoinResponse,
)
from matrix_bot.gitea import (
GiteaData,
)
from .matrix import MatrixData, send_message
from .openai import create_jsonl_file, upload_and_process_file
log = logging.getLogger(__name__)
def write_file_with_date_prefix(content: str, directory: Path, suffix: str) -> Path:
"""
Write content to a file with the current date as filename prefix.
:param content: The content to write to the file.
:param directory: The directory where the file will be saved.
:return: The path to the created file.
"""
# Ensure the directory exists
directory.mkdir(parents=True, exist_ok=True)
# Get the current date
current_date = datetime.datetime.now().strftime("%Y-%m-%d")
# Create the filename
filename = f"{current_date}_{suffix}.txt"
file_path = directory / filename
# Write the content to the file
with open(file_path, "w") as file:
file.write(content)
return file_path
async def git_pull(repo_path: Path) -> None:
cmd = ["git", "pull"]
process = await asyncio.create_subprocess_exec(
*cmd,
cwd=str(repo_path),
)
await process.wait()
async def git_log(repo_path: str) -> str:
cmd = [
"git",
"log",
"--since=1 week ago",
"--pretty=format:%h - %an, %ar : %s",
"--stat",
"--patch",
]
process = await asyncio.create_subprocess_exec(
*cmd,
cwd=repo_path,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await process.communicate()
if process.returncode != 0:
raise Exception(
f"Command '{' '.join(cmd)}' failed with exit code {process.returncode}"
)
return stdout.decode()
async def changelog_bot(
client: AsyncClient,
http: aiohttp.ClientSession,
matrix: MatrixData,
gitea: GiteaData,
data_dir: Path,
) -> None:
# If you made a new room and haven't joined as that user, you can use
room: JoinResponse = await client.join(matrix.room)
if not room.transport_response.ok:
log.error("This can happen if the room doesn't exist or the bot isn't invited")
raise Exception(f"Failed to join room {room}")
repo_path = data_dir / gitea.repo
if not repo_path.exists():
cmd = [
"git",
"clone",
f"{gitea.url}/{gitea.owner}/{gitea.repo}.git",
gitea.repo,
]
subprocess.run(cmd, cwd=data_dir, check=True)
# git pull
await git_pull(repo_path)
# git log
diff = await git_log(repo_path)
system_prompt = """
Generate a concise changelog for the past week,
focusing only on new features and summarizing bug fixes into a single entry.
Ensure the following:
- Deduplicate entries
- Discard uninteresting changes
- Keep the summary as brief as possible
- Use present tense
The changelog is as follows:
---
"""
jsonl_path = data_dir / "changelog.jsonl"
# Step 1: Create the JSONL file
await create_jsonl_file(
user_prompt=diff, system_prompt=system_prompt, jsonl_path=jsonl_path
)
# Step 2: Upload the JSONL file and process it
results = await upload_and_process_file(session=http, jsonl_path=jsonl_path)
result_file = write_file_with_date_prefix(json.dumps(results, indent=4), data_dir, "result")
log.info(f"LLM result written to: {result_file}")
# Join all changelogs with a separator (e.g., two newlines)
all_changelogs = []
for result in results:
choices = result["response"]["body"]["choices"]
changelog = "\n".join(choice["message"]["content"] for choice in choices)
all_changelogs.append(changelog)
full_changelog = "\n\n".join(all_changelogs)
await send_message(client, room, full_changelog)