llmrouter: Namen 42i/marvin-2609:*, Durchreiche unbekannter Namen an LiteLLM
Caddy zeigt llm.lan künftig auf den Router; alles Unbekannte (2608, role/*) geht unverändert mit dem Client-Key an LiteLLM :4000. Umstellung je Agent = Modellname, kein base_url-Wechsel (Andreas 2026-09-05). altnamen entfällt, bis LiteLLM abgeschaltet wird. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -30,9 +30,16 @@ Zwei Arten:
|
|||||||
Embeddings, kira auf deizo). Optional ein `body`-Patch, etwa
|
Embeddings, kira auf deizo). Optional ein `body`-Patch, etwa
|
||||||
`chat_template_kwargs.enable_thinking` für die Qwen-Stufen.
|
`chat_template_kwargs.enable_thinking` für die Qwen-Stufen.
|
||||||
|
|
||||||
`altnamen` übersetzt die LiteLLM-Namen (`42i/marvin-2608:low` …), damit kein
|
Die Namen sind versioniert wie bei LiteLLM: `42i/marvin-2609:low` … `:max`,
|
||||||
Container angefasst werden muss; geloggt wird der neue Name. Abbauen, sobald
|
`42i/marvin-2609-core:none|medium`. **Unbekannte Namen** (alles aus der
|
||||||
die Clients umgestellt sind.
|
LiteLLM-Zeit, `42i/marvin-2608:*`) reicht der Router unverändert mit dem
|
||||||
|
Client-Key an LiteLLM auf :4000 durch (`fallback`). Caddy zeigt `llm.lan`
|
||||||
|
auf den Router; ein Agent wechselt also per Modellname 2608 → 2609, nicht
|
||||||
|
per base_url, und rollt per Umbenennen zurück. Durchgereichte Anfragen stehen
|
||||||
|
im Log mit Upstream `litellm`, ohne Kosten (die kennt nur LiteLLM).
|
||||||
|
|
||||||
|
Wird LiteLLM abgeschaltet, entfällt `fallback`, und `altnamen` (Übersetzung
|
||||||
|
2608 → 2609) übernimmt, damit auch Nachzügler nicht brechen.
|
||||||
|
|
||||||
## Auflösung und Takt
|
## Auflösung und Takt
|
||||||
|
|
||||||
@@ -81,8 +88,8 @@ PORT=4010 KEYS_FILE=/srv/llmrouter/keys.json ADMIN_KEY=… OPENROUTER_API_KEY=
|
|||||||
bun run build # dist/llmrouter, ein statisches Linux-Binary
|
bun run build # dist/llmrouter, ein statisches Linux-Binary
|
||||||
```
|
```
|
||||||
|
|
||||||
Parallelbetrieb neben LiteLLM (Port 4000) im LXC 185020 auf Port 4010; die
|
Parallelbetrieb neben LiteLLM (Port 4000) im LXC 185020 auf Port 4010; Caddy
|
||||||
Umschaltung ist ein Wechsel der `base_url` in den Client-Configs.
|
zeigt `llm.lan` auf 4010, die Umschaltung je Agent ist der Modellname.
|
||||||
|
|
||||||
Bedient: `/v1/chat/completions`, `/v1/completions`, `/v1/responses`,
|
Bedient: `/v1/chat/completions`, `/v1/completions`, `/v1/responses`,
|
||||||
`/v1/embeddings`, `/v1/audio/speech`, `/v1/audio/transcriptions`,
|
`/v1/embeddings`, `/v1/audio/speech`, `/v1/audio/transcriptions`,
|
||||||
|
|||||||
+16
-26
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"_doku": "Versionierte Quelle des llmrouter. Secrets kommen NUR aus der Umgebung: OPENROUTER_API_KEY, MISTRAL_API_KEY, KIRA_REASONING_KEY, KIRA_STT_KEY, ARTIFICIALANALYSIS_API_KEY, ADMIN_KEY; Client-Keys aus KEYS_FILE (token -> name), Rechte aus key-acls.json (name -> aliasse). Port 4010, weil 4001 im LXC von nginx belegt ist. MODEL_BLOCKLIST zeigt auf die Sperrliste (Host: /srv/llmrouter/model-blocklist.json).",
|
"_doku": "Versionierte Quelle des llmrouter. Secrets kommen NUR aus der Umgebung: OPENROUTER_API_KEY, MISTRAL_API_KEY, KIRA_REASONING_KEY, KIRA_STT_KEY, ARTIFICIALANALYSIS_API_KEY, ADMIN_KEY; Client-Keys aus KEYS_FILE (token -> name), Rechte aus key-acls.json (name -> aliasse). Port 4010 (4001 im LXC von nginx belegt); Caddy zeigt llm.lan auf 4010, LiteLLM bleibt auf 4000 und bekommt alles, was hier unbekannt ist (fallback). MODEL_BLOCKLIST zeigt auf die Sperrliste (Host: /srv/llmrouter/model-blocklist.json).",
|
||||||
"port": 4010,
|
"port": 4010,
|
||||||
"logDir": "./log",
|
"logDir": "./log",
|
||||||
"refreshHours": 12,
|
"refreshHours": 12,
|
||||||
@@ -31,25 +31,29 @@
|
|||||||
"kira-stt": {
|
"kira-stt": {
|
||||||
"base": "http://10.6.42.111:8001/v1",
|
"base": "http://10.6.42.111:8001/v1",
|
||||||
"keyEnv": "KIRA_STT_KEY"
|
"keyEnv": "KIRA_STT_KEY"
|
||||||
|
},
|
||||||
|
"litellm": {
|
||||||
|
"base": "http://127.0.0.1:4000/v1",
|
||||||
|
"clientKey": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"aliases": {
|
"aliases": {
|
||||||
"marvin:low": {
|
"42i/marvin-2609:low": {
|
||||||
"art": "schwelle",
|
"art": "schwelle",
|
||||||
"index": 25,
|
"index": 25,
|
||||||
"minContext": 256000
|
"minContext": 256000
|
||||||
},
|
},
|
||||||
"marvin:medium": {
|
"42i/marvin-2609:medium": {
|
||||||
"art": "schwelle",
|
"art": "schwelle",
|
||||||
"index": 45,
|
"index": 45,
|
||||||
"minContext": 256000
|
"minContext": 256000
|
||||||
},
|
},
|
||||||
"marvin:high": {
|
"42i/marvin-2609:high": {
|
||||||
"art": "schwelle",
|
"art": "schwelle",
|
||||||
"index": 49,
|
"index": 49,
|
||||||
"minContext": 500000
|
"minContext": 500000
|
||||||
},
|
},
|
||||||
"marvin:max": {
|
"42i/marvin-2609:max": {
|
||||||
"art": "schwelle",
|
"art": "schwelle",
|
||||||
"index": 53,
|
"index": 53,
|
||||||
"minContext": 500000
|
"minContext": 500000
|
||||||
@@ -59,7 +63,7 @@
|
|||||||
"upstream": "openrouter",
|
"upstream": "openrouter",
|
||||||
"model": "openrouter/free"
|
"model": "openrouter/free"
|
||||||
},
|
},
|
||||||
"marvin-core:none": {
|
"42i/marvin-2609-core:none": {
|
||||||
"art": "fest",
|
"art": "fest",
|
||||||
"upstream": "qwen",
|
"upstream": "qwen",
|
||||||
"model": "qwen36:35b",
|
"model": "qwen36:35b",
|
||||||
@@ -69,7 +73,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"marvin-core:medium": {
|
"42i/marvin-2609-core:medium": {
|
||||||
"art": "fest",
|
"art": "fest",
|
||||||
"upstream": "qwen",
|
"upstream": "qwen",
|
||||||
"model": "qwen36:35b",
|
"model": "qwen36:35b",
|
||||||
@@ -120,23 +124,9 @@
|
|||||||
"model": "mistralai/mistral-embed-2312"
|
"model": "mistralai/mistral-embed-2312"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"_altnamen_doku": "Übergangs-Aliasse aus der LiteLLM-Zeit, damit kein Container angefasst werden muss. Loggen unter dem NEUEN Namen. Nach und nach abbauen. Stufen 2026-09-05 (Andreas): low=Haiku 4.5, medium=Sonnet 5, high=Opus 5 medium, max=Fable 5.1 medium; none/extra/ultra/mass abgeschafft.",
|
"_stufen_doku": "Stufen als Index-Schwelle (Artificial-Analysis-Intelligence-Index, 0-100) mit Mindestkontext (Andreas 2026-09-05): low 25/256k, medium 45/256k, high 49/500k, max 53/500k. Die Art \"alternative\" mit Referenzmodell (z.B. anthropic/claude-opus-5:medium) bleibt möglich. Namen versioniert wie bei LiteLLM (2608): 42i/marvin-2609:*.",
|
||||||
"altnamen": {
|
"fallback": {
|
||||||
"42i/marvin-2608": "marvin:low",
|
"upstream": "litellm",
|
||||||
"42i/marvin-2608:none": "marvin:low",
|
"_doku": "Unbekannte Modellnamen (z.B. 42i/marvin-2608:*) gehen unverändert mit dem Client-Key an LiteLLM. Umstellung je Agent = Modellname 2608 -> 2609. Fällt weg, wenn LiteLLM abgeschaltet wird; dann kommen die 2608-Namen als altnamen zurück."
|
||||||
"42i/marvin-2608:low": "marvin:low",
|
}
|
||||||
"42i/marvin-2608:medium": "marvin:medium",
|
|
||||||
"42i/marvin-2608:high": "marvin:high",
|
|
||||||
"42i/marvin-2608:extra": "marvin:high",
|
|
||||||
"42i/marvin-2608:ultra": "marvin:max",
|
|
||||||
"42i/marvin-2608-auto": "marvin:medium",
|
|
||||||
"42i/marvin-2608-mass": "marvin:low",
|
|
||||||
"42i/marvin-2608-mass:none": "marvin:low",
|
|
||||||
"42i/marvin-2608-mass:medium": "marvin:low",
|
|
||||||
"42i/marvin-2608-core:none": "marvin-core:none",
|
|
||||||
"42i/marvin-2608-core:medium": "marvin-core:medium",
|
|
||||||
"marvin-reasoning": "marvin-core:medium",
|
|
||||||
"marvin-core": "marvin-core:none"
|
|
||||||
},
|
|
||||||
"_stufen_doku": "Stufen als Index-Schwelle (Artificial-Analysis-Intelligence-Index, 0-100) mit Mindestkontext (Andreas 2026-09-05): low 25/256k, medium 45/256k, high 49/500k, max 53/500k. Die Art \"alternative\" mit Referenzmodell (z.B. anthropic/claude-opus-5:medium) bleibt möglich."
|
|
||||||
}
|
}
|
||||||
|
|||||||
+32
-32
@@ -1,41 +1,41 @@
|
|||||||
{
|
{
|
||||||
"_note": "Rechte je Client-Key: Name -> erlaubte Aliasse (neue Namen; Altnamen werden vor der Pruefung uebersetzt). [] = alles. Die Token selbst liegen NICHT hier, sondern in KEYS_FILE auf dem Host (token -> name). Abgeleitet aus llmlite/key-acls.json am 2026-09-05: role/* und -auto gestrichen (Andreas), -auto -> :medium. Stand 2026-09-05 abends: Stufen low/medium/high/max; none->low, extra->high, ultra->max, mass->low.",
|
"_note": "Rechte je Client-Key: Name -> erlaubte Aliasse (neue Namen; Altnamen werden vor der Pruefung uebersetzt). [] = alles. Die Token selbst liegen NICHT hier, sondern in KEYS_FILE auf dem Host (token -> name). Abgeleitet aus llmlite/key-acls.json am 2026-09-05: role/* und -auto gestrichen (Andreas), -auto -> :medium. Stand 2026-09-05 abends: Stufen low/medium/high/max; none->low, extra->high, ultra->max, mass->low. Namen ab 2026-09-05: 42i/marvin-2609:*; die Rechte gelten nur fuer Router-Aliasse, unbekannte Namen (2608) reicht der Router an LiteLLM durch, dort gelten dessen ACLs.",
|
||||||
"keys": {
|
"keys": {
|
||||||
"persona-spark": [
|
"persona-spark": [
|
||||||
"marvin:medium",
|
"42i/marvin-2609:medium",
|
||||||
"kira-reasoning",
|
"kira-reasoning",
|
||||||
"kira-stt",
|
"kira-stt",
|
||||||
"marvin-stt",
|
"marvin-stt",
|
||||||
"marvin-tts"
|
"marvin-tts"
|
||||||
],
|
],
|
||||||
"persona-buzz": [
|
"persona-buzz": [
|
||||||
"marvin:medium",
|
"42i/marvin-2609:medium",
|
||||||
"kira-reasoning",
|
"kira-reasoning",
|
||||||
"kira-stt",
|
"kira-stt",
|
||||||
"marvin-stt",
|
"marvin-stt",
|
||||||
"marvin-tts"
|
"marvin-tts"
|
||||||
],
|
],
|
||||||
"persona-jessie": [
|
"persona-jessie": [
|
||||||
"marvin:medium",
|
"42i/marvin-2609:medium",
|
||||||
"kira-reasoning",
|
"kira-reasoning",
|
||||||
"kira-stt",
|
"kira-stt",
|
||||||
"marvin-stt",
|
"marvin-stt",
|
||||||
"marvin-tts"
|
"marvin-tts"
|
||||||
],
|
],
|
||||||
"persona-klara": [
|
"persona-klara": [
|
||||||
"marvin:medium",
|
"42i/marvin-2609:medium",
|
||||||
"kira-reasoning",
|
"kira-reasoning",
|
||||||
"kira-stt",
|
"kira-stt",
|
||||||
"marvin-stt",
|
"marvin-stt",
|
||||||
"marvin-tts"
|
"marvin-tts"
|
||||||
],
|
],
|
||||||
"persona-elton": [
|
"persona-elton": [
|
||||||
"marvin:low",
|
"42i/marvin-2609:low",
|
||||||
"marvin:medium",
|
"42i/marvin-2609:medium",
|
||||||
"marvin:high",
|
"42i/marvin-2609:high",
|
||||||
"marvin:max",
|
"42i/marvin-2609:max",
|
||||||
"marvin-core:none",
|
"42i/marvin-2609-core:none",
|
||||||
"marvin-core:medium",
|
"42i/marvin-2609-core:medium",
|
||||||
"kira-reasoning",
|
"kira-reasoning",
|
||||||
"kira-stt",
|
"kira-stt",
|
||||||
"marvin-stt",
|
"marvin-stt",
|
||||||
@@ -44,24 +44,24 @@
|
|||||||
"marvin-tts-turbo"
|
"marvin-tts-turbo"
|
||||||
],
|
],
|
||||||
"persona-festus": [
|
"persona-festus": [
|
||||||
"marvin-core:none",
|
"42i/marvin-2609-core:none",
|
||||||
"marvin-core:medium",
|
"42i/marvin-2609-core:medium",
|
||||||
"marvin:medium",
|
"42i/marvin-2609:medium",
|
||||||
"kira-reasoning",
|
"kira-reasoning",
|
||||||
"kira-stt"
|
"kira-stt"
|
||||||
],
|
],
|
||||||
"persona-aria": [
|
"persona-aria": [
|
||||||
"marvin-core:none",
|
"42i/marvin-2609-core:none",
|
||||||
"marvin-core:medium",
|
"42i/marvin-2609-core:medium",
|
||||||
"marvin:medium",
|
"42i/marvin-2609:medium",
|
||||||
"kira-reasoning",
|
"kira-reasoning",
|
||||||
"kira-stt"
|
"kira-stt"
|
||||||
],
|
],
|
||||||
"persona-inka": [
|
"persona-inka": [
|
||||||
"marvin-core:none",
|
"42i/marvin-2609-core:none",
|
||||||
"marvin-core:medium",
|
"42i/marvin-2609-core:medium",
|
||||||
"marvin:low",
|
"42i/marvin-2609:low",
|
||||||
"marvin:medium",
|
"42i/marvin-2609:medium",
|
||||||
"kira-reasoning",
|
"kira-reasoning",
|
||||||
"kira-stt",
|
"kira-stt",
|
||||||
"marvin-stt",
|
"marvin-stt",
|
||||||
@@ -70,10 +70,10 @@
|
|||||||
"marvin-tts-turbo"
|
"marvin-tts-turbo"
|
||||||
],
|
],
|
||||||
"persona-inka-mx": [
|
"persona-inka-mx": [
|
||||||
"marvin-core:none",
|
"42i/marvin-2609-core:none",
|
||||||
"marvin-core:medium",
|
"42i/marvin-2609-core:medium",
|
||||||
"marvin:low",
|
"42i/marvin-2609:low",
|
||||||
"marvin:medium",
|
"42i/marvin-2609:medium",
|
||||||
"kira-reasoning",
|
"kira-reasoning",
|
||||||
"kira-stt",
|
"kira-stt",
|
||||||
"marvin-stt",
|
"marvin-stt",
|
||||||
@@ -83,8 +83,8 @@
|
|||||||
],
|
],
|
||||||
"persona-andreas": [],
|
"persona-andreas": [],
|
||||||
"nightjob": [
|
"nightjob": [
|
||||||
"marvin-core:none",
|
"42i/marvin-2609-core:none",
|
||||||
"marvin:medium",
|
"42i/marvin-2609:medium",
|
||||||
"kira-reasoning",
|
"kira-reasoning",
|
||||||
"kira-stt",
|
"kira-stt",
|
||||||
"marvin-embedding",
|
"marvin-embedding",
|
||||||
@@ -95,15 +95,15 @@
|
|||||||
"marvin-tts-turbo"
|
"marvin-tts-turbo"
|
||||||
],
|
],
|
||||||
"lab-xo": [
|
"lab-xo": [
|
||||||
"marvin:low",
|
"42i/marvin-2609:low",
|
||||||
"marvin:high",
|
"42i/marvin-2609:high",
|
||||||
"marvin:medium",
|
"42i/marvin-2609:medium",
|
||||||
"kira-reasoning",
|
"kira-reasoning",
|
||||||
"kira-stt"
|
"kira-stt"
|
||||||
],
|
],
|
||||||
"team-copilot": [
|
"team-copilot": [
|
||||||
"marvin:low",
|
"42i/marvin-2609:low",
|
||||||
"marvin:medium",
|
"42i/marvin-2609:medium",
|
||||||
"kira-reasoning",
|
"kira-reasoning",
|
||||||
"kira-stt"
|
"kira-stt"
|
||||||
]
|
]
|
||||||
|
|||||||
+6
-3
@@ -10,7 +10,7 @@
|
|||||||
import { readFileSync } from "fs";
|
import { readFileSync } from "fs";
|
||||||
import { dirname, resolve } from "path";
|
import { dirname, resolve } from "path";
|
||||||
|
|
||||||
export type Upstream = { base: string; keyEnv?: string; maxParallel?: number };
|
export type Upstream = { base: string; keyEnv?: string; maxParallel?: number; /** Client-Token unveraendert weitergeben (Durchreiche an LiteLLM) */ clientKey?: boolean };
|
||||||
export type Alias =
|
export type Alias =
|
||||||
| { art: "alternative"; referenz: string }
|
| { art: "alternative"; referenz: string }
|
||||||
| { art: "schwelle"; index: number; minContext: number }
|
| { art: "schwelle"; index: number; minContext: number }
|
||||||
@@ -23,7 +23,9 @@ export type Config = {
|
|||||||
lasttest: boolean;
|
lasttest: boolean;
|
||||||
upstreams: Record<string, Upstream>;
|
upstreams: Record<string, Upstream>;
|
||||||
aliases: Record<string, Alias>;
|
aliases: Record<string, Alias>;
|
||||||
altnamen: Record<string, string>;
|
altnamen?: Record<string, string>;
|
||||||
|
/** Unbekannte Modellnamen unveraendert an diesen Upstream (Parallelbetrieb mit LiteLLM). */
|
||||||
|
fallback?: { upstream: string };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const BASE = resolve(dirname(import.meta.path), "..");
|
export const BASE = resolve(dirname(import.meta.path), "..");
|
||||||
@@ -34,7 +36,8 @@ export function configLaden(): Config {
|
|||||||
for (const [name, a] of Object.entries(c.aliases)) {
|
for (const [name, a] of Object.entries(c.aliases)) {
|
||||||
if (a.art === "fest" && c.upstreams[a.upstream] === undefined) throw new Error(`Alias ${name}: Upstream ${a.upstream} fehlt`);
|
if (a.art === "fest" && c.upstreams[a.upstream] === undefined) throw new Error(`Alias ${name}: Upstream ${a.upstream} fehlt`);
|
||||||
}
|
}
|
||||||
for (const [alt, ziel] of Object.entries(c.altnamen)) {
|
if (c.fallback !== undefined && c.upstreams[c.fallback.upstream] === undefined) throw new Error(`fallback: Upstream ${c.fallback.upstream} fehlt`);
|
||||||
|
for (const [alt, ziel] of Object.entries(c.altnamen ?? {})) {
|
||||||
if (c.aliases[ziel] === undefined) throw new Error(`Altname ${alt} zeigt auf unbekannten Alias ${ziel}`);
|
if (c.aliases[ziel] === undefined) throw new Error(`Altname ${alt} zeigt auf unbekannten Alias ${ziel}`);
|
||||||
}
|
}
|
||||||
c.logDir = resolve(dirname(CONFIG_PATH), c.logDir);
|
c.logDir = resolve(dirname(CONFIG_PATH), c.logDir);
|
||||||
|
|||||||
+14
-4
@@ -53,9 +53,18 @@ async function belegen(name: string, u: Upstream): Promise<() => void> {
|
|||||||
// --- Aufloesung Alias -> Ziel ------------------------------------------------
|
// --- Aufloesung Alias -> Ziel ------------------------------------------------
|
||||||
type Ziel = { alias: string; upstreamName: string; upstream: Upstream; model: string; effort: string | null; body?: Record<string, unknown>; alternative: boolean };
|
type Ziel = { alias: string; upstreamName: string; upstream: Upstream; model: string; effort: string | null; body?: Record<string, unknown>; alternative: boolean };
|
||||||
function zielBestimmen(angefragt: string, keyName: string): Ziel | { fehler: string; status: number } {
|
function zielBestimmen(angefragt: string, keyName: string): Ziel | { fehler: string; status: number } {
|
||||||
const alias = config.altnamen[angefragt] ?? angefragt;
|
const alias = config.altnamen?.[angefragt] ?? angefragt;
|
||||||
const def = config.aliases[alias];
|
const def = config.aliases[alias];
|
||||||
if (def === undefined) return { fehler: `Unbekanntes Modell ${angefragt}`, status: 404 };
|
if (def === undefined) {
|
||||||
|
// Durchreiche: unbekannter Name geht unveraendert an LiteLLM, mit dem
|
||||||
|
// Client-Key -- dort gelten dessen ACLs. So wechselt ein Agent per
|
||||||
|
// Modellname (2608 -> 2609), nicht per base_url.
|
||||||
|
if (config.fallback !== undefined) {
|
||||||
|
const name = config.fallback.upstream;
|
||||||
|
return { alias: `(durchreiche)`, upstreamName: name, upstream: config.upstreams[name], model: angefragt, effort: null, alternative: false };
|
||||||
|
}
|
||||||
|
return { fehler: `Unbekanntes Modell ${angefragt}`, status: 404 };
|
||||||
|
}
|
||||||
const erlaubt = acl.get(keyName) ?? [];
|
const erlaubt = acl.get(keyName) ?? [];
|
||||||
if (erlaubt.length > 0 && !erlaubt.includes(alias)) return { fehler: `${keyName} darf ${alias} nicht rufen`, status: 403 };
|
if (erlaubt.length > 0 && !erlaubt.includes(alias)) return { fehler: `${keyName} darf ${alias} nicht rufen`, status: 403 };
|
||||||
if (def.art === "fest") {
|
if (def.art === "fest") {
|
||||||
@@ -126,7 +135,7 @@ Bun.serve({
|
|||||||
if ("fehler" in z) return Response.json({ error: { message: z.fehler } }, { status: z.status });
|
if ("fehler" in z) return Response.json({ error: { message: z.fehler } }, { status: z.status });
|
||||||
ziel = z;
|
ziel = z;
|
||||||
stream = orig.stream === true;
|
stream = orig.stream === true;
|
||||||
upstreamBody = JSON.stringify(jsonBody(orig, ziel));
|
upstreamBody = JSON.stringify(ziel.upstream.clientKey === true ? orig : jsonBody(orig, ziel));
|
||||||
headers.set("content-type", "application/json");
|
headers.set("content-type", "application/json");
|
||||||
} else {
|
} else {
|
||||||
const form = await req.formData();
|
const form = await req.formData();
|
||||||
@@ -134,11 +143,12 @@ Bun.serve({
|
|||||||
const z = zielBestimmen(angefragt, keyName);
|
const z = zielBestimmen(angefragt, keyName);
|
||||||
if ("fehler" in z) return Response.json({ error: { message: z.fehler } }, { status: z.status });
|
if ("fehler" in z) return Response.json({ error: { message: z.fehler } }, { status: z.status });
|
||||||
ziel = z;
|
ziel = z;
|
||||||
form.set("model", ziel.model);
|
if (ziel.upstream.clientKey !== true) form.set("model", ziel.model);
|
||||||
upstreamBody = form;
|
upstreamBody = form;
|
||||||
}
|
}
|
||||||
const k = upstreamKey(ziel.upstream);
|
const k = upstreamKey(ziel.upstream);
|
||||||
if (k !== undefined) headers.set("authorization", `Bearer ${k}`);
|
if (k !== undefined) headers.set("authorization", `Bearer ${k}`);
|
||||||
|
if (ziel.upstream.clientKey === true) headers.set("authorization", `Bearer ${auth}`);
|
||||||
if (ziel.upstreamName === "openrouter") { headers.set("http-referer", "https://llm.lan"); headers.set("x-title", `llmrouter/${keyName}`); }
|
if (ziel.upstreamName === "openrouter") { headers.set("http-referer", "https://llm.lan"); headers.set("x-title", `llmrouter/${keyName}`); }
|
||||||
const accept = req.headers.get("accept"); if (accept) headers.set("accept", accept);
|
const accept = req.headers.get("accept"); if (accept) headers.set("accept", accept);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user