src / config / sources / EnvironmentConfigurationSource.ts
src / config / sources / EnvironmentConfigurationSource.ts
import { ImageProviderRegistry } from "../../image_search/providers/ImageProviderRegistry";
import { ProviderRegistry } from "../../providers/ProviderRegistry";
import { DEFAULT_HTTP_TIMEOUT } from "../Config";
import { IConfigurationSource } from "../IConfigurationSource";
export { DEFAULT_HTTP_TIMEOUT };
export const DEFAULT_COOLDOWN_HOURS = 24.0;
/**
* Configuration source reading environment variables from process.env.
* Supports legacy Python .env environment variable keys.
*/
export class EnvironmentConfigurationSource implements IConfigurationSource {
public getWebDefaultProvider(): string | undefined {
const raw = process.env.WEB_DEFAULT_PROVIDER;
return raw && raw.trim() ? raw.trim().toLowerCase() : undefined;
}
public getWebProviderPriority(): string[] | undefined {
const raw = process.env.ENABLED_PROVIDERS || process.env.WEB_PROVIDER_PRIORITY;
if (!raw || !raw.trim()) {
return undefined;
}
const tokens = raw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
if (tokens.length === 0) return undefined;
// Support numeric IDs (e.g. '3,1,2,4') mapped via ProviderRegistry
const mapped: string[] = [];
for (const token of tokens) {
const num = Number.parseInt(token, 10);
if (!Number.isNaN(num)) {
const spec = ProviderRegistry.get_by_id(num);
if (spec) {
mapped.push(spec.name);
continue;
}
}
mapped.push(token.toLowerCase());
}
return mapped.length > 0 ? mapped : undefined;
}
public getProviderKeys(providerName: string, category?: string): string[] | undefined {
const norm = providerName.toLowerCase().trim();
const catUpper = category ? category.toUpperCase() : "";
const envVars: string[] = [];
if (catUpper) {
envVars.push(`${catUpper}_${norm.toUpperCase()}_KEYS`, `${catUpper}_${norm.toUpperCase()}_API_KEY`);
}
const webSpec = ProviderRegistry.getSpec(norm);
if (webSpec && webSpec.envVar) {
envVars.push(webSpec.envVar, `${norm.toUpperCase()}_API_KEY`);
}
const imageSpec = ImageProviderRegistry.getSpec(norm);
if (imageSpec && imageSpec.envVar) {
envVars.push(imageSpec.envVar, `${norm.toUpperCase()}_API_KEY`);
}
envVars.push(`${norm.toUpperCase()}_KEYS`, `${norm.toUpperCase()}_API_KEY`);
for (const varName of envVars) {
const val = process.env[varName];
if (val && val.trim()) {
const keys = val.split(",").map((k) => k.trim()).filter((k) => k.length > 0);
if (keys.length > 0) return keys;
}
}
return undefined;
}
public getImageDefaultProvider(): string | undefined {
const raw = process.env.IMAGE_PROVIDER;
return raw && raw.trim() ? raw.trim().toLowerCase() : undefined;
}
public getImageProviderPriority(): string[] | undefined {
const raw = process.env.IMAGE_ENABLED_PROVIDERS || process.env.IMAGE_PROVIDER_PRIORITY;
if (!raw || !raw.trim()) {
return undefined;
}
const tokens = raw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
if (tokens.length === 0) return undefined;
const mapped: string[] = [];
for (const token of tokens) {
const num = Number.parseInt(token, 10);
if (!Number.isNaN(num)) {
const spec = ImageProviderRegistry.get_by_id(num);
if (spec) {
mapped.push(spec.name);
continue;
}
}
mapped.push(token.toLowerCase());
}
return mapped.length > 0 ? mapped : undefined;
}
public getHttpTimeoutSeconds(): number | undefined {
const raw = process.env.HTTP_TIMEOUT;
if (!raw) return undefined;
const parsed = Number.parseFloat(raw);
return !Number.isNaN(parsed) && parsed > 0 ? parsed : undefined;
}
public getQuotaCooldownHours(): number | undefined {
const raw = process.env.QUOTA_COOLDOWN_HOURS;
if (!raw) return undefined;
const parsed = Number.parseFloat(raw);
return !Number.isNaN(parsed) && parsed > 0 ? parsed : undefined;
}
public getSearchMaxSnippetLength(): number | undefined {
const raw = process.env.SEARCH_MAX_SNIPPET_LENGTH;
if (!raw) return undefined;
const parsed = Number.parseInt(raw, 10);
return !Number.isNaN(parsed) && parsed > 0 ? parsed : undefined;
}
public getSearchMaxPayloadCharacters(): number | undefined {
const raw = process.env.SEARCH_MAX_PAYLOAD_CHARACTERS;
if (!raw) return undefined;
const parsed = Number.parseInt(raw, 10);
return !Number.isNaN(parsed) && parsed > 0 ? parsed : undefined;
}
public getPrependTimeContext(): boolean | undefined {
const raw = process.env.PREPEND_TIME_CONTEXT;
if (raw !== undefined && raw.trim() !== "") {
const lower = raw.trim().toLowerCase();
if (lower === "true" || lower === "1") return true;
if (lower === "false" || lower === "0") return false;
}
return undefined;
}
public getPrependSearchImagesContext(): boolean | undefined {
const raw = process.env.PREPEND_SEARCH_IMAGES_CONTEXT;
if (raw !== undefined && raw.trim() !== "") {
const lower = raw.trim().toLowerCase();
if (lower === "true" || lower === "1") return true;
if (lower === "false" || lower === "0") return false;
}
return undefined;
}
public getPrependVisionContext(): boolean | undefined {
const raw = process.env.PREPEND_VISION_CONTEXT;
if (raw !== undefined && raw.trim() !== "") {
const lower = raw.trim().toLowerCase();
if (lower === "true" || lower === "1") return true;
if (lower === "false" || lower === "0") return false;
}
return undefined;
}
public getMaxImageResults(): number | undefined {
const raw = process.env.SEARCH_MAX_IMAGES;
if (!raw || !raw.trim()) return undefined;
const parsed = Number.parseInt(raw.trim(), 10);
return !Number.isNaN(parsed) && parsed > 0 ? parsed : undefined;
}
public getMaxWebResults(): number | undefined {
const raw = process.env.SEARCH_MAX_WEB_RESULTS || process.env.SEARCH_MAX_RESULTS;
if (!raw || !raw.trim()) return undefined;
const parsed = Number.parseInt(raw.trim(), 10);
return !Number.isNaN(parsed) && parsed > 0 ? parsed : undefined;
}
public getReadWebpageChunkSize(): number | undefined {
const raw = process.env.READ_WEBPAGE_CHUNK_SIZE || process.env.READ_WEBPAGE_MAX_LENGTH;
if (!raw || !raw.trim()) return undefined;
const parsed = Number.parseInt(raw.trim(), 10);
return !Number.isNaN(parsed) && parsed > 0 ? parsed : undefined;
}
}
import { ImageProviderRegistry } from "../../image_search/providers/ImageProviderRegistry";
import { ProviderRegistry } from "../../providers/ProviderRegistry";
import { DEFAULT_HTTP_TIMEOUT } from "../Config";
import { IConfigurationSource } from "../IConfigurationSource";
export { DEFAULT_HTTP_TIMEOUT };
export const DEFAULT_COOLDOWN_HOURS = 24.0;
/**
* Configuration source reading environment variables from process.env.
* Supports legacy Python .env environment variable keys.
*/
export class EnvironmentConfigurationSource implements IConfigurationSource {
public getWebDefaultProvider(): string | undefined {
const raw = process.env.WEB_DEFAULT_PROVIDER;
return raw && raw.trim() ? raw.trim().toLowerCase() : undefined;
}
public getWebProviderPriority(): string[] | undefined {
const raw = process.env.ENABLED_PROVIDERS || process.env.WEB_PROVIDER_PRIORITY;
if (!raw || !raw.trim()) {
return undefined;
}
const tokens = raw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
if (tokens.length === 0) return undefined;
// Support numeric IDs (e.g. '3,1,2,4') mapped via ProviderRegistry
const mapped: string[] = [];
for (const token of tokens) {
const num = Number.parseInt(token, 10);
if (!Number.isNaN(num)) {
const spec = ProviderRegistry.get_by_id(num);
if (spec) {
mapped.push(spec.name);
continue;
}
}
mapped.push(token.toLowerCase());
}
return mapped.length > 0 ? mapped : undefined;
}
public getProviderKeys(providerName: string, category?: string): string[] | undefined {
const norm = providerName.toLowerCase().trim();
const catUpper = category ? category.toUpperCase() : "";
const envVars: string[] = [];
if (catUpper) {
envVars.push(`${catUpper}_${norm.toUpperCase()}_KEYS`, `${catUpper}_${norm.toUpperCase()}_API_KEY`);
}
const webSpec = ProviderRegistry.getSpec(norm);
if (webSpec && webSpec.envVar) {
envVars.push(webSpec.envVar, `${norm.toUpperCase()}_API_KEY`);
}
const imageSpec = ImageProviderRegistry.getSpec(norm);
if (imageSpec && imageSpec.envVar) {
envVars.push(imageSpec.envVar, `${norm.toUpperCase()}_API_KEY`);
}
envVars.push(`${norm.toUpperCase()}_KEYS`, `${norm.toUpperCase()}_API_KEY`);
for (const varName of envVars) {
const val = process.env[varName];
if (val && val.trim()) {
const keys = val.split(",").map((k) => k.trim()).filter((k) => k.length > 0);
if (keys.length > 0) return keys;
}
}
return undefined;
}
public getImageDefaultProvider(): string | undefined {
const raw = process.env.IMAGE_PROVIDER;
return raw && raw.trim() ? raw.trim().toLowerCase() : undefined;
}
public getImageProviderPriority(): string[] | undefined {
const raw = process.env.IMAGE_ENABLED_PROVIDERS || process.env.IMAGE_PROVIDER_PRIORITY;
if (!raw || !raw.trim()) {
return undefined;
}
const tokens = raw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
if (tokens.length === 0) return undefined;
const mapped: string[] = [];
for (const token of tokens) {
const num = Number.parseInt(token, 10);
if (!Number.isNaN(num)) {
const spec = ImageProviderRegistry.get_by_id(num);
if (spec) {
mapped.push(spec.name);
continue;
}
}
mapped.push(token.toLowerCase());
}
return mapped.length > 0 ? mapped : undefined;
}
public getHttpTimeoutSeconds(): number | undefined {
const raw = process.env.HTTP_TIMEOUT;
if (!raw) return undefined;
const parsed = Number.parseFloat(raw);
return !Number.isNaN(parsed) && parsed > 0 ? parsed : undefined;
}
public getQuotaCooldownHours(): number | undefined {
const raw = process.env.QUOTA_COOLDOWN_HOURS;
if (!raw) return undefined;
const parsed = Number.parseFloat(raw);
return !Number.isNaN(parsed) && parsed > 0 ? parsed : undefined;
}
public getSearchMaxSnippetLength(): number | undefined {
const raw = process.env.SEARCH_MAX_SNIPPET_LENGTH;
if (!raw) return undefined;
const parsed = Number.parseInt(raw, 10);
return !Number.isNaN(parsed) && parsed > 0 ? parsed : undefined;
}
public getSearchMaxPayloadCharacters(): number | undefined {
const raw = process.env.SEARCH_MAX_PAYLOAD_CHARACTERS;
if (!raw) return undefined;
const parsed = Number.parseInt(raw, 10);
return !Number.isNaN(parsed) && parsed > 0 ? parsed : undefined;
}
public getPrependTimeContext(): boolean | undefined {
const raw = process.env.PREPEND_TIME_CONTEXT;
if (raw !== undefined && raw.trim() !== "") {
const lower = raw.trim().toLowerCase();
if (lower === "true" || lower === "1") return true;
if (lower === "false" || lower === "0") return false;
}
return undefined;
}
public getPrependSearchImagesContext(): boolean | undefined {
const raw = process.env.PREPEND_SEARCH_IMAGES_CONTEXT;
if (raw !== undefined && raw.trim() !== "") {
const lower = raw.trim().toLowerCase();
if (lower === "true" || lower === "1") return true;
if (lower === "false" || lower === "0") return false;
}
return undefined;
}
public getPrependVisionContext(): boolean | undefined {
const raw = process.env.PREPEND_VISION_CONTEXT;
if (raw !== undefined && raw.trim() !== "") {
const lower = raw.trim().toLowerCase();
if (lower === "true" || lower === "1") return true;
if (lower === "false" || lower === "0") return false;
}
return undefined;
}
public getMaxImageResults(): number | undefined {
const raw = process.env.SEARCH_MAX_IMAGES;
if (!raw || !raw.trim()) return undefined;
const parsed = Number.parseInt(raw.trim(), 10);
return !Number.isNaN(parsed) && parsed > 0 ? parsed : undefined;
}
public getMaxWebResults(): number | undefined {
const raw = process.env.SEARCH_MAX_WEB_RESULTS || process.env.SEARCH_MAX_RESULTS;
if (!raw || !raw.trim()) return undefined;
const parsed = Number.parseInt(raw.trim(), 10);
return !Number.isNaN(parsed) && parsed > 0 ? parsed : undefined;
}
public getReadWebpageChunkSize(): number | undefined {
const raw = process.env.READ_WEBPAGE_CHUNK_SIZE || process.env.READ_WEBPAGE_MAX_LENGTH;
if (!raw || !raw.trim()) return undefined;
const parsed = Number.parseInt(raw.trim(), 10);
return !Number.isNaN(parsed) && parsed > 0 ? parsed : undefined;
}
}