Files
united-workforce/packages/workflow-agent-hermes/__tests__/hermes-prompt.test.ts
T
xingyue e067a2f25a
CI / check (pull_request) Failing after 9m51s
refactor: rebrand npm packages @uncaged/* → @united-workforce/*
Package mapping:
- @uncaged/cli-workflow → @united-workforce/cli
- @uncaged/workflow-protocol → @united-workforce/protocol
- @uncaged/workflow-util → @united-workforce/util
- @uncaged/workflow-util-agent → @united-workforce/util-agent
- @uncaged/workflow-agent-hermes → @united-workforce/agent-hermes
- @uncaged/workflow-agent-claude-code → @united-workforce/agent-claude-code
- @uncaged/workflow-agent-builtin → @united-workforce/agent-builtin
- @uncaged/workflow-dashboard → @united-workforce/dashboard

Changes:
- 8 package.json name + dependency refs
- 82 files: import statements updated
- .changeset/config.json updated
- CLAUDE.md updated
- bunfig.toml restored for preload

CLI command (uwf) and directory names unchanged.

Closes shazhou/united-workforce#8
2026-06-02 20:56:06 +08:00

188 lines
5.9 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import type { ThreadId } from "@united-workforce/protocol";
import type { AgentContext } from "@united-workforce/util-agent";
import { buildHermesPrompt } from "../src/hermes.js";
function makeCtx(overrides: Partial<AgentContext> = {}): AgentContext {
return {
threadId: "01JTEST0000000000000000000" as ThreadId,
edgePrompt: "Proceed with the assigned role.",
isFirstVisit: true,
workflow: {
roles: {
developer: {
description: "TDD implementation per test spec",
goal: "Write code",
capabilities: ["coding"],
procedure: "1. Read spec\n2. Write code",
output: "List files changed",
frontmatter: "",
},
},
conditions: {},
graph: {},
},
role: "developer",
start: { prompt: "Fix the bug", workflow: "abc123" },
steps: [],
store: {} as AgentContext["store"],
outputFormatInstruction: "Use YAML frontmatter",
...overrides,
};
}
describe("buildHermesPrompt", () => {
test("first visit uses full role prompt and includes moderator instruction", () => {
const result = buildHermesPrompt(
makeCtx({ edgePrompt: "Focus on the failing test.", isFirstVisit: true }),
);
expect(result).toMatch(/^Use YAML frontmatter/);
expect(result).toContain("Write code");
expect(result).toContain("## Task\nFix the bug");
expect(result).toContain("## Moderator Instruction");
expect(result).toContain("Focus on the failing test.");
});
test("re-entry uses continuation prompt with edge instruction", () => {
const ctx = makeCtx({
isFirstVisit: false,
edgePrompt: "The reviewer rejected your work. Fix the issues.",
steps: [
{
role: "developer",
output: { summary: "Initial fix" },
agent: "uwf-hermes",
detail: "detail-1",
edgePrompt: "Implement the fix.",
content: null,
},
{
role: "reviewer",
output: { approved: false },
agent: "uwf-hermes",
detail: "detail-2",
edgePrompt: "Review the code.",
content: null,
},
],
});
const result = buildHermesPrompt(ctx);
expect(result).not.toContain("## Task");
expect(result).toContain("## What Happened Since Your Last Turn");
expect(result).toContain("## Moderator Instruction");
expect(result).toContain("The reviewer rejected your work.");
});
test("forced first visit via isFirstVisit uses initial prompt even when role appears in history", () => {
const result = buildHermesPrompt(
makeCtx({
isFirstVisit: true,
steps: [
{
role: "developer",
output: { done: true },
agent: "uwf-hermes",
detail: "detail-1",
edgePrompt: "First attempt.",
content: null,
},
],
edgePrompt: "Retry with a fresh approach.",
}),
);
expect(result).toContain("## Task");
expect(result).toContain("Retry with a fresh approach.");
expect(result).not.toContain("## What Happened Since Your Last Turn");
});
test("first visit includes content from previous steps", () => {
const ctx = makeCtx({
isFirstVisit: true,
steps: [
{
role: "planner",
output: { plan: "hash1" },
agent: "uwf-hermes",
detail: "detail-1",
edgePrompt: "Create the plan.",
content: "# Plan\nDetailed plan markdown...",
},
{
role: "developer",
output: { files: ["app.ts"] },
agent: "uwf-hermes",
detail: "detail-2",
edgePrompt: "Implement the code.",
content: "# Implementation\nCode changes...",
},
{
role: "reviewer",
output: { approved: true },
agent: "uwf-hermes",
detail: "detail-3",
edgePrompt: "Review the work.",
content: "# Review\nApproved!",
},
],
role: "committer",
edgePrompt: "Commit the reviewed code.",
});
const result = buildHermesPrompt(ctx);
expect(result).toContain("Use YAML frontmatter");
expect(result).toContain("## Task");
expect(result).toContain("Fix the bug");
expect(result).toContain("## What Happened Since Your Last Turn");
expect(result).toContain("### Step 1: planner");
expect(result).toContain("#### Step Content");
expect(result).toContain("# Plan");
expect(result).toContain("Detailed plan markdown");
expect(result).toContain("### Step 2: developer");
expect(result).toContain("# Implementation");
expect(result).toContain("### Step 3: reviewer");
expect(result).toContain("# Review");
expect(result).toContain("## Moderator Instruction");
expect(result).toContain("Commit the reviewed code.");
});
test("re-entry omits content from previous steps", () => {
const ctx = makeCtx({
isFirstVisit: false,
steps: [
{
role: "developer",
output: { files: ["app.ts"] },
agent: "uwf-hermes",
detail: "detail-1",
edgePrompt: "Implement the code.",
content: "# Implementation\nCode changes...",
},
{
role: "reviewer",
output: { approved: false },
agent: "uwf-hermes",
detail: "detail-2",
edgePrompt: "Review the work.",
content: "# Review\nNot approved!",
},
],
role: "developer",
edgePrompt: "Fix the issues.",
});
const result = buildHermesPrompt(ctx);
expect(result).toContain("## What Happened Since Your Last Turn");
expect(result).toContain("### Step 2: reviewer");
expect(result).toContain(JSON.stringify({ approved: false }));
expect(result).not.toContain("#### Step Content");
expect(result).not.toContain("# Review");
expect(result).not.toContain("Not approved!");
});
});