41 lines
1.4 KiB
TypeScript
41 lines
1.4 KiB
TypeScript
import type { AgentFn, Role, ThreadContext } from "@uncaged/nerve-core";
|
|
import type { LlmExtractorConfig } from "@uncaged/nerve-workflow-utils";
|
|
import { createRole } from "@uncaged/nerve-workflow-utils";
|
|
import { z } from "zod";
|
|
|
|
function testPrompt({ threadId }: { threadId: string }): string {
|
|
return `You are the **test** agent (Hermes). You execute automated tests for the change.
|
|
|
|
Read workflow context: \`nerve thread show ${threadId}\`
|
|
|
|
Find **repo path** from \`---SOLVE_ISSUE_REPO--- path:\` in the thread.
|
|
|
|
From the **plan** step output, locate **Test commands** (explicit shell commands). Run each command with cwd = repo path, in order.
|
|
|
|
If the plan lists **no** test commands, try **pnpm test**, then **npm test** if pnpm is unavailable; if neither applies, explain skip.
|
|
|
|
Collect stdout/stderr snippets on failure.
|
|
|
|
End with JSON only:
|
|
\`\`\`json
|
|
{ "passed": true }
|
|
\`\`\`
|
|
or \`{ "passed": false }\`
|
|
|
|
**passed=true** only if every executed command exited 0 (or skip was justified with no failing command).`;
|
|
}
|
|
|
|
export const testMetaSchema = z.object({
|
|
passed: z.boolean().describe("true if all test commands passed"),
|
|
});
|
|
export type TestMeta = z.infer<typeof testMetaSchema>;
|
|
|
|
export function createTestRole(adapter: AgentFn, extract: LlmExtractorConfig): Role<TestMeta> {
|
|
return createRole(
|
|
adapter,
|
|
async (ctx: ThreadContext) => testPrompt({ threadId: ctx.start.meta.threadId }),
|
|
testMetaSchema,
|
|
extract,
|
|
);
|
|
}
|