changelog_generator/changelog2/crew.py
2024-09-20 16:00:11 +02:00

153 lines
4 KiB
Python

import os
from typing import List
from config.config import parse_config
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.tasks.conditional_task import ConditionalTask
from crewai_tools import FileReadTool
from langchain_ollama import ChatOllama
from langchain_openai import ChatOpenAI
from pydantic import BaseModel
from tools.tools import (
get_categorized_commits_since_last_tag,
get_commits_since_last_tag,
get_redmine_issues,
)
config = parse_config()
os.environ["OPENAI_API_KEY"] = config["OPENAI_API_KEY"]
rag_tool = FileReadTool(file_path="./data/CodeOfConduct.md")
template_tool = FileReadTool(file_path="./data/template2.txt")
llmLocal = ChatOllama(model="gemma2", base_url="http://ollama:11434")
llmOpenAI = ChatOpenAI(
base_url="https://api.openai.com/v1/",
model_name="gpt-4o",
temperature=0.4,
)
@CrewBase
class ChangelogCrew:
"""Changelog writing crew"""
agents_config = "config/agents.yaml"
tasks_config = "config/tasks.yaml"
def __init__(self, git_task: bool = False, local: bool = True):
self.git_task = git_task
self.local = local
if self.local:
os.environ["OPENAI_API_BASE"] = "http://ollama:11434"
os.environ["OPENAI_MODEL_NAME"] = "gemma2"
else:
os.environ["OPENAI_API_BASE"] = "https://api.openai.com/v1/chat/completions"
@agent
def gitlog_analyst(self) -> Agent:
if self.local:
llm = llmLocal
else:
llm = llmOpenAI
return Agent(
config=self.agents_config["gitlog_analyst"],
tools=[get_categorized_commits_since_last_tag],
llm=llm,
max_iter=5,
verbose=False,
memory=False,
)
@agent
def redmine_analyst(self) -> Agent:
if self.local:
llm = llmLocal
else:
llm = llmOpenAI
return Agent(
config=self.agents_config["redmine_analyst"],
tools=[get_redmine_issues],
llm=llm,
max_iter=5,
verbose=False,
memory=False,
)
@agent
def writing_agent(self) -> Agent:
if self.local:
llm = llmLocal
else:
llm = llmOpenAI
with open("./data/template2.txt", "r") as template_file:
template_content = template_file.read()
return Agent(
config=self.agents_config["writing_agent"],
tools=[template_tool],
llm=llm,
max_iter=5,
verbose=False,
memory=False,
template=template_content,
)
@task
def redmine_analysis_task(self) -> Task:
return Task(
config=self.tasks_config["redmine_analysis_task"],
agent=self.redmine_analyst(),
)
@task
def gitlog_analysis_task(self) -> ConditionalTask:
return ConditionalTask(
config=self.tasks_config["gitlog_analysis_task"],
condition=lambda context: self.git_task,
agent=self.gitlog_analyst(),
)
@task
def writing_task(self) -> Task:
context = []
context.append(self.redmine_analysis_task())
if self.git_task:
context.append(self.gitlog_analysis_task())
return Task(
config=self.tasks_config["writing_task"],
agent=self.writing_agent(),
context=context,
)
@crew
def crew(self) -> Crew:
"""Creates the Changelog crew"""
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=False,
)
class GitCommit(BaseModel):
hash: str
author: str
date: str
message: str
category: str
class RedmineTicket(BaseModel):
id: int
subject: str
tracker: str
summary: str
class Changelog(BaseModel):
version: str
date: str
changes: List[str]
fixes: List[str]
new_features: List[str]