Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(index.ts): add new 'one-shot' command to ask a quick question an… #6

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 102 additions & 49 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { deleteCredentials } from "./creds";
import readline from "readline";
import { findPlugin, executePlugin, initializePlugins } from "./commands";
import determinePlugins from "./rag";
import multiline from "./multiline";

const program = new Command();

Expand All @@ -26,69 +27,121 @@ program
// Initialize plugins
initializePlugins();

const prompt = () => {
const prompt = async () => {
process.stdout.write(chalk.blueBright("\nYou: "));
process.stdin.resume();
process.stdin.setEncoding("utf-8");
process.stdin.once("data", async (data) => {
const userInput = data.toString().trim();

if (creds.apiKey != null) {
try {
// Direct plugin call
const plugin = findPlugin(userInput);
if (plugin) {
console.log(chalk.yellow(`Executing plugin: ${plugin.name}`));
await executePlugin(plugin, {
userInput,
engine: creds.engine,
apiKey: creds.apiKey,
opts: { ...opts, model: creds.model || undefined },
});
} else {
// Use LLM to determine if a plugin should be used
const pluginKeyword = await determinePlugins(
creds.engine,
creds.apiKey,
userInput,
{ ...opts, model: creds.model || undefined }
);

if (pluginKeyword !== "none") {
const plugin = findPlugin(pluginKeyword);
if (plugin) {
console.log(chalk.yellow(`Executing plugin: ${plugin.name}`));
await executePlugin(plugin, {
userInput,
engine: creds.engine,
apiKey: creds.apiKey,
opts: { ...opts, model: creds.model || undefined },
});
} else {
console.log(chalk.red(`Plugin not found: ${pluginKeyword}`));
}
} else {
// No plugin applicable, use regular promptResponse
await promptResponse(creds.engine, creds.apiKey, userInput, {
...opts,
model: creds.model || undefined,

const data = await multiline();

// process.stdin.once("data", async (data) => {
const userInput = data.toString().trim();

if (creds.apiKey != null) {
try {
// Direct plugin call
const plugin = findPlugin(userInput);
if (plugin) {
console.log(chalk.yellow(`Executing plugin: ${plugin.name}`));
await executePlugin(plugin, {
userInput,
engine: creds.engine,
apiKey: creds.apiKey,
opts: { ...opts, model: creds.model || undefined },
});
} else {
// Use LLM to determine if a plugin should be used
const pluginKeyword = await determinePlugins(
creds.engine,
creds.apiKey,
userInput,
{ ...opts, model: creds.model || undefined }
);

if (pluginKeyword.trim() !== "none") {
const plugin = findPlugin(pluginKeyword);
if (plugin) {
console.log(chalk.yellow(`Executing plugin: ${plugin.name}`));
await executePlugin(plugin, {
userInput,
engine: creds.engine,
apiKey: creds.apiKey,
opts: { ...opts, model: creds.model || undefined },
});
} else {
console.log(chalk.red(`Plugin not found: ${pluginKeyword}`));
}
} else {
// No plugin applicable, use regular promptResponse
await promptResponse(creds.engine, creds.apiKey, userInput, {
...opts,
model: creds.model || undefined,
});
}
} catch (error) {
console.error(chalk.red("An error occurred:"), error);
}
} else {
console.log(chalk.red("API key is required for chat functionality."));
} catch (error) {
console.error(chalk.red("An error occurred:"), error);
}
} else {
console.log(chalk.red("API key is required for chat functionality."));
}

prompt();
});
prompt();
// });
};

prompt();
});

program
.command("one-shot <question>")
.description("Ask a one-shot question and get a quick answer")
.option("-e, --engine <engine>", "LLM to use")
.option("-t, --temperature <temperature>", "Response temperature")
.action(async (question, opts) => {
await checkIsLatestVersion();
const creds = await apiKeyPrompt();

if (creds.apiKey != null) {
try {
// Use LLM to determine if a plugin should be used
const pluginKeyword = await determinePlugins(
creds.engine,
creds.apiKey,
question,
{ ...opts, model: creds.model || undefined }
);

if (pluginKeyword !== "none") {
const plugin = findPlugin(pluginKeyword);
if (plugin) {
console.log(chalk.yellow(`Executing plugin: ${plugin.name}`));
await executePlugin(plugin, {
userInput: question,
engine: creds.engine,
apiKey: creds.apiKey,
opts: { ...opts, model: creds.model || undefined },
});
} else {
console.log(chalk.red(`Plugin not found: ${pluginKeyword}`));
}
} else {
// No plugin applicable, use regular promptResponse
await promptResponse(creds.engine, creds.apiKey, question, {
...opts,
model: creds.model || undefined,
});
}
} catch (error) {
console.error(chalk.red("An error occurred:"), error);
}
} else {
console.log(chalk.red("API key is required for chat functionality."));
}

process.exit(0);
});

program
.command("delete")
.description("Delete your API key")
Expand Down
4 changes: 3 additions & 1 deletion src/intro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ export default async function intro() {
"@exit"
)} plugin.

${chalk.greenBright("Start chatting or use a plugin to begin!")}
${chalk.greenBright(
"Start chatting, or use a plugin to begin! Use shift+enter to finish your message, ctrl+c to exit."
)}
`;

console.log(usageText);
Expand Down
32 changes: 32 additions & 0 deletions src/multiline.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import readline from "readline";

// Function to prompt for multiline input
function promptMultilineInput() {
return new Promise((resolve) => {
let multilineInput = "";
console.log(
"Enter your text (to finish enter an empty line, Ctrl+D to submit, Ctrl+C to exit):\n"
);

const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: true,
});

rl.on("line", (line) => {
multilineInput += line + "\n";
});

rl.on("close", () => {
resolve(multilineInput);
});
});
}

// Main function to loop input
export default async function multiline(): Promise<string> {
const input = await promptMultilineInput();
// console.log("\nYou entered:\n", input);
return input as string;
}
2 changes: 1 addition & 1 deletion src/rag/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const determinePlugins = async (
.join("\n");

const llmPrompt = `
Given the following user input, conversation context, and available plugins, determine if any plugins should be used. If so, provide the plugin keyword (with @ handle). If no plugins are applicable, respond with "none".
Given the following user input, conversation context, and available plugins, determine if any plugins should be used. If so, provide the plugin keyword (with @ handle) only. If no plugins are applicable, respond with "none".

Available plugins:
${pluginDescriptions}
Expand Down