小橘 🍊(NEKO Team) c585e0d8a8 Refactor committer into Hermes agent with branch/commit/push workflow
Add solve-issue committer after implement; replace develop-sense and develop-workflow script roles with createRole(hermesAdapter). Implement prompt no longer does git; publish prompt asks for meaningful PR titles.

Refs #9

Made-with: Cursor
2026-04-29 10:44:28 +00:00

63 lines
1.7 KiB
TypeScript

import type { Role, RoleResult, StartStep } from "@uncaged/nerve-core";
import { hermesAdapter } from "@uncaged/nerve-adapter-hermes";
import type { LlmExtractorConfig } from "@uncaged/nerve-workflow-utils";
import { createRole, isDryRun } from "@uncaged/nerve-workflow-utils";
import { z } from "zod";
import { workspaceCommitterPrompt } from "./prompt.js";
export const committerMetaSchema = z.object({
committed: z
.boolean()
.describe("true if branch created, changes committed, and pushed successfully"),
});
export type CommitterMeta = z.infer<typeof committerMetaSchema>;
export type BuildWorkspaceCommitterDeps = {
extract: LlmExtractorConfig;
nerveRoot: string;
workflowName: string;
};
export function buildWorkspaceCommitterRole({
extract,
nerveRoot,
workflowName,
}: BuildWorkspaceCommitterDeps): Role<CommitterMeta> {
const innerRole = createRole(
hermesAdapter,
async (start: StartStep) =>
workspaceCommitterPrompt({
threadId: start.meta.threadId,
nerveRoot,
workflowName,
}),
committerMetaSchema,
extract,
);
return async (start, _messages): Promise<RoleResult<CommitterMeta>> => {
if (isDryRun(start)) {
return {
content: "[dry-run] committer skipped (no git branch/commit/push)",
meta: { committed: true },
};
}
const innerStart = {
...start,
meta: { ...start.meta, workdir: nerveRoot },
} as StartStep;
try {
return await innerRole(innerStart, _messages);
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
return {
content: `committer failed: ${msg}`,
meta: { committed: false },
};
}
};
}