fix: show print mode liveness
This commit is contained in:
parent
487237a32c
commit
f88b48b0aa
2 changed files with 94 additions and 0 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import assert from "node:assert/strict";
|
||||
import { test } from "vitest";
|
||||
import {
|
||||
createPrintModeLivenessReporter,
|
||||
PrintModeTimeoutError,
|
||||
promptWithPrintTimeout,
|
||||
resolvePrintModeTimeoutMs,
|
||||
|
|
@ -79,3 +80,61 @@ test("runPrintMode_when_extension_startup_hangs_still_runs_prompt", async () =>
|
|||
console.log = originalLog;
|
||||
}
|
||||
});
|
||||
|
||||
test("createPrintModeLivenessReporter_in_text_mode_reports_progress_to_stderr_once", () => {
|
||||
const writes: string[] = [];
|
||||
const originalWrite = process.stderr.write;
|
||||
process.stderr.write = ((chunk: string | Uint8Array) => {
|
||||
writes.push(String(chunk));
|
||||
return true;
|
||||
}) as typeof process.stderr.write;
|
||||
try {
|
||||
const report = createPrintModeLivenessReporter("text");
|
||||
report({ type: "message_start" });
|
||||
report({
|
||||
type: "message_update",
|
||||
assistantMessageEvent: { type: "thinking_start" },
|
||||
});
|
||||
report({
|
||||
type: "message_update",
|
||||
assistantMessageEvent: { type: "thinking_delta" },
|
||||
});
|
||||
report({
|
||||
type: "message_update",
|
||||
assistantMessageEvent: { type: "text_start" },
|
||||
});
|
||||
report({
|
||||
type: "message_update",
|
||||
assistantMessageEvent: { type: "text_delta" },
|
||||
});
|
||||
|
||||
assert.deepEqual(writes, [
|
||||
"[forge] model responding...\n",
|
||||
"[forge] thinking...\n",
|
||||
"[forge] writing response...\n",
|
||||
]);
|
||||
} finally {
|
||||
process.stderr.write = originalWrite;
|
||||
}
|
||||
});
|
||||
|
||||
test("createPrintModeLivenessReporter_in_json_mode_keeps_stderr_quiet", () => {
|
||||
const writes: string[] = [];
|
||||
const originalWrite = process.stderr.write;
|
||||
process.stderr.write = ((chunk: string | Uint8Array) => {
|
||||
writes.push(String(chunk));
|
||||
return true;
|
||||
}) as typeof process.stderr.write;
|
||||
try {
|
||||
const report = createPrintModeLivenessReporter("json");
|
||||
report({ type: "message_start" });
|
||||
report({
|
||||
type: "message_update",
|
||||
assistantMessageEvent: { type: "thinking_start" },
|
||||
});
|
||||
|
||||
assert.deepEqual(writes, []);
|
||||
} finally {
|
||||
process.stderr.write = originalWrite;
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ export async function runPrintMode(
|
|||
// Print mode intentionally skips extension session_start binding. One-shot
|
||||
// automation needs bounded prompt output; startup hooks are interactive/RPC
|
||||
// lifecycle work and have previously blocked `sf -p` before the prompt ran.
|
||||
const liveness = createPrintModeLivenessReporter(mode);
|
||||
|
||||
// Always subscribe to enable session persistence via _handleAgentEvent
|
||||
const unsubscribe = session.subscribe((event) => {
|
||||
|
|
@ -133,6 +134,7 @@ export async function runPrintMode(
|
|||
if (mode === "json") {
|
||||
console.log(JSON.stringify(event));
|
||||
}
|
||||
liveness(event);
|
||||
});
|
||||
|
||||
let exitCode = 0;
|
||||
|
|
@ -232,3 +234,36 @@ export async function runPrintMode(
|
|||
process.exit(exitCode);
|
||||
}
|
||||
}
|
||||
|
||||
export function createPrintModeLivenessReporter(
|
||||
mode: "text" | "json",
|
||||
): (event: { type: string; assistantMessageEvent?: { type: string } }) => void {
|
||||
if (mode !== "text") return () => {};
|
||||
let sawAssistant = false;
|
||||
let sawThinking = false;
|
||||
let sawText = false;
|
||||
return (event) => {
|
||||
if (event.type === "message_start" && !sawAssistant) {
|
||||
sawAssistant = true;
|
||||
process.stderr.write("[forge] model responding...\n");
|
||||
return;
|
||||
}
|
||||
if (event.type !== "message_update") return;
|
||||
const streamType = event.assistantMessageEvent?.type;
|
||||
if (
|
||||
(streamType === "thinking_start" || streamType === "thinking_delta") &&
|
||||
!sawThinking
|
||||
) {
|
||||
sawThinking = true;
|
||||
process.stderr.write("[forge] thinking...\n");
|
||||
return;
|
||||
}
|
||||
if (
|
||||
(streamType === "text_start" || streamType === "text_delta") &&
|
||||
!sawText
|
||||
) {
|
||||
sawText = true;
|
||||
process.stderr.write("[forge] writing response...\n");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue