From a91f5fd19de50e84a5f53fbd5c28eed6dcf381d3 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 1 Apr 2026 01:03:23 +0000 Subject: [PATCH] Phase 1C: Add centralized configuration with env var support - Create src/config/defaults.ts with DEFAULT_CONFIG and loadConfig() - Support env vars: VCG_VLLM_URL, VCG_VLLM_MODEL, VCG_VLLM_API_KEY, VCG_DEFAULT_PROVIDER, VCG_MAX_CONCURRENCY, VCG_LOG_LEVEL - Config priority: constructor args > env vars > defaults - Add VCGConfig type to types.ts - Export config utilities from public API https://claude.ai/code/session_012cMotoivyjuMwbrnDo6YRg --- src/config/defaults.ts | 96 ++++++++++++++++++++++++++++++++++++++++++ src/config/index.ts | 6 +++ src/index.ts | 9 ++++ src/types.ts | 17 ++++++++ 4 files changed, 128 insertions(+) create mode 100644 src/config/defaults.ts create mode 100644 src/config/index.ts diff --git a/src/config/defaults.ts b/src/config/defaults.ts new file mode 100644 index 0000000..d83167d --- /dev/null +++ b/src/config/defaults.ts @@ -0,0 +1,96 @@ +/** + * @fileoverview Centralized configuration with env-var support. + * + * Config priority: constructor args (overrides) > env vars > defaults. + * + * Supported environment variables: + * - `VCG_VLLM_URL` — vLLM base URL + * - `VCG_VLLM_MODEL` — vLLM model name + * - `VCG_VLLM_API_KEY` — vLLM auth token + * - `VCG_DEFAULT_PROVIDER` — 'vllm' | 'anthropic' | 'openai' + * - `VCG_MAX_CONCURRENCY` — default concurrency limit + * - `VCG_LOG_LEVEL` — 'debug' | 'info' | 'warn' | 'error' | 'silent' + * + * @module @vcg/agent-sdk + */ + +import type { VCGConfig } from '../types.js' + +/** Valid log levels for the SDK. */ +const VALID_LOG_LEVELS = ['debug', 'info', 'warn', 'error', 'silent'] as const + +/** Valid provider names. */ +const VALID_PROVIDERS = ['anthropic', 'openai', 'vllm'] as const + +/** + * Default configuration values used when no override or env var is present. + */ +export const DEFAULT_CONFIG: Readonly = { + defaultProvider: 'anthropic', + maxConcurrency: 5, + logLevel: 'info', +} + +/** + * Build a fully-resolved configuration by merging (in priority order): + * 1. Explicit `overrides` (constructor args) + * 2. Environment variables + * 3. {@link DEFAULT_CONFIG} + * + * Only defined override fields take precedence; `undefined` fields fall through + * to env vars, then to defaults. + */ +export function loadConfig(overrides?: Partial): VCGConfig { + const env = readEnv() + + return { + defaultProvider: overrides?.defaultProvider ?? env.defaultProvider ?? DEFAULT_CONFIG.defaultProvider, + maxConcurrency: overrides?.maxConcurrency ?? env.maxConcurrency ?? DEFAULT_CONFIG.maxConcurrency, + logLevel: overrides?.logLevel ?? env.logLevel ?? DEFAULT_CONFIG.logLevel, + vllm: overrides?.vllm ?? env.vllm, + } +} + +// --------------------------------------------------------------------------- +// Internal: read env vars into a partial config +// --------------------------------------------------------------------------- + +type MutablePartialConfig = { -readonly [K in keyof VCGConfig]?: VCGConfig[K] } + +function readEnv(): MutablePartialConfig { + const result: MutablePartialConfig = {} + + // Provider + const provider = process.env['VCG_DEFAULT_PROVIDER'] + if (provider && (VALID_PROVIDERS as readonly string[]).includes(provider)) { + result.defaultProvider = provider as VCGConfig['defaultProvider'] + } + + // Concurrency + const concurrency = process.env['VCG_MAX_CONCURRENCY'] + if (concurrency) { + const parsed = parseInt(concurrency, 10) + if (!isNaN(parsed) && parsed > 0) { + result.maxConcurrency = parsed + } + } + + // Log level + const logLevel = process.env['VCG_LOG_LEVEL'] + if (logLevel && (VALID_LOG_LEVELS as readonly string[]).includes(logLevel)) { + result.logLevel = logLevel as VCGConfig['logLevel'] + } + + // vLLM + const vllmURL = process.env['VCG_VLLM_URL'] + const vllmModel = process.env['VCG_VLLM_MODEL'] + if (vllmURL && vllmModel) { + result.vllm = { + baseURL: vllmURL, + model: vllmModel, + apiKey: process.env['VCG_VLLM_API_KEY'], + } + } + + return result +} diff --git a/src/config/index.ts b/src/config/index.ts new file mode 100644 index 0000000..d44161b --- /dev/null +++ b/src/config/index.ts @@ -0,0 +1,6 @@ +/** + * @fileoverview Re-exports for the config module. + * @module @vcg/agent-sdk + */ + +export { DEFAULT_CONFIG, loadConfig } from './defaults.js' diff --git a/src/index.ts b/src/index.ts index 98ca209..55dbe91 100644 --- a/src/index.ts +++ b/src/index.ts @@ -110,6 +110,12 @@ export { createAdapter } from './llm/adapter.js' export type { SupportedProvider } from './llm/adapter.js' export { VLLMAdapter } from './llm/vllm.js' +// --------------------------------------------------------------------------- +// Configuration +// --------------------------------------------------------------------------- + +export { DEFAULT_CONFIG, loadConfig } from './config/index.js' + // --------------------------------------------------------------------------- // Memory // --------------------------------------------------------------------------- @@ -170,4 +176,7 @@ export type { // vLLM VLLMConfig, + + // Config + VCGConfig, } from './types.js' diff --git a/src/types.ts b/src/types.ts index 8b150b6..a7b4109 100644 --- a/src/types.ts +++ b/src/types.ts @@ -293,6 +293,23 @@ export interface OrchestratorConfig { // vLLM configuration // --------------------------------------------------------------------------- +/** + * Centralized SDK configuration. + * + * Resolved by {@link loadConfig} using the priority: + * constructor args > env vars > defaults. + */ +export interface VCGConfig { + /** Default LLM provider. */ + readonly defaultProvider: 'anthropic' | 'openai' | 'vllm' + /** Maximum concurrency for agent pools. */ + readonly maxConcurrency: number + /** Logging verbosity. */ + readonly logLevel: 'debug' | 'info' | 'warn' | 'error' | 'silent' + /** vLLM connection settings (populated from env vars or constructor). */ + readonly vllm?: VLLMConfig +} + /** Configuration for connecting to a vLLM inference server. */ export interface VLLMConfig { /** Base URL of the vLLM server (e.g. `'http://localhost:8000/v1'`). */