|
|
|
|
|
const { input } = require("@inquirer/prompts"); |
|
|
const chalk = require("chalk"); |
|
|
const { RetryError } = require("../error"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const cli = { |
|
|
name: "cli", |
|
|
startupConfig: { |
|
|
params: {}, |
|
|
}, |
|
|
plugin: function ({ simulateStream = true } = {}) { |
|
|
return { |
|
|
name: this.name, |
|
|
setup(aibitat) { |
|
|
let printing = []; |
|
|
|
|
|
aibitat.onError(async (error) => { |
|
|
let errorMessage = |
|
|
error?.message || "An error occurred while running the agent."; |
|
|
console.error(chalk.red(` error: ${errorMessage}`), error); |
|
|
}); |
|
|
|
|
|
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); |
|
|
|
|
|
console.log(); |
|
|
|
|
|
if (feedback === "exit") { |
|
|
console.log("๐ chat finished"); |
|
|
return process.exit(0); |
|
|
} |
|
|
|
|
|
await aibitat.continue(feedback); |
|
|
}); |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
|
console.log(); |
|
|
return; |
|
|
} |
|
|
|
|
|
process.stdout.write(`${reference}\n`); |
|
|
|
|
|
|
|
|
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, |
|
|
|
|
|
Math.floor(Math.random() * 40) + 10 |
|
|
) |
|
|
); |
|
|
} |
|
|
controller.close(); |
|
|
}, |
|
|
}); |
|
|
|
|
|
|
|
|
for await (const chunk of stream) { |
|
|
process.stdout.write(new TextDecoder().decode(chunk)); |
|
|
} |
|
|
|
|
|
|
|
|
console.log(); |
|
|
console.log(); |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 }; |
|
|
|