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
import { trackOpenAiFreeUsage } from "https://esm.town/v/patrickjm/trackOpenAiFreeUsage";
import { openAiTextCompletion } from "https://esm.town/v/patrickjm/openAiTextCompletion";
import { openAiModeration } from "https://esm.town/v/patrickjm/openAiModeration";
import { openAiFreeQuotaExceeded } from "https://esm.town/v/patrickjm/openAiFreeQuotaExceeded";
import { openAiFreeUsageConfig } from "https://esm.town/v/patrickjm/openAiFreeUsageConfig";
/**
* OpenAI text completion. https://platform.openai.com/docs/api-reference/completions
*
* val.town has generously provided a free daily quota. Until the quota is met, no need to provide an API key.
* To see if the quota has been met, you can run @patrickjm.openAiFreeQuotaExceeded()
*
* For full REST API access, see @patrickjm.openAiTextCompletion
*/
export let gpt3 = async (params: {
openAiKey?: string,
prompt: string,
maxTokens?: number,
}) => {
const MODEL = "text-davinci-003";
// Determine whether to use provided apiKey or free usage apiKey based on daily quota.
const apiKey = params.openAiKey ?? openAiFreeUsageConfig.key;
const exceeded = await openAiFreeQuotaExceeded();
if (!params.openAiKey && exceeded) {
throw new Error(openAiFreeUsageConfig.quota_error);
}
// If using free token, first check inputs against moderation api
if (!params.openAiKey) {
const moderation = await openAiModeration({
apiKey,
input: params.prompt,
});
if (moderation.results.some((r) => r.flagged)) {
throw new Error(
"Sorry, this prompt was flagged by OpenAI moderation. If you provide your own API key, moderation will be turned off."
);
}
}
// Call completion API
const response = await openAiTextCompletion({
apiKey: apiKey,
prompt: params.prompt,
model: MODEL,
max_tokens: params.maxTokens ?? 1000,
});
// If using free token, track usage against the quota.