mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-22 06:42:19 +03:00
fix(services): separate CLIProxyAPI health and model auth (#11811)
Obrigado! Validado em lote combinado (8 PRs, release/v3.8.51):
- Separação correta de responsabilidades: probe de saúde via `/healthz` público vs. autenticação de `/v1/models` com `settings.cliproxyapi_api_key` dedicada; `MANAGEMENT_PASSWORD` mantida estritamente no plano de gestão do CLIProxyAPI.
- Evidência RED→GREEN documentada e reproduzida: `tests/unit/services/cliproxy-health-model-auth.test.ts` — verde no lote.
- `⚠️ base-red inherited: #11449` reconhecido — não é causado por esta PR.
- Gates estáticos do lote OK.
This commit is contained in:
@@ -20,7 +20,7 @@ export async function getOrInitSupervisor(): Promise<ServiceSupervisor> {
|
||||
tool: TOOL,
|
||||
port: PORT,
|
||||
spawnArgs: () => resolveSpawnArgs(PORT, managementKey),
|
||||
healthUrl: () => `http://127.0.0.1:${PORT}/v1/models`,
|
||||
healthUrl: () => `http://127.0.0.1:${PORT}/healthz`,
|
||||
healthIntervalMs: 5_000,
|
||||
stopTimeoutMs: 15_000,
|
||||
logsBufferBytes: 5_242_880,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { getVersionManagerTool } from "@/lib/db/versionManager";
|
||||
import { getSettings } from "@/lib/db/settings";
|
||||
import { markAllUnavailable } from "@/lib/db/serviceModels";
|
||||
import { resolveDedicatedCliproxyapiApiKey } from "@omniroute/open-sse/handlers/chatCore/cliproxyapiCredentials";
|
||||
import { registerSupervisor, getSupervisor } from "./registry";
|
||||
import { ServiceSupervisor } from "./ServiceSupervisor";
|
||||
import { resolveSpawnArgs as nineRouterSpawnArgs } from "./installers/ninerouter";
|
||||
@@ -8,10 +10,7 @@ import {
|
||||
CLIPROXY_DEFAULT_PORT,
|
||||
} from "./installers/cliproxy";
|
||||
import { resolveSpawnArgs as muxSpawnArgs, MUX_DEFAULT_PORT } from "./installers/mux";
|
||||
import {
|
||||
resolveSpawnArgs as bifrostSpawnArgs,
|
||||
BIFROST_DEFAULT_PORT,
|
||||
} from "./installers/bifrost";
|
||||
import { resolveSpawnArgs as bifrostSpawnArgs, BIFROST_DEFAULT_PORT } from "./installers/bifrost";
|
||||
import { resolveSpawnArgs as darioSpawnArgs, DARIO_DEFAULT_PORT } from "./installers/dario";
|
||||
import { getOrCreateApiKey } from "./apiKey";
|
||||
import { scheduleServiceModelSync, stopServiceModelSync } from "./modelSync";
|
||||
@@ -59,7 +58,7 @@ const SERVICES: ServiceEntry[] = [
|
||||
{
|
||||
tool: "cliproxy",
|
||||
port: CLIPROXY_PORT,
|
||||
healthPath: "/v1/models",
|
||||
healthPath: "/healthz",
|
||||
healthIntervalMs: 5_000,
|
||||
stopTimeoutMs: 15_000,
|
||||
logsBufferBytes: 5_242_880,
|
||||
@@ -128,6 +127,11 @@ export async function bootstrapEmbeddedServices(): Promise<void> {
|
||||
const apiKey = cfg.needsApiKey
|
||||
? await getOrCreateApiKey(cfg.tool).catch(() => "placeholder")
|
||||
: "";
|
||||
// CLIProxyAPI's generated key is management-only; /v1/models uses its dedicated data-plane key.
|
||||
const modelSyncApiKey =
|
||||
cfg.tool === "cliproxy"
|
||||
? (resolveDedicatedCliproxyapiApiKey(await getSettings()) ?? "")
|
||||
: apiKey;
|
||||
|
||||
const supervisor = new ServiceSupervisor({
|
||||
tool: cfg.tool,
|
||||
@@ -148,7 +152,7 @@ export async function bootstrapEmbeddedServices(): Promise<void> {
|
||||
const baseUrl = `http://127.0.0.1:${cfg.port}`;
|
||||
supervisor.on("stateChange", (status: ServiceStatus) => {
|
||||
if (status.state === "running") {
|
||||
scheduleServiceModelSync(cfg.tool, baseUrl, apiKey);
|
||||
scheduleServiceModelSync(cfg.tool, baseUrl, modelSyncApiKey);
|
||||
} else if (status.state === "stopped" || status.state === "error") {
|
||||
stopServiceModelSync(cfg.tool);
|
||||
markAllUnavailable(cfg.tool);
|
||||
|
||||
Reference in New Issue
Block a user