Files
united-workforce/packages/workflow-agent-hermes/src/index.ts
T
xiaoju fa9163e462 refactor: all-agentic architecture — roles as pure data, agent binding at runtime
BREAKING: Major architecture change.

- RoleDefinition = pure data (systemPrompt + schema + dryRunMeta)
- AgentFn = (ctx: ThreadContext) => Promise<string>, reads ctx.currentRole
- WorkflowDefinition decoupled from agents, bound via AgentBinding at runtime
- createWorkflow(def, binding, extract) replaces createRoleModerator
- Meta extraction moved into engine loop
- Delete workflow-util-role package (createRole, decorators, extract all gone)
- Role packages become pure data exports
- Agent packages updated to single-arg AgentFn

小橘 <xiaoju@shazhou.work>
2026-05-06 14:14:33 +00:00

61 lines
1.8 KiB
TypeScript

import type { AgentFn } from "@uncaged/workflow";
import { buildAgentPrompt, type SpawnCliError, spawnCli } from "@uncaged/workflow-util-agent";
import type { HermesAgentConfig } from "./types.js";
import { validateHermesAgentConfig } from "./validate-config.js";
const HERMES_DEFAULT_MAX_TURNS = 90;
export { buildAgentPrompt } from "@uncaged/workflow-util-agent";
export type { HermesAgentConfig } from "./types.js";
export { validateHermesAgentConfig } from "./validate-config.js";
function throwHermesSpawnError(error: SpawnCliError): never {
if (error.kind === "non_zero_exit") {
throw new Error(
`hermes: exitCode=${error.exitCode} stdout=${error.stdout} stderr=${error.stderr}`,
);
}
if (error.kind === "timeout") {
throw new Error("hermes: timeout");
}
if (error.kind === "spawn_failed") {
throw new Error(`hermes: ${error.message}`);
}
throw new Error("hermes: unknown spawn error");
}
/** Runs `hermes chat` non-interactively with the Nerve-style argv contract (`-q`, `--yolo`, `--quiet`). */
export function createHermesAgent(config: HermesAgentConfig): AgentFn {
const validated = validateHermesAgentConfig(config);
if (!validated.ok) {
throw new Error(validated.error);
}
const timeoutMs = config.timeout;
return async (ctx) => {
const fullPrompt = buildAgentPrompt(ctx.currentRole.systemPrompt, ctx);
const args = [
"chat",
"-q",
fullPrompt,
"--yolo",
"--max-turns",
String(HERMES_DEFAULT_MAX_TURNS),
"--quiet",
];
if (config.model !== null) {
args.push("--model", config.model);
}
const run = await spawnCli("hermes", args, {
cwd: null,
timeoutMs,
});
if (!run.ok) {
throwHermesSpawnError(run.error);
}
return run.value;
};
}