|
1 |
| -import OpenAI from 'openai'; |
2 |
| -import { OpenAIStream, StreamingTextResponse } from 'ai'; |
3 |
| -import { kv } from '@vercel/kv'; |
4 |
| -import { Ratelimit } from '@upstash/ratelimit'; |
5 |
| -import { match } from 'ts-pattern'; |
6 |
| -import type { ChatCompletionMessageParam } from 'openai/resources/index.mjs'; |
| 1 | +import { Ratelimit } from "@upstash/ratelimit"; |
| 2 | +import { kv } from "@vercel/kv"; |
| 3 | +import { OpenAIStream, StreamingTextResponse } from "ai"; |
| 4 | +import OpenAI from "openai"; |
| 5 | +import type { ChatCompletionMessageParam } from "openai/resources/index.mjs"; |
| 6 | +import { match } from "ts-pattern"; |
7 | 7 |
|
8 | 8 | // Create an OpenAI API client (that's edge friendly!)
|
9 |
| -// Using LLamma's OpenAI client: |
10 | 9 |
|
11 | 10 | // IMPORTANT! Set the runtime to edge: https://vercel.com/docs/functions/edge-functions/edge-runtime
|
12 |
| -export const runtime = 'edge'; |
13 |
| - |
14 |
| -const llama = new OpenAI({ |
15 |
| - apiKey: 'ollama', |
16 |
| - baseURL: 'http://localhost:11434/v1', |
17 |
| -}); |
| 11 | +export const runtime = "edge"; |
18 | 12 |
|
19 | 13 | export async function POST(req: Request): Promise<Response> {
|
20 | 14 | const openai = new OpenAI({
|
21 | 15 | apiKey: process.env.OPENAI_API_KEY,
|
22 |
| - baseURL: process.env.OPENAI_BASE_URL || 'https://api.openai.com/v1', |
| 16 | + baseURL: process.env.OPENAI_BASE_URL || "https://api.openai.com/v1", |
23 | 17 | });
|
24 | 18 | // Check if the OPENAI_API_KEY is set, if not return 400
|
25 |
| - if (!process.env.OPENAI_API_KEY || process.env.OPENAI_API_KEY === '') { |
26 |
| - return new Response('Missing OPENAI_API_KEY - make sure to add it to your .env file.', { |
| 19 | + if (!process.env.OPENAI_API_KEY || process.env.OPENAI_API_KEY === "") { |
| 20 | + return new Response("Missing OPENAI_API_KEY - make sure to add it to your .env file.", { |
27 | 21 | status: 400,
|
28 | 22 | });
|
29 | 23 | }
|
30 | 24 | if (process.env.KV_REST_API_URL && process.env.KV_REST_API_TOKEN) {
|
31 |
| - const ip = req.headers.get('x-forwarded-for'); |
| 25 | + const ip = req.headers.get("x-forwarded-for"); |
32 | 26 | const ratelimit = new Ratelimit({
|
33 | 27 | redis: kv,
|
34 |
| - limiter: Ratelimit.slidingWindow(50, '1 d'), |
| 28 | + limiter: Ratelimit.slidingWindow(50, "1 d"), |
35 | 29 | });
|
36 | 30 |
|
37 | 31 | const { success, limit, reset, remaining } = await ratelimit.limit(`novel_ratelimit_${ip}`);
|
38 | 32 |
|
39 | 33 | if (!success) {
|
40 |
| - return new Response('You have reached your request limit for the day.', { |
| 34 | + return new Response("You have reached your request limit for the day.", { |
41 | 35 | status: 429,
|
42 | 36 | headers: {
|
43 |
| - 'X-RateLimit-Limit': limit.toString(), |
44 |
| - 'X-RateLimit-Remaining': remaining.toString(), |
45 |
| - 'X-RateLimit-Reset': reset.toString(), |
| 37 | + "X-RateLimit-Limit": limit.toString(), |
| 38 | + "X-RateLimit-Remaining": remaining.toString(), |
| 39 | + "X-RateLimit-Reset": reset.toString(), |
46 | 40 | },
|
47 | 41 | });
|
48 | 42 | }
|
49 | 43 | }
|
50 | 44 |
|
51 | 45 | const { prompt, option, command } = await req.json();
|
52 | 46 | const messages = match(option)
|
53 |
| - .with('continue', () => [ |
| 47 | + .with("continue", () => [ |
54 | 48 | {
|
55 |
| - role: 'system', |
| 49 | + role: "system", |
56 | 50 | content:
|
57 |
| - 'You are an AI writing assistant that continues existing text based on context from prior text. ' + |
58 |
| - 'Give more weight/priority to the later characters than the beginning ones. ' + |
59 |
| - 'Limit your response to no more than 200 characters, but make sure to construct complete sentences.' + |
60 |
| - 'Use Markdown formatting when appropriate.', |
| 51 | + "You are an AI writing assistant that continues existing text based on context from prior text. " + |
| 52 | + "Give more weight/priority to the later characters than the beginning ones. " + |
| 53 | + "Limit your response to no more than 200 characters, but make sure to construct complete sentences." + |
| 54 | + "Use Markdown formatting when appropriate.", |
61 | 55 | },
|
62 | 56 | {
|
63 |
| - role: 'user', |
| 57 | + role: "user", |
64 | 58 | content: prompt,
|
65 | 59 | },
|
66 | 60 | ])
|
67 |
| - .with('improve', () => [ |
| 61 | + .with("improve", () => [ |
68 | 62 | {
|
69 |
| - role: 'system', |
| 63 | + role: "system", |
70 | 64 | content:
|
71 |
| - 'You are an AI writing assistant that improves existing text. ' + |
72 |
| - 'Limit your response to no more than 200 characters, but make sure to construct complete sentences.' + |
73 |
| - 'Use Markdown formatting when appropriate.', |
| 65 | + "You are an AI writing assistant that improves existing text. " + |
| 66 | + "Limit your response to no more than 200 characters, but make sure to construct complete sentences." + |
| 67 | + "Use Markdown formatting when appropriate.", |
74 | 68 | },
|
75 | 69 | {
|
76 |
| - role: 'user', |
| 70 | + role: "user", |
77 | 71 | content: `The existing text is: ${prompt}`,
|
78 | 72 | },
|
79 | 73 | ])
|
80 |
| - .with('shorter', () => [ |
| 74 | + .with("shorter", () => [ |
81 | 75 | {
|
82 |
| - role: 'system', |
| 76 | + role: "system", |
83 | 77 | content:
|
84 |
| - 'You are an AI writing assistant that shortens existing text. ' + 'Use Markdown formatting when appropriate.', |
| 78 | + "You are an AI writing assistant that shortens existing text. " + "Use Markdown formatting when appropriate.", |
85 | 79 | },
|
86 | 80 | {
|
87 |
| - role: 'user', |
| 81 | + role: "user", |
88 | 82 | content: `The existing text is: ${prompt}`,
|
89 | 83 | },
|
90 | 84 | ])
|
91 |
| - .with('longer', () => [ |
| 85 | + .with("longer", () => [ |
92 | 86 | {
|
93 |
| - role: 'system', |
| 87 | + role: "system", |
94 | 88 | content:
|
95 |
| - 'You are an AI writing assistant that lengthens existing text. ' + |
96 |
| - 'Use Markdown formatting when appropriate.', |
| 89 | + "You are an AI writing assistant that lengthens existing text. " + |
| 90 | + "Use Markdown formatting when appropriate.", |
97 | 91 | },
|
98 | 92 | {
|
99 |
| - role: 'user', |
| 93 | + role: "user", |
100 | 94 | content: `The existing text is: ${prompt}`,
|
101 | 95 | },
|
102 | 96 | ])
|
103 |
| - .with('fix', () => [ |
| 97 | + .with("fix", () => [ |
104 | 98 | {
|
105 |
| - role: 'system', |
| 99 | + role: "system", |
106 | 100 | content:
|
107 |
| - 'You are an AI writing assistant that fixes grammar and spelling errors in existing text. ' + |
108 |
| - 'Limit your response to no more than 200 characters, but make sure to construct complete sentences.' + |
109 |
| - 'Use Markdown formatting when appropriate.', |
| 101 | + "You are an AI writing assistant that fixes grammar and spelling errors in existing text. " + |
| 102 | + "Limit your response to no more than 200 characters, but make sure to construct complete sentences." + |
| 103 | + "Use Markdown formatting when appropriate.", |
110 | 104 | },
|
111 | 105 | {
|
112 |
| - role: 'user', |
| 106 | + role: "user", |
113 | 107 | content: `The existing text is: ${prompt}`,
|
114 | 108 | },
|
115 | 109 | ])
|
116 |
| - .with('zap', () => [ |
| 110 | + .with("zap", () => [ |
117 | 111 | {
|
118 |
| - role: 'system', |
| 112 | + role: "system", |
119 | 113 | content:
|
120 |
| - 'You area an AI writing assistant that generates text based on a prompt. ' + |
121 |
| - 'You take an input from the user and a command for manipulating the text' + |
122 |
| - 'Use Markdown formatting when appropriate.', |
| 114 | + "You area an AI writing assistant that generates text based on a prompt. " + |
| 115 | + "You take an input from the user and a command for manipulating the text" + |
| 116 | + "Use Markdown formatting when appropriate.", |
123 | 117 | },
|
124 | 118 | {
|
125 |
| - role: 'user', |
| 119 | + role: "user", |
126 | 120 | content: `For this text: ${prompt}. You have to respect the command: ${command}`,
|
127 | 121 | },
|
128 | 122 | ])
|
129 | 123 | .run() as ChatCompletionMessageParam[];
|
130 | 124 |
|
131 | 125 | const response = await openai.chat.completions.create({
|
132 |
| - model: 'gpt-3.5-turbo', |
| 126 | + model: "gpt-3.5-turbo", |
133 | 127 | stream: true,
|
134 | 128 | messages,
|
135 | 129 | temperature: 0.7,
|
|
0 commit comments