-
Notifications
You must be signed in to change notification settings - Fork 0
/
cligpt.ts
139 lines (114 loc) · 4.18 KB
/
cligpt.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import { OpenAI } from "https://deno.land/x/openai/mod.ts";
import {
bold,
cyan,
green,
red,
yellow,
} from "https://deno.land/std/fmt/colors.ts";
import { TerminalSpinner } from "https://deno.land/x/spinners/mod.ts";
import { config } from "https://deno.land/x/dotenv/mod.ts";
interface Message {
role: "user" | "assistant";
content: string;
}
const openaiApiKeyFromEnv = Deno.env.get("OPENAI_API_KEY");
const modelVersionFromEnv = Deno.env.get("MODEL_VERSION");
const { OPENAI_API_KEY, MODEL_VERSION } = {
OPENAI_API_KEY: openaiApiKeyFromEnv || config().OPENAI_API_KEY,
MODEL_VERSION: modelVersionFromEnv || config().MODEL_VERSION,
};
if (!OPENAI_API_KEY) {
console.error(red(bold("Error: ")) + "Missing OpenAI key.");
Deno.exit(1);
}
const openai = new OpenAI(OPENAI_API_KEY);
const args = Deno.args;
if (args.length === 0) {
console.log(cyan(bold("Usage: ")) + "chatgpt [options] [prompt]");
Deno.exit(0);
}
const historyFile = `${Deno.env.get("HOME")}/.conversation_history.json`;
function displayHelp() {
console.log(cyan(bold("Usage: ")) + "cligpt [options] [prompt]");
console.log("\n" + cyan(bold("Options:")));
console.log(" -c, --clear-history Clear conversation history");
console.log(" -l, --list-history List conversation history");
console.log(" -h, --help Show help information");
}
async function updateConversationHistory(newMessage: Message): Promise<Message[]> {
let conversationHistory = [];
try {
const historyJson = await Deno.readTextFile(historyFile);
conversationHistory = JSON.parse(historyJson);
} catch (error) {
if (error instanceof Deno.errors.NotFound) {
await Deno.writeTextFile(historyFile, JSON.stringify(conversationHistory));
} else {
console.error(red(bold("Error: ")) + "Failed to read conversation history.");
Deno.exit(1);
}
}
conversationHistory.push(newMessage);
await Deno.writeTextFile(historyFile, JSON.stringify(conversationHistory));
return conversationHistory;
}
async function clearConversationHistory(): Promise<void> {
await Deno.writeTextFile(historyFile, JSON.stringify([]));
}
async function readConversationHistory(): Promise<Message[]> {
let conversationHistory = [];
try {
const historyJson = await Deno.readTextFile(historyFile);
conversationHistory = JSON.parse(historyJson);
} catch (error) {
if (error instanceof Deno.errors.NotFound) {
await Deno.writeTextFile(historyFile, JSON.stringify(conversationHistory));
} else {
console.error(red(bold("Error: ")) + "Failed to read conversation history.");
Deno.exit(1);
}
}
return conversationHistory;
}
function printConversationHistory(conversationHistory: Message[]): void {
conversationHistory.forEach((message) => {
const role = message.role === "user" ? cyan(bold("User: ")) : green(bold("Assistant: "));
console.log(role + message.content);
});
}
if (args.includes("--help") || args.includes("-h")) {
displayHelp();
Deno.exit(0);
}
// Check for the --clear-history option and its shorthand
if (args.includes("--clear-history") || args.includes("-c")) {
await clearConversationHistory();
console.log(yellow(bold("Info: ")) + "Conversation history cleared.");
Deno.exit(0);
}
// Check for the --show-history option and its shorthand
if (args.includes("--list-history") || args.includes("-l")) {
const conversationHistory = await readConversationHistory();
printConversationHistory(conversationHistory);
Deno.exit(0);
}
const prompt = args.join(" ");
const terminalSpinner = new TerminalSpinner("Please wait...");
terminalSpinner.start();
try {
const userMessage = { role: "user", content: prompt };
const conversationHistory = await updateConversationHistory(userMessage);
const response = await openai.createChatCompletion({
model: MODEL_VERSION,
messages: conversationHistory,
});
const assistantMessage = response.choices[0].message.content.trim();
await updateConversationHistory({ role: "assistant", content: assistantMessage });
terminalSpinner.stop();
console.log(green(bold("Response: ")) + assistantMessage);
} catch (error) {
terminalSpinner.stop();
console.error(red(bold("Error: ")) + error.message);
Deno.exit(1);
}