From 4ae6a76b8a9b1e41ff15c8aac61ede432c8727e4 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 26 Feb 2025 21:29:36 -0500 Subject: [PATCH 1/2] central user prompts with consistent formatting into a function. --- packages/agent/src/index.ts | 1 + .../agent/src/tools/interaction/userPrompt.ts | 22 ++-------------- packages/agent/src/utils/userPrompt.ts | 25 +++++++++++++++++++ packages/cli/src/commands/$default.ts | 20 +++------------ 4 files changed, 32 insertions(+), 36 deletions(-) create mode 100644 packages/agent/src/utils/userPrompt.ts 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..b9f3219 --- /dev/null +++ b/packages/agent/src/utils/userPrompt.ts @@ -0,0 +1,25 @@ +import * as readline from 'readline'; + +import chalk from 'chalk'; + +export const userPrompt = async (prompt: string): Promise => { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + terminal: true, + }); + + try { + // Disable the readline interface's internal input processing + if (rl.terminal) { + process.stdin.setRawMode(false); + } + return await new Promise((resolve) => { + rl.question(chalk.green('\n' + prompt + '\n') + '\n> ', (answer) => { + resolve(answer); + }); + }); + } 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; From c0c8e50c07b15678028dc0a1c30d1bc4636dd669 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Thu, 27 Feb 2025 08:10:23 -0500 Subject: [PATCH 2/2] better terminal compatibility. --- packages/agent/src/utils/userPrompt.ts | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/packages/agent/src/utils/userPrompt.ts b/packages/agent/src/utils/userPrompt.ts index b9f3219..3da50da 100644 --- a/packages/agent/src/utils/userPrompt.ts +++ b/packages/agent/src/utils/userPrompt.ts @@ -1,24 +1,15 @@ -import * as readline from 'readline'; +import { createInterface } from 'readline/promises'; import chalk from 'chalk'; export const userPrompt = async (prompt: string): Promise => { - const rl = readline.createInterface({ + const rl = createInterface({ input: process.stdin, output: process.stdout, - terminal: true, }); try { - // Disable the readline interface's internal input processing - if (rl.terminal) { - process.stdin.setRawMode(false); - } - return await new Promise((resolve) => { - rl.question(chalk.green('\n' + prompt + '\n') + '\n> ', (answer) => { - resolve(answer); - }); - }); + return await rl.question(chalk.green('\n' + prompt + '\n') + '\n> '); } finally { rl.close(); }