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]