Add print-mode thinking output flag
This commit is contained in:
@@ -56,6 +56,7 @@ export interface Args {
|
||||
noExtensions?: boolean;
|
||||
pluginDirs?: string[];
|
||||
print?: boolean;
|
||||
printThoughts?: boolean;
|
||||
export?: string;
|
||||
noSkills?: boolean;
|
||||
skills?: string[];
|
||||
@@ -200,6 +201,8 @@ export function parseArgs(inputArgs: string[], extensionFlags?: Map<string, { ty
|
||||
result.advisor = true;
|
||||
} else if (arg === "--print" || arg === "-p") {
|
||||
result.print = true;
|
||||
} else if (arg === "--print-thoughts") {
|
||||
result.printThoughts = true;
|
||||
} else if (arg === "--no-extensions") {
|
||||
result.noExtensions = true;
|
||||
} else if (arg === "--no-skills") {
|
||||
|
||||
@@ -270,6 +270,7 @@ export const VALUELESS_FLAGS: ReadonlySet<string> = new Set([
|
||||
"--hide-thinking",
|
||||
"--advisor",
|
||||
"--print",
|
||||
"--print-thoughts",
|
||||
"--no-extensions",
|
||||
"--no-skills",
|
||||
"--no-rules",
|
||||
|
||||
@@ -136,6 +136,9 @@ export default class Index extends Command {
|
||||
"no-title": Flags.boolean({
|
||||
description: "Disable title auto-generation",
|
||||
}),
|
||||
"print-thoughts": Flags.boolean({
|
||||
description: "Include thinking blocks in print mode text output",
|
||||
}),
|
||||
"max-time": Flags.string({
|
||||
description: "Stop the session after this many seconds",
|
||||
}),
|
||||
|
||||
@@ -1373,6 +1373,7 @@ export async function runRootCommand(
|
||||
messages: initialArgs.messages,
|
||||
initialMessage,
|
||||
initialImages,
|
||||
printThoughts: initialArgs.printThoughts,
|
||||
});
|
||||
if ($env.PI_TIMING) {
|
||||
logger.printTimings();
|
||||
|
||||
@@ -24,6 +24,8 @@ export interface PrintModeOptions {
|
||||
initialMessage?: string;
|
||||
/** Images to attach to the initial message */
|
||||
initialImages?: ImageContent[];
|
||||
/** If true, include thinking blocks in text output */
|
||||
printThoughts?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -31,7 +33,7 @@ export interface PrintModeOptions {
|
||||
* Sends prompts to the agent and outputs the result.
|
||||
*/
|
||||
export async function runPrintMode(session: AgentSession, options: PrintModeOptions): Promise<void> {
|
||||
const { mode, messages = [], initialMessage, initialImages } = options;
|
||||
const { mode, messages = [], initialMessage, initialImages, printThoughts } = options;
|
||||
|
||||
// Emit session header for JSON mode
|
||||
if (mode === "json") {
|
||||
@@ -108,6 +110,8 @@ export async function runPrintMode(session: AgentSession, options: PrintModeOpti
|
||||
for (const content of assistantMsg.content) {
|
||||
if (content.type === "text") {
|
||||
process.stdout.write(`${sanitizeText(content.text)}\n`);
|
||||
} else if (printThoughts && content.type === "thinking" && content.thinking.trim().length > 0) {
|
||||
process.stdout.write(`${sanitizeText(content.thinking)}\n`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import { parseArgs } from "@oh-my-pi/pi-coding-agent/cli/args";
|
||||
|
||||
describe("parseArgs — --print-thoughts flag", () => {
|
||||
it("parses --print-thoughts as a boolean flag", () => {
|
||||
const result = parseArgs(["--print-thoughts"]);
|
||||
expect(result.printThoughts).toBe(true);
|
||||
});
|
||||
|
||||
it("does not consume the next argument", () => {
|
||||
const result = parseArgs(["--print", "--print-thoughts", "explain"]);
|
||||
expect(result.print).toBe(true);
|
||||
expect(result.printThoughts).toBe(true);
|
||||
expect(result.messages).toEqual(["explain"]);
|
||||
});
|
||||
});
|
||||
@@ -48,15 +48,19 @@ function createMockSession(messages: AssistantMessage[]): AgentSession {
|
||||
describe("Print-mode silent-abort regression", () => {
|
||||
let exitSpy: ReturnType<typeof vi.spyOn>;
|
||||
let stderrOutput: string[];
|
||||
let stdoutOutput: string[];
|
||||
|
||||
beforeEach(() => {
|
||||
stderrOutput = [];
|
||||
stdoutOutput = [];
|
||||
vi.spyOn(process.stderr, "write").mockImplementation((chunk: unknown) => {
|
||||
stderrOutput.push(String(chunk));
|
||||
return true;
|
||||
});
|
||||
exitSpy = vi.spyOn(process, "exit").mockImplementation(() => undefined as never);
|
||||
vi.spyOn(process.stdout, "write").mockImplementation((...args: unknown[]) => {
|
||||
const chunk = args[0];
|
||||
if (typeof chunk === "string") stdoutOutput.push(chunk);
|
||||
// Invoke callback if present (runPrintMode flushes stdout before returning)
|
||||
const last = args[args.length - 1];
|
||||
if (typeof last === "function") last();
|
||||
@@ -105,4 +109,22 @@ describe("Print-mode silent-abort regression", () => {
|
||||
// process.exit(1) SHOULD have been called
|
||||
expect(exitSpy).toHaveBeenCalledWith(1);
|
||||
});
|
||||
|
||||
it("prints thinking blocks only when printThoughts is enabled", async () => {
|
||||
const { runPrintMode } = await import("@oh-my-pi/pi-coding-agent/modes/print-mode");
|
||||
|
||||
const message = makeAssistantMessage({
|
||||
content: [
|
||||
{ type: "thinking", thinking: "inspect hidden branch" },
|
||||
{ type: "text", text: "final answer" },
|
||||
],
|
||||
});
|
||||
|
||||
await runPrintMode(createMockSession([message]), { mode: "text" });
|
||||
expect(stdoutOutput.join("")).toBe("final answer\n");
|
||||
|
||||
stdoutOutput = [];
|
||||
await runPrintMode(createMockSession([message]), { mode: "text", printThoughts: true });
|
||||
expect(stdoutOutput.join("")).toBe("inspect hidden branch\nfinal answer\n");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user