fix(coding-agent): merge piped stdin into initial prompt closes #2315
This commit is contained in:
43
packages/coding-agent/src/cli/initial-message.ts
Normal file
43
packages/coding-agent/src/cli/initial-message.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import type { ImageContent } from "@mariozechner/pi-ai";
|
||||
import type { Args } from "./args.js";
|
||||
|
||||
export interface InitialMessageInput {
|
||||
parsed: Args;
|
||||
fileText?: string;
|
||||
fileImages?: ImageContent[];
|
||||
stdinContent?: string;
|
||||
}
|
||||
|
||||
export interface InitialMessageResult {
|
||||
initialMessage?: string;
|
||||
initialImages?: ImageContent[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine stdin content, @file text, and the first CLI message into a single
|
||||
* initial prompt for non-interactive mode.
|
||||
*/
|
||||
export function buildInitialMessage({
|
||||
parsed,
|
||||
fileText,
|
||||
fileImages,
|
||||
stdinContent,
|
||||
}: InitialMessageInput): InitialMessageResult {
|
||||
const parts: string[] = [];
|
||||
if (stdinContent !== undefined) {
|
||||
parts.push(stdinContent);
|
||||
}
|
||||
if (fileText) {
|
||||
parts.push(fileText);
|
||||
}
|
||||
|
||||
if (parsed.messages.length > 0) {
|
||||
parts.push(parsed.messages[0]);
|
||||
parsed.messages.shift();
|
||||
}
|
||||
|
||||
return {
|
||||
initialMessage: parts.length > 0 ? parts.join("") : undefined,
|
||||
initialImages: fileImages && fileImages.length > 0 ? fileImages : undefined,
|
||||
};
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import { createInterface } from "readline";
|
||||
import { type Args, parseArgs, printHelp } from "./cli/args.js";
|
||||
import { selectConfig } from "./cli/config-selector.js";
|
||||
import { processFileArguments } from "./cli/file-processor.js";
|
||||
import { buildInitialMessage } from "./cli/initial-message.js";
|
||||
import { listModels } from "./cli/list-models.js";
|
||||
import { selectSession } from "./cli/session-picker.js";
|
||||
import { APP_NAME, getAgentDir, getModelsPath, VERSION } from "./config.js";
|
||||
@@ -311,28 +312,22 @@ async function handlePackageCommand(args: string[]): Promise<boolean> {
|
||||
async function prepareInitialMessage(
|
||||
parsed: Args,
|
||||
autoResizeImages: boolean,
|
||||
stdinContent?: string,
|
||||
): Promise<{
|
||||
initialMessage?: string;
|
||||
initialImages?: ImageContent[];
|
||||
}> {
|
||||
if (parsed.fileArgs.length === 0) {
|
||||
return {};
|
||||
return buildInitialMessage({ parsed, stdinContent });
|
||||
}
|
||||
|
||||
const { text, images } = await processFileArguments(parsed.fileArgs, { autoResizeImages });
|
||||
|
||||
let initialMessage: string;
|
||||
if (parsed.messages.length > 0) {
|
||||
initialMessage = text + parsed.messages[0];
|
||||
parsed.messages.shift();
|
||||
} else {
|
||||
initialMessage = text;
|
||||
}
|
||||
|
||||
return {
|
||||
initialMessage,
|
||||
initialImages: images.length > 0 ? images : undefined,
|
||||
};
|
||||
return buildInitialMessage({
|
||||
parsed,
|
||||
fileText: text,
|
||||
fileImages: images,
|
||||
stdinContent,
|
||||
});
|
||||
}
|
||||
|
||||
/** Result from resolving a session argument */
|
||||
@@ -675,13 +670,12 @@ export async function main(args: string[]) {
|
||||
}
|
||||
|
||||
// Read piped stdin content (if any) - skip for RPC mode which uses stdin for JSON-RPC
|
||||
let stdinContent: string | undefined;
|
||||
if (parsed.mode !== "rpc") {
|
||||
const stdinContent = await readPipedStdin();
|
||||
stdinContent = await readPipedStdin();
|
||||
if (stdinContent !== undefined) {
|
||||
// Force print mode since interactive mode requires a TTY for keyboard input
|
||||
parsed.print = true;
|
||||
// Prepend stdin content to messages
|
||||
parsed.messages.unshift(stdinContent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -704,7 +698,11 @@ export async function main(args: string[]) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const { initialMessage, initialImages } = await prepareInitialMessage(parsed, settingsManager.getImageAutoResize());
|
||||
const { initialMessage, initialImages } = await prepareInitialMessage(
|
||||
parsed,
|
||||
settingsManager.getImageAutoResize(),
|
||||
stdinContent,
|
||||
);
|
||||
const isInteractive = !parsed.print && parsed.mode === undefined;
|
||||
const mode = parsed.mode || "text";
|
||||
initTheme(settingsManager.getTheme(), isInteractive);
|
||||
|
||||
Reference in New Issue
Block a user