diff --git a/packages/agent/src/index.ts b/packages/agent/src/index.ts index bb716a4..b86b6ce 100644 --- a/packages/agent/src/index.ts +++ b/packages/agent/src/index.ts @@ -36,3 +36,4 @@ export * from './utils/errorToString.js'; export * from './utils/logger.js'; export * from './utils/mockLogger.js'; export * from './utils/stringifyLimited.js'; +export * from './utils/userPrompt.js'; diff --git a/packages/agent/src/tools/interaction/userPrompt.ts b/packages/agent/src/tools/interaction/userPrompt.ts index c735b68..25b99a1 100644 --- a/packages/agent/src/tools/interaction/userPrompt.ts +++ b/packages/agent/src/tools/interaction/userPrompt.ts @@ -1,10 +1,8 @@ -import * as readline from 'readline'; - -import chalk from 'chalk'; import { z } from 'zod'; import { zodToJsonSchema } from 'zod-to-json-schema'; import { Tool } from '../../core/types.js'; +import { userPrompt } from '../../utils/userPrompt.js'; const parameterSchema = z.object({ prompt: z.string().describe('The prompt message to display to the user'), @@ -23,26 +21,10 @@ export const userPromptTool: Tool = { execute: async ({ prompt }, { logger }) => { logger.verbose(`Prompting user with: ${prompt}`); - const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout, - terminal: true, - }); - - // Disable the readline interface's internal input processing - if (rl.terminal) { - process.stdin.setRawMode(false); - } - - const response = await new Promise((resolve) => { - rl.question(chalk.green(prompt + ' '), (answer) => { - resolve(answer); - }); - }); + const response = await userPrompt(prompt); logger.verbose(`Received user response: ${response}`); - rl.close(); return response; }, logParameters: () => {}, diff --git a/packages/agent/src/utils/userPrompt.ts b/packages/agent/src/utils/userPrompt.ts new file mode 100644 index 0000000..3da50da --- /dev/null +++ b/packages/agent/src/utils/userPrompt.ts @@ -0,0 +1,16 @@ +import { createInterface } from 'readline/promises'; + +import chalk from 'chalk'; + +export const userPrompt = async (prompt: string): Promise => { + const rl = createInterface({ + input: process.stdin, + output: process.stdout, + }); + + try { + return await rl.question(chalk.green('\n' + prompt + '\n') + '\n> '); + } finally { + rl.close(); + } +}; diff --git a/packages/cli/src/commands/$default.ts b/packages/cli/src/commands/$default.ts index 9e8712b..65e9656 100644 --- a/packages/cli/src/commands/$default.ts +++ b/packages/cli/src/commands/$default.ts @@ -1,13 +1,13 @@ import * as fs from 'fs/promises'; import { createInterface } from 'readline/promises'; -import chalk from 'chalk'; import { toolAgent, Logger, getTools, getAnthropicApiKeyError, TokenLevel, + userPrompt, } from 'mycoder-agent'; import { SharedOptions } from '../options.js'; @@ -85,21 +85,9 @@ export const command: CommandModule = { // If interactive mode if (argv.interactive) { - const readline = createInterface({ - input: process.stdin, - output: process.stdout, - }); - - try { - console.log( - chalk.green( - "Type your request below or 'help' for usage information. Use Ctrl+C to exit.", - ), - ); - prompt = await readline.question('\n> '); - } finally { - readline.close(); - } + prompt = await userPrompt( + "Type your request below or 'help' for usage information. Use Ctrl+C to exit.", + ); } else if (!prompt) { // Use command line prompt if provided prompt = argv.prompt;