Skip to content

Commit

Permalink
Add support for GPT-4 & better cost estimation
Browse files Browse the repository at this point in the history
  • Loading branch information
alanzchen committed Apr 11, 2023
1 parent 982aaac commit 44172a2
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 14 deletions.
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
}
],
"dependencies": {
"@nem035/gpt-3-encoder": "^1.1.7",
"@raycast/api": "^1.48.5",
"openai": "^3.2.1",
"run-applescript": "^6.1.0"
Expand All @@ -54,6 +55,23 @@
"required": true,
"title": "OpenAI API Key"
},
{
"name": "model",
"description": "OpenAI LLM to use for your commands",
"type": "dropdown",
"data": [
{
"title": "GPT-3.5 Turbo",
"value": "gpt-3.5-turbo"
},
{
"title": "GPT-4",
"value": "gpt-4"
}
],
"required": true,
"title": "OpenAI Model"
},
{
"name": "prompt_summarize",
"title": "Summarize Prompt",
Expand Down
2 changes: 1 addition & 1 deletion src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ const configuration = new Configuration({
apiKey: getPreferenceValues().apikey,
});
export const openai = new OpenAIApi(configuration);
export const model = "gpt-3.5-turbo";
export const model = getPreferenceValues().model;
25 changes: 21 additions & 4 deletions src/common.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export default function ResultView(prompt: string, toast_title: string) {
const [loading, setLoading] = useState(true);
let response_ = "";
const [cumulative_tokens, setCumulativeTokens] = useState(0);
const [cumulative_cost, setCumulativeCost] = useState(0);
const [model_override, setModelOverride] = useState(model);

async function getResult() {
const now = new Date();
Expand All @@ -29,7 +31,7 @@ export default function ResultView(prompt: string, toast_title: string) {
const selectedText = await getSelectedText();
const stream = await openai.createChatCompletion(
{
model: model,
model: model_override,
messages: [
{ role: "system", content: prompt },
{ role: "user", content: selectedText }
Expand Down Expand Up @@ -79,12 +81,23 @@ export default function ResultView(prompt: string, toast_title: string) {
getResult();
}

async function retryWithGPT4() {
setModelOverride("gpt-4");
setLoading(true);
setResponse("");
getResult();
}

useEffect(() => {
getResult();
}, []);

useEffect(() => {
if (loading == false) setCumulativeTokens(cumulative_tokens + prompt_token_count + response_token_count);
if (loading == false) {
setCumulativeTokens(cumulative_tokens + prompt_token_count + response_token_count);
setCumulativeCost(cumulative_cost + estimatePrice(prompt_token_count, response_token_count, model_override));
}

}, [loading]);

let sidenote = undefined;
Expand All @@ -110,24 +123,28 @@ export default function ResultView(prompt: string, toast_title: string) {
<Action.CopyToClipboard title="Copy Results" content={response} />
<Action.Paste title="Paste Results" content={response} />
<Action title="Retry" onAction={retry} shortcut={{ modifiers: ["cmd"], key: "r" }} icon={Icon.Repeat} />
{(
model_override != "gpt-4" && <Action title="Retry with GPT-4" onAction={retryWithGPT4} shortcut={{ modifiers: ["cmd", "shift"], key: "r" }} icon={Icon.ArrowNe} />
)}
{sidenote}
</ActionPanel>
}
metadata={
<Detail.Metadata>
<Detail.Metadata.Label title="Current Model" text={model_override} />
<Detail.Metadata.Label title="Prompt Tokens" text={prompt_token_count.toString()} />
<Detail.Metadata.Label title="Response Tokens" text={response_token_count.toString()} />
<Detail.Metadata.Separator />
<Detail.Metadata.Label title="Total Tokens" text={(prompt_token_count + response_token_count).toString()} />
<Detail.Metadata.Label
title="Total Cost"
text={estimatePrice(prompt_token_count + response_token_count).toString() + " cents"}
text={estimatePrice(prompt_token_count, response_token_count, model_override).toString() + " cents"}
/>
<Detail.Metadata.Separator />
<Detail.Metadata.Label title="Culmulative Tokens" text={cumulative_tokens.toString()} />
<Detail.Metadata.Label
title="Culmulative Cost"
text={estimatePrice(cumulative_tokens).toString() + " cents"}
text={cumulative_cost.toString() + " cents"}
/>
</Detail.Metadata>
}
Expand Down
19 changes: 11 additions & 8 deletions src/util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { closeMainWindow } from "@raycast/api";
import { runAppleScript } from "run-applescript";
import { encode } from "@nem035/gpt-3-encoder";

function escapeStringForAppleScript(str: string) {
return str.replace(/[\\"]/g, "\\$&");
Expand All @@ -21,16 +22,18 @@ function naiveRound(num: number, decimalPlaces = 0) {
}

export function countToken(content: string) {
const word_count = content.split(" ").length;
const char_count = content.length;
const tokens_count_word_est = word_count / 0.75;
const tokens_count_char_est = char_count / 4.0;
const token_est = (tokens_count_word_est + tokens_count_char_est) / 2;
return Math.round(token_est);
return encode(content).length;
}

export function estimatePrice(token_est: number) {
return naiveRound((token_est * 0.002) / 10, 2);
export function estimatePrice(prompt_token: number, output_token: number, model: string) {
// price is per 1K tokens, but we are measuing in cents. Hence the denominator is 10
if (model == "gpt-3.5-turbo") {
return naiveRound((prompt_token + output_token) * 0.002 / 10, 2);
} else if (model == "gpt-4") {
return naiveRound((prompt_token * 0.03 + output_token * 0.06) / 10, 2);
} else {
return -1;
}
}

export async function runAppleScriptSilently(appleScript: string) {
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Node 16",
"include": ["src/**/*"],
"include": ["src/**/*", "encoder.json"],
"compilerOptions": {
"lib": ["es2021"],
"module": "commonjs",
Expand Down

0 comments on commit 44172a2

Please sign in to comment.