Skip to content

Commit c74380d

Browse files
Merge pull request #96 from warpy-ai/main
Fix package build structure and improve multiline input
2 parents ff0dd6b + f4e447f commit c74380d

File tree

8 files changed

+152
-62
lines changed

8 files changed

+152
-62
lines changed

bun.lockb

0 Bytes
Binary file not shown.

package.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
{
22
"name": "terminalgpt",
3-
"version": "2.0.1",
4-
"main": "lib/index.js",
3+
"version": "2.0.3",
4+
"main": "lib/src/index.js",
55
"description": "Get GPT like chatGPT on your terminal",
66
"scripts": {
7-
"tgpt": "node lib/index.js",
7+
"tgpt": "node lib/src/index.js",
88
"test": "jest --ci --coverage --verbose",
99
"dev": "ts-node src/index.ts chat --temperature 0.7",
1010
"dev:delete": "ts-node src/index.ts delete",
11-
"postinstall": "tsc"
11+
"build": "tsc && chmod +x lib/src/index.js",
12+
"postinstall": "npm run build"
1213
},
1314
"homepage": "https://github.com/jucasoliveira/terminalGPT#readme",
1415
"repository": {
@@ -22,7 +23,7 @@
2223
"url": "https://github.com/jucasoliveira/terminalGPT/issues"
2324
},
2425
"bin": {
25-
"tgpt": "lib/index.js"
26+
"tgpt": "lib/src/index.js"
2627
},
2728
"jest": {
2829
"transform": {

src/index.ts

Lines changed: 102 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { deleteCredentials } from "./creds";
1010
import readline from "readline";
1111
import { findPlugin, executePlugin, initializePlugins } from "./commands";
1212
import determinePlugins from "./rag";
13+
import multiline from "./multiline";
14+
import { clearContext } from "./context";
1315

1416
const program = new Command();
1517

@@ -26,69 +28,120 @@ program
2628
// Initialize plugins
2729
initializePlugins();
2830

29-
const prompt = () => {
31+
const prompt = async () => {
3032
process.stdout.write(chalk.blueBright("\nYou: "));
3133
process.stdin.resume();
3234
process.stdin.setEncoding("utf-8");
33-
process.stdin.once("data", async (data) => {
34-
const userInput = data.toString().trim();
35-
36-
if (creds.apiKey != null) {
37-
try {
38-
// Direct plugin call
39-
const plugin = findPlugin(userInput);
40-
if (plugin) {
41-
console.log(chalk.yellow(`Executing plugin: ${plugin.name}`));
42-
await executePlugin(plugin, {
43-
userInput,
44-
engine: creds.engine,
45-
apiKey: creds.apiKey,
46-
opts: { ...opts, model: creds.model || undefined },
47-
});
48-
} else {
49-
// Use LLM to determine if a plugin should be used
50-
const pluginKeyword = await determinePlugins(
51-
creds.engine,
52-
creds.apiKey,
53-
userInput,
54-
{ ...opts, model: creds.model || undefined }
55-
);
56-
57-
if (pluginKeyword !== "none") {
58-
const plugin = findPlugin(pluginKeyword);
59-
if (plugin) {
60-
console.log(chalk.yellow(`Executing plugin: ${plugin.name}`));
61-
await executePlugin(plugin, {
62-
userInput,
63-
engine: creds.engine,
64-
apiKey: creds.apiKey,
65-
opts: { ...opts, model: creds.model || undefined },
66-
});
67-
} else {
68-
console.log(chalk.red(`Plugin not found: ${pluginKeyword}`));
69-
}
70-
} else {
71-
// No plugin applicable, use regular promptResponse
72-
await promptResponse(creds.engine, creds.apiKey, userInput, {
73-
...opts,
74-
model: creds.model || undefined,
35+
36+
const data = await multiline();
37+
38+
// process.stdin.once("data", async (data) => {
39+
const userInput = data.toString().trim();
40+
41+
if (creds.apiKey != null) {
42+
try {
43+
// Direct plugin call
44+
const plugin = findPlugin(userInput);
45+
if (plugin) {
46+
console.log(chalk.yellow(`Executing plugin: ${plugin.name}`));
47+
await executePlugin(plugin, {
48+
userInput,
49+
engine: creds.engine,
50+
apiKey: creds.apiKey,
51+
opts: { ...opts, model: creds.model || undefined },
52+
});
53+
} else {
54+
// Use LLM to determine if a plugin should be used
55+
const pluginKeyword = await determinePlugins(
56+
creds.engine,
57+
creds.apiKey,
58+
userInput,
59+
{ ...opts, model: creds.model || undefined }
60+
);
61+
clearContext();
62+
if (pluginKeyword.trim() !== "none") {
63+
const plugin = findPlugin(pluginKeyword);
64+
if (plugin) {
65+
console.log(chalk.yellow(`Executing plugin: ${plugin.name}`));
66+
await executePlugin(plugin, {
67+
userInput,
68+
engine: creds.engine,
69+
apiKey: creds.apiKey,
70+
opts: { ...opts, model: creds.model || undefined },
7571
});
72+
} else {
73+
console.log(chalk.red(`Plugin not found: ${pluginKeyword}`));
7674
}
75+
} else {
76+
await promptResponse(creds.engine, creds.apiKey, userInput, {
77+
...opts,
78+
model: creds.model || undefined,
79+
});
7780
}
78-
} catch (error) {
79-
console.error(chalk.red("An error occurred:"), error);
8081
}
81-
} else {
82-
console.log(chalk.red("API key is required for chat functionality."));
82+
} catch (error) {
83+
console.error(chalk.red("An error occurred:"), error);
8384
}
85+
} else {
86+
console.log(chalk.red("API key is required for chat functionality."));
87+
}
8488

85-
prompt();
86-
});
89+
prompt();
90+
// });
8791
};
8892

8993
prompt();
9094
});
9195

96+
program
97+
.command("one-shot <question>")
98+
.description("Ask a one-shot question and get a quick answer")
99+
.option("-e, --engine <engine>", "LLM to use")
100+
.option("-t, --temperature <temperature>", "Response temperature")
101+
.action(async (question, opts) => {
102+
await checkIsLatestVersion();
103+
const creds = await apiKeyPrompt();
104+
105+
if (creds.apiKey != null) {
106+
try {
107+
// Use LLM to determine if a plugin should be used
108+
const pluginKeyword = await determinePlugins(
109+
creds.engine,
110+
creds.apiKey,
111+
question,
112+
{ ...opts, model: creds.model || undefined }
113+
);
114+
115+
if (pluginKeyword.trim() !== "none") {
116+
const plugin = findPlugin(pluginKeyword);
117+
if (plugin) {
118+
console.log(chalk.yellow(`Executing plugin: ${plugin.name}`));
119+
await executePlugin(plugin, {
120+
userInput: question,
121+
engine: creds.engine,
122+
apiKey: creds.apiKey,
123+
opts: { ...opts, model: creds.model || undefined },
124+
});
125+
} else {
126+
console.log(chalk.red(`Plugin not found: ${pluginKeyword}`));
127+
}
128+
} else {
129+
// No plugin applicable, use regular promptResponse
130+
await promptResponse(creds.engine, creds.apiKey, question, {
131+
...opts,
132+
model: creds.model || undefined,
133+
});
134+
}
135+
} catch (error) {
136+
console.error(chalk.red("An error occurred:"), error);
137+
}
138+
} else {
139+
console.log(chalk.red("API key is required for chat functionality."));
140+
}
141+
142+
process.exit(0);
143+
});
144+
92145
program
93146
.command("delete")
94147
.description("Delete your API key")

src/intro.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ export default async function intro() {
7272
"@exit"
7373
)} plugin.
7474
75-
${chalk.greenBright("Start chatting or use a plugin to begin!")}
75+
${chalk.greenBright(
76+
"Start chatting, or use a plugin to begin! Use shift+enter to finish your message, ctrl+c to exit."
77+
)}
7678
`;
7779

7880
console.log(usageText);

src/multiline.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import readline from "readline";
2+
3+
// Function to prompt for multiline input
4+
function promptMultilineInput() {
5+
return new Promise((resolve) => {
6+
let multilineInput = "";
7+
console.log(
8+
"Enter your text (to finish enter an empty line, Ctrl+D to submit, Ctrl+C to exit):\n"
9+
);
10+
11+
const rl = readline.createInterface({
12+
input: process.stdin,
13+
output: process.stdout,
14+
terminal: true,
15+
});
16+
17+
rl.on("line", (line) => {
18+
multilineInput += line + "\n";
19+
});
20+
21+
rl.on("close", () => {
22+
resolve(multilineInput);
23+
});
24+
});
25+
}
26+
27+
// Main function to loop input
28+
export default async function multiline(): Promise<string> {
29+
const input = await promptMultilineInput();
30+
// console.log("\nYou entered:\n", input);
31+
return input as string;
32+
}

src/rag/index.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const determinePlugins = async (
2121
.join("\n");
2222

2323
const llmPrompt = `
24-
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".
24+
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".
2525
2626
Available plugins:
2727
${pluginDescriptions}
@@ -48,10 +48,11 @@ const determinePlugins = async (
4848
const result = matchedPlugin ? matchedPlugin.keyword : "none";
4949

5050
// Add AI response to context
51-
addContext({
52-
role: "assistant",
53-
content: result,
54-
});
51+
result !== "none" &&
52+
addContext({
53+
role: "assistant",
54+
content: result,
55+
});
5556

5657
return result;
5758
};

src/utils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ export const promptResponse = async (
158158
const markedText = marked.parse(text);
159159
for (let i = 0; i < markedText.length; i++) {
160160
process.stdout.write(markedText[i]);
161-
await new Promise((resolve) => setTimeout(resolve, 10));
161+
// increase the speed of the output
162+
await new Promise((resolve) => setTimeout(resolve, 5));
162163
}
163164
} catch (err) {
164165
console.error(`${chalk.red("Something went wrong!!")} ${err}`);

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"resolveJsonModule": true
1313
},
1414
"include": [
15-
"src/*.ts"
15+
"src/**/*.ts"
1616
],
1717
"exclude": [
1818
"node_modules",

0 commit comments

Comments
 (0)