Repository navigation
Expand file tree
/
Copy pathopenai-auth.js
More file actions
51 lines (44 loc) · 1.55 KB
/
Copy pathopenai-auth.js
File metadata and controls
51 lines (44 loc) · 1.55 KB
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
import { jsonResponse } from "./http.js";
export const OPENAI_KEY_HEADER = "x-sandevistan-openai-key";
const CONTROL_CHARACTERS = /[\u0000-\u001f\u007f]/;
export function validOpenAiKey(value) {
return typeof value === "string"
&& value.startsWith("sk-")
&& value.length >= 20
&& value.length <= 4_096
&& !CONTROL_CHARACTERS.test(value);
}
export function openAiError(code, message, status) {
return jsonResponse(
{ error: { code, message } },
{ status, headers: { "cache-control": "no-store" } },
);
}
export const DEFAULT_OPENAI_MODELS = Object.freeze({
analysis: "gpt-6-luna",
search: "gpt-6.1-sol",
realtime: "gpt-realtime-2.1",
transcription: "gpt-live-transcribe",
refinement: "gpt-transcribe",
});
const MODEL_FAMILIES = {
analysis: /^gpt-(\d+(?:\.\d+)?)-luna$/,
search: /^gpt-(\d+(?:\.\d+)?)-sol$/,
realtime: /^gpt-realtime-(\d+(?:\.\d+)?)$/,
};
export function allowedOpenAiModel(role, model) {
return typeof model === "string" && Boolean(MODEL_FAMILIES[role]?.test(model));
}
export function selectOpenAiModels(ids) {
const models = { ...DEFAULT_OPENAI_MODELS };
for (const [role, pattern] of Object.entries(MODEL_FAMILIES)) {
const candidates = ids.filter((id) => typeof id === "string" && pattern.test(id));
candidates.sort((left, right) => {
const a = left.match(pattern)[1].split(".").map(Number);
const b = right.match(pattern)[1].split(".").map(Number);
return (b[0] - a[0]) || ((b[1] ?? 0) - (a[1] ?? 0));
});
if (candidates[0]) models[role] = candidates[0];
}
return models;
}