Skip to content

Commit

Permalink
Good commit messages (meltylabs#100)
Browse files Browse the repository at this point in the history
* good commit messages

* [by melty] Refactor authentication logic and add token expiration handling

* [by melty] Refactor user authentication flow

* update prompt

* [by melty] empty commit

* [by melty] Empty commit

* fixed up diff generation

* [by melty] Empty commit

* [by melty] empty commit

* [via melty] Improve Claude conversation stream handling and diff preview

* [by melty] empty commit

* [by melty] Add Dog class with bark method and string representation

* [via melty] Remove dog.py

* [via melty] Add forceRemoveHumanJoules function and use it in Task

* [via melty] Fix force remove human joules logic

* [by melty] empty commit

* [by melty] Add main function to src/cat.py

* [via melty] Remove unused files

* [by melty] empty commit

* show message when we force-remove joules

* remove junk
  • Loading branch information
jacksondc authored Aug 17, 2024
1 parent 79ae847 commit 1223923
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 320 deletions.
2 changes: 0 additions & 2 deletions hi.txt

This file was deleted.

3 changes: 1 addition & 2 deletions src/assistants/coder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ export class Coder extends BaseAssistant {
rawOutput: response,
contextPaths: contextPaths,
assistantType: "coder",
filePathsChanged: [],
});
return conversations.addJoule(prevConversation, newJoule);
}
Expand All @@ -142,7 +141,7 @@ export class Coder extends BaseAssistant {
const changeSet = await this.applyChanges(gitRepo, searchReplaceList);
const newCommit = await changeSets.commitChangeSet(changeSet, gitRepo);
const diffInfo = {
diffPreview: await utils.getUdiffPreview(gitRepo, newCommit),
diffPreview: await utils.getUdiffPreviewFromCommit(gitRepo, newCommit),
filePathsChanged: Array.from(Object.keys(changeSet.filesChanged)),
};
const newJoule = joules.createJouleBotWithChanges(
Expand Down
16 changes: 13 additions & 3 deletions src/backend/changeSets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ import path from "path";
import * as files from "./meltyFiles";
import { generateCommitMessage } from "./commitMessageGenerator";

export async function getChangeSet(gitRepo: GitRepo, commit: string) {
const repository = gitRepo.repository;
await repository.status();

const changeSet = await meltyFiles.getChangeSet(
gitRepo,
commit,
parentCommit
);
return changeSet;
}

/**
* Commits changes in a changeset
* @param changeSet The change set to apply
Expand Down Expand Up @@ -40,10 +52,8 @@ export async function commitChangeSet(changeSet: ChangeSet, gitRepo: GitRepo) {
)
);

const changedFiles = Object.keys(changeSet.filesChanged);
const commitMessage = await generateCommitMessage(
changedFiles,
gitRepo.rootPath
utils.getDiffPreviewFromChangeSet(changeSet)
);
await repository.commit(`[by melty] ${commitMessage}`, {
empty: true,
Expand Down
10 changes: 10 additions & 0 deletions src/backend/claudeAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ export async function streamClaude(
processPartial: (text: string) => void,
model: Models = Models.Claude35Sonnet
): Promise<string> {
if (claudeConversation.messages.length === 0) {
throw new Error("No messages to stream");
}
if (
claudeConversation.messages[claudeConversation.messages.length - 1].role ===
"assistant"
) {
throw new Error("Last message is an assistant message");
}

const config = vscode.workspace.getConfiguration("melty");
const apiKey = config.get<string>("anthropicApiKey");

Expand Down
40 changes: 20 additions & 20 deletions src/backend/commitMessageGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import * as fs from "fs";
import * as path from "path";
import { Anthropic } from "@anthropic-ai/sdk";
import * as vscode from "vscode";
import * as files from "./meltyFiles";
import { GitRepo, ChangeSet } from "../types";

export async function generateCommitMessage(
changedFiles: string[],
rootPath: string
udiffPreview: string
): Promise<string> {
const config = vscode.workspace.getConfiguration("melty");
const apiKey = config.get<string>("anthropicApiKey");
Expand All @@ -20,37 +21,36 @@ export async function generateCommitMessage(
apiKey: apiKey,
});

// const fileContents = changedFiles
// .map((file) => {
// const filePath = path.join(rootPath, file);
// return `${file}:\n${fs.readFileSync(filePath, "utf-8")}`;
// })
// .join("\n\n");

const fileContents = "";

const prompt = `You are an expert software engineer.
Review the provided context and diffs which are about to be committed to a git repo.
Review the diffs carefully.
Review the provided diff which is about to be committed to a git repo.
Review the diff carefully.
Generate a commit message for those changes.
The commit message MUST use the imperative tense.
The commit message should be structured as follows: <type>: <description>
Use these for <type>: fix, feat, build, chore, ci, docs, style, refactor, perf, test
Reply with JUST the commit message, without quotes, comments, questions, etc!
If the diff contains no files changed, you can just reply with "empty commit".
Example:
<CommitMessage>Add logging to foo/bar/baz.py</CommitMessage>
Changes to be committed:
Here is the diff:
${fileContents}`;
<Diff>
${udiffPreview}
</Diff>`;

try {
const response = await anthropic.messages.create({
model: "claude-3-sonnet-20240229",
max_tokens: 100,
temperature: 0.7,
messages: [{ role: "user", content: prompt }],
messages: [
{ role: "user", content: prompt },
{ role: "assistant", content: "<CommitMessage>" },
],
});

const commitMessage = response.content[0].text.trim();
const responseText = response.content[0].text.trim();
const commitMessage = responseText.split("</CommitMessage>")[0].trim();
return commitMessage;
} catch (error) {
console.error("Error generating commit message:", error);
Expand Down
29 changes: 19 additions & 10 deletions src/backend/conversations.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Joule, Conversation } from "../types";
import * as joules from "./joules";
import * as vscode from "vscode";

export function create(): Conversation {
return { joules: [] };
Expand All @@ -12,17 +12,26 @@ export function addJoule(
return { joules: [...conversation.joules, joule] };
}

export function respondHuman(
conversation: Conversation,
message: string,
commit: string | null
): Conversation {
const newJoule = joules.createJouleHuman(message, commit);
return addJoule(conversation, newJoule);
}

export function lastJoule(conversation: Conversation): Joule | undefined {
return conversation.joules.length
? conversation.joules[conversation.joules.length - 1]
: undefined;
}

export function forceRemoveHumanJoules(
conversation: Conversation
): Conversation {
vscode.window.showInformationMessage(
"Melty is force-removing failed messages to recover from an issue"
);
// remove any human joules at the end of the conversation
const indexOfLastBotJoule =
conversation.joules.length -
1 -
Array.from(conversation.joules)
.reverse()
.findIndex((joule) => joule.author === "bot");
return {
joules: conversation.joules.slice(0, indexOfLastBotJoule + 1),
};
}
Loading

0 comments on commit 1223923

Please sign in to comment.