-
-
Notifications
You must be signed in to change notification settings - Fork 20
/
proxy.ts
69 lines (60 loc) · 1.87 KB
/
proxy.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
import { Hono } from "@hono/hono";
import { bearerAuth } from "@hono/hono/bearer-auth";
import { assert, is } from "@core/unknownutil";
import { parseURL } from "ufo";
import { chooseEndpoint, convertToCustomEndpoint } from "./util.ts";
export function createApp(
{
openAIEndpoint,
ollamaEndpoint,
OPENAI_API_KEY,
}: {
openAIEndpoint: string;
ollamaEndpoint: string;
OPENAI_API_KEY: string | undefined;
},
) {
const app = new Hono();
// Apply bearer authentication, but skip it for OPTIONS requests
app.use((c, next) => {
if (c.req.method !== "OPTIONS") {
if (is.String(OPENAI_API_KEY)) {
return bearerAuth({ token: OPENAI_API_KEY })(c, next);
}
}
// If the method is OPTIONS, skip the bearerAuth
return next();
});
// Handle POST requests
app.post("*", async (c) => {
const json = await c.req.raw.clone().json();
const { model } = json;
// Validate the request payload
assert(json, is.ObjectOf({ model: is.String }));
const endpoint = chooseEndpoint({
model,
ollamaEndpoint,
openAIEndpoint,
});
const url = convertToCustomEndpoint(c.req.url, parseURL(endpoint));
const req = new Request(url, c.req.raw);
req.headers.set("Host", ollamaEndpoint);
return fetch(req);
});
// Handle GET requests
app.get("*", (c) => {
const url = convertToCustomEndpoint(c.req.url, parseURL(ollamaEndpoint));
const req = new Request(url, c.req.raw);
req.headers.set("Host", ollamaEndpoint);
return fetch(req);
});
// Handle OPTIONS requests
app.options("*", (c) => {
c.header("Allow", "OPTIONS, GET, POST");
c.header("Access-Control-Allow-Origin", "*");
c.header("Access-Control-Allow-Methods", "OPTIONS, GET, POST");
c.header("Access-Control-Allow-Headers", "Content-Type, Authorization");
return c.body(null, 204);
});
return app;
}