import os, logging DEBUG = os.environ.get('DEBUG') logging.basicConfig( format='[%(asctime)s] %(levelname)s %(module)s/%(funcName)s - %(message)s', level=logging.DEBUG if DEBUG else logging.INFO) import requests import subprocess LLAMA_URL = 'http://10.55.0.105:11434/api/generate' NOTES_DIR = '/home/tanner/notes-git/notes' #NOTES_DIR = '/home/tanner/' def controller_message(message): payload = dict(home=message) logging.info('Controller message: %s', message) r = requests.post('https://tbot.tannercollin.com/message', data=payload, timeout=10) if r.status_code == 200: return True else: logging.exception('Unable to communicate with controller! Message: ' + message) return False def llama(prompt): data = dict(model='llama3.1', prompt=prompt, stream=False, keep_alive=25) # don't keep in memory, interferes with Stable Diffusion try: r = requests.post(LLAMA_URL, json=data, timeout=20) r.raise_for_status() r = r.json() return r['response'] except BaseException as e: logging.error('Problem with llama: {} - {}'.format(e.__class__.__name__, str(e))) return False def git_diff(): result = subprocess.run(['git', 'diff', '--cached', '-U0'], stdout=subprocess.PIPE, cwd=NOTES_DIR) diff = result.stdout.decode() if diff: logging.info('Analyzing diff:\n%s', diff) return diff def git_add(): result = subprocess.run(['git', 'add', '-A'], stdout=subprocess.PIPE, cwd=NOTES_DIR) def git_commit(message): result = subprocess.run(['git', 'commit', '-m', message], stdout=subprocess.PIPE, cwd=NOTES_DIR) return result.stdout.decode() def generate_message(diff): prompt = '''You are an expert software engineer that generates concise, \ one-line Git commit messages based on the provided diffs. Review the provided context and diffs which are about to be committed to a git repo. Review the diffs carefully. Generate a one-line commit message for those changes. Ensure the commit message: - Is in the imperative mood (e.g., \"add feature\" not \"added feature\" or \"adding feature\"). - Does not exceed one line - DO NOT just say "Update notes", "Add new notes", "Refactor notes", "Make documentation updates". - Tersely summarize how each note changed. Reply only with the one-line commit message, without any additional text, explanations, or line breaks. Reply only with the one-line commit message, without any additional text, explanations, \ or line breaks. \n\n==============\n\nDiffs:\n\n''' prompt += diff logging.debug('Using prompt:\n%s', prompt) message = llama(prompt) if not message: logging.info(' Failed to generate') return False logging.info('Generated message: %s', message) if '.md' in message.lower(): logging.info(' Message contains .md extension, aborting') return False elif 'notes/' in message.lower(): logging.info(' Message contains notes directory, aborting') return False elif '\n' in message: logging.info(' Message contains new lines, aborting') return False return message def main(): git_add() # add so we can diff new files diff = git_diff() if not diff: logging.info('No diff, exiting.') exit(0) for _ in range(5): message = generate_message(diff) if message: break else: # for loop never broke msg = 'Unable to generate acceptable diff message.' controller_message(msg) logging.info(msg) message = 'Auto-commit, can\'t generate message' if DEBUG: logging.info('Running in debug, not actually committing.') else: git_commit(message) if __name__ == '__main__': main()