mirror of
https://github.com/Routstr/routstrd.git
synced 2026-10-05 20:38:22 +00:00
Merge branch 'feat/models-pubkey-env'
This commit is contained in:
@@ -69,17 +69,30 @@ function repairConfigPermissions(): void {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Environment-variable overrides take precedence over config.json so operators
|
||||
* can set values via Cloudron/docker env (e.g. ROUTSTRD_MODELS_PUBKEY) without
|
||||
* hand-editing the config file.
|
||||
*/
|
||||
function envConfigOverrides(): Partial<RoutstrdConfig> {
|
||||
const overrides: Partial<RoutstrdConfig> = {};
|
||||
if (process.env.ROUTSTRD_MODELS_PUBKEY) {
|
||||
overrides.routstrModelsPubkey = process.env.ROUTSTRD_MODELS_PUBKEY;
|
||||
}
|
||||
return overrides;
|
||||
}
|
||||
|
||||
export async function loadDaemonConfig(): Promise<RoutstrdConfig> {
|
||||
try {
|
||||
if (existsSync(CONFIG_FILE)) {
|
||||
repairConfigPermissions();
|
||||
const content = await Bun.file(CONFIG_FILE).text();
|
||||
return { ...DEFAULT_CONFIG, ...JSON.parse(content) };
|
||||
return { ...DEFAULT_CONFIG, ...JSON.parse(content), ...envConfigOverrides() };
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error("Failed to load config:", error);
|
||||
}
|
||||
return DEFAULT_CONFIG;
|
||||
return { ...DEFAULT_CONFIG, ...envConfigOverrides() };
|
||||
}
|
||||
|
||||
export function loadDaemonConfigSync(): RoutstrdConfig {
|
||||
@@ -87,12 +100,12 @@ export function loadDaemonConfigSync(): RoutstrdConfig {
|
||||
if (existsSync(CONFIG_FILE)) {
|
||||
repairConfigPermissions();
|
||||
const content = readFileSync(CONFIG_FILE, "utf-8");
|
||||
return { ...DEFAULT_CONFIG, ...JSON.parse(content) };
|
||||
return { ...DEFAULT_CONFIG, ...JSON.parse(content), ...envConfigOverrides() };
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error("Failed to load config:", error);
|
||||
}
|
||||
return DEFAULT_CONFIG;
|
||||
return { ...DEFAULT_CONFIG, ...envConfigOverrides() };
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+27
-1
@@ -8,7 +8,10 @@ import { callDaemon, getDaemonBaseUrl } from "../utils/daemon-client";
|
||||
type PiModelEntry = {
|
||||
id: string;
|
||||
contextWindow?: number;
|
||||
// Preserve arbitrary manual fields (reasoning, thinkingLevelMap, compat, cost, maxTokens, etc.)
|
||||
name?: string;
|
||||
input?: string[];
|
||||
maxTokens?: number;
|
||||
// Preserve arbitrary manual fields (reasoning, thinkingLevelMap, compat, cost, etc.)
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
@@ -75,8 +78,31 @@ export async function installPiIntegration(
|
||||
const entry: PiModelEntry = previous ? { ...previous } : { id: model.id };
|
||||
|
||||
entry.id = model.id;
|
||||
|
||||
if (model.context_length !== undefined && model.context_length > 0) {
|
||||
entry.contextWindow = model.context_length;
|
||||
} else {
|
||||
delete entry.contextWindow;
|
||||
}
|
||||
|
||||
if (model.name) {
|
||||
entry.name = model.name;
|
||||
} else {
|
||||
delete entry.name;
|
||||
}
|
||||
|
||||
// Map the daemon's input modalities to Pi's ["text", "image"] vocabulary.
|
||||
const mods = model.architecture?.input_modalities ?? [];
|
||||
const input: string[] = [];
|
||||
if (mods.includes("text")) input.push("text");
|
||||
if (mods.includes("image")) input.push("image");
|
||||
entry.input = input;
|
||||
|
||||
const maxTokens = model.top_provider?.max_completion_tokens;
|
||||
if (maxTokens !== undefined && maxTokens !== null && maxTokens > 0) {
|
||||
entry.maxTokens = maxTokens;
|
||||
} else {
|
||||
delete entry.maxTokens;
|
||||
}
|
||||
|
||||
return entry;
|
||||
|
||||
@@ -18,6 +18,15 @@ export type RoutstrModel = {
|
||||
id: string;
|
||||
name?: string;
|
||||
context_length?: number;
|
||||
architecture?: {
|
||||
modality?: string;
|
||||
input_modalities?: string[];
|
||||
output_modalities?: string[];
|
||||
};
|
||||
top_provider?: {
|
||||
context_length?: number;
|
||||
max_completion_tokens?: number;
|
||||
};
|
||||
};
|
||||
|
||||
export type IntegrationFn = (
|
||||
|
||||
Reference in New Issue
Block a user