fix: share ACP client across run/continue for session continuity

The client is now created once in createHermesAgent() and shared by
runHermes and continueHermes closures. This preserves conversation
context during frontmatter retry loops — continue() sends a follow-up
prompt on the same ACP session instead of starting a new one.

Client is cleaned up via process.on('exit').

Ref #398
This commit is contained in:
2026-05-22 13:06:14 +00:00
parent 025695dbe9
commit 68af555313
+23 -20
View File
@@ -45,38 +45,41 @@ export function buildHermesPrompt(ctx: AgentContext): string {
return parts.join("\n"); return parts.join("\n");
} }
async function runHermes(ctx: AgentContext): Promise<AgentRunResult> { /**
const fullPrompt = buildHermesPrompt(ctx); * Agent CLI factory: parses argv, runs Hermes, extracts output, writes StepNode.
*
* A single ACP client is shared across run() and continue() calls so that
* frontmatter retry loops keep the same Hermes session context. The client
* is closed once the agent process exits (via process.on("exit")).
*/
export function createHermesAgent(): () => Promise<void> {
const client = new HermesAcpClient(); const client = new HermesAcpClient();
try {
// Ensure cleanup regardless of how the process exits.
process.on("exit", () => {
void client.close();
});
async function runHermes(ctx: AgentContext): Promise<AgentRunResult> {
const fullPrompt = buildHermesPrompt(ctx);
await client.connect(process.cwd()); await client.connect(process.cwd());
const { text, sessionId } = await client.prompt(fullPrompt); const { text, sessionId } = await client.prompt(fullPrompt);
const detailHash = await storeHermesRawOutput(ctx.store, text); const detailHash = await storeHermesRawOutput(ctx.store, text);
return { output: text, detailHash, sessionId }; return { output: text, detailHash, sessionId };
} finally {
await client.close();
} }
}
async function continueHermes( async function continueHermes(
_sessionId: string, _sessionId: string,
message: string, message: string,
store: Store, store: Store,
): Promise<AgentRunResult> { ): Promise<AgentRunResult> {
// ACP does not support resuming an external session; start a new session with the message as prompt // Client is already connected from runHermes — same ACP session,
const client = new HermesAcpClient(); // so the agent sees the full conversation history (crucial for retries).
try {
await client.connect(process.cwd());
const { text, sessionId } = await client.prompt(message); const { text, sessionId } = await client.prompt(message);
const detailHash = await storeHermesRawOutput(store, text); const detailHash = await storeHermesRawOutput(store, text);
return { output: text, detailHash, sessionId }; return { output: text, detailHash, sessionId };
} finally {
await client.close();
} }
}
/** Agent CLI factory: parses argv, runs Hermes, extracts output, writes StepNode. */
export function createHermesAgent(): () => Promise<void> {
return createAgent({ return createAgent({
name: "hermes", name: "hermes",
run: runHermes, run: runHermes,