You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
// Plugin CAN ONLY BE USE IN DEVELOPMENT.
const { input } = require("@inquirer/prompts");const chalk = require("chalk");const { RetryError } = require("../error");
/** * Command-line Interface plugin. It prints the messages on the console and asks for feedback * while the conversation is running in the background. */const cli = { name: "cli", startupConfig: { params: {}, }, plugin: function ({ simulateStream = true } = {}) { return { name: this.name, setup(aibitat) { let printing = [];
aibitat.onError(async (error) => { console.error(chalk.red(` error: ${error?.message}`)); if (error instanceof RetryError) { console.error(chalk.red(` retrying in 60 seconds...`)); setTimeout(() => { aibitat.retry(); }, 60000); return; } });
aibitat.onStart(() => { console.log(); console.log("🚀 starting chat ...\n"); printing = [Promise.resolve()]; });
aibitat.onMessage(async (message) => { const next = new Promise(async (resolve) => { await Promise.all(printing); await this.print(message, simulateStream); resolve(); }); printing.push(next); });
aibitat.onTerminate(async () => { await Promise.all(printing); console.log("🚀 chat finished"); });
aibitat.onInterrupt(async (node) => { await Promise.all(printing); const feedback = await this.askForFeedback(node); // Add an extra line after the message
console.log();
if (feedback === "exit") { console.log("🚀 chat finished"); return process.exit(0); }
await aibitat.continue(feedback); }); },
/** * Print a message on the terminal * * @param message * // message Type { from: string; to: string; content?: string } & {
state: 'loading' | 'error' | 'success' | 'interrupt' } * @param simulateStream */ print: async function (message = {}, simulateStream = true) { const replying = chalk.dim(`(to ${message.to})`); const reference = `${chalk.magenta("✎")} ${chalk.bold( message.from )} ${replying}:`;
if (!simulateStream) { console.log(reference); console.log(message.content); // Add an extra line after the message
console.log(); return; }
process.stdout.write(`${reference}\n`);
// Emulate streaming by breaking the cached response into chunks
const chunks = message.content?.split(" ") || []; const stream = new ReadableStream({ async start(controller) { for (const chunk of chunks) { const bytes = new TextEncoder().encode(chunk + " "); controller.enqueue(bytes); await new Promise((r) => setTimeout( r, // get a random number between 10ms and 50ms to simulate a random delay
Math.floor(Math.random() * 40) + 10 ) ); } controller.close(); }, });
// Stream the response to the chat
for await (const chunk of stream) { process.stdout.write(new TextDecoder().decode(chunk)); }
// Add an extra line after the message
console.log(); console.log(); },
/** * Ask for feedback to the user using the terminal * * @param node //{ from: string; to: string }
* @returns */ askForFeedback: function (node = {}) { return input({ message: `Provide feedback to ${chalk.yellow( node.to )} as ${chalk.yellow( node.from )}. Press enter to skip and use auto-reply, or type 'exit' to end the conversation: `,
}); }, }; },};
module.exports = { cli };
|