quantum-cli-core
Version:
Quantum CLI Core - Multi-LLM Collaboration System
446 lines • 16.4 kB
JavaScript
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { readFileSync, existsSync } from 'fs';
import { join } from 'path';
import { homedir } from 'os';
export const DEFAULT_COLLABORATION_CONFIG = {
enabled: false,
autoVerifyThreshold: 0.7,
showConfidenceScores: false,
maxCostPerQuery: 0.05,
maxProviders: 3,
consensusThreshold: 0.8,
verificationMode: 'smart',
fallbackBehavior: 'primary',
maxLatency: 10000,
parallelExecution: true,
cacheResponses: true,
minConfidenceScore: 0.6,
requireConsensus: false,
diversityBonus: 0.1,
providers: [],
};
export const DEFAULT_PROVIDERS = [
{
id: 'gemini-primary',
name: 'Gemini Pro',
type: 'gemini',
modelName: 'gemini-1.5-pro-002',
maxTokens: 8192,
temperature: 0.1,
capabilities: ['text', 'code', 'reasoning'],
strengths: ['general', 'coding', 'analysis'],
costPerToken: 0.000003,
enabled: true,
},
{
id: 'openai-secondary',
name: 'GPT-4',
type: 'openai',
apiKeyEnvVar: 'OPENAI_API_KEY',
modelName: 'gpt-4',
maxTokens: 8192,
temperature: 0.1,
capabilities: ['text', 'code', 'reasoning'],
strengths: ['general', 'creative', 'reasoning'],
costPerToken: 0.00006,
enabled: false,
},
{
id: 'anthropic-tertiary',
name: 'Claude 3.5 Sonnet',
type: 'anthropic',
apiKeyEnvVar: 'ANTHROPIC_API_KEY',
modelName: 'claude-3-5-sonnet-20241022',
maxTokens: 8192,
temperature: 0.1,
capabilities: ['text', 'code', 'reasoning', 'analysis'],
strengths: ['coding', 'analysis', 'safety'],
costPerToken: 0.000015,
enabled: false,
},
];
/**
* Validates and normalizes collaboration configuration.
* Applies defaults for missing values and validates constraints.
*/
export function validateCollaborationConfig(config) {
const errors = [];
const normalizedConfig = {
...DEFAULT_COLLABORATION_CONFIG,
};
// Merge provided config with defaults
Object.assign(normalizedConfig, config);
// Validate enabled flag
if (typeof normalizedConfig.enabled !== 'boolean') {
normalizedConfig.enabled = DEFAULT_COLLABORATION_CONFIG.enabled;
}
// Validate thresholds (0-1 range)
if (normalizedConfig.autoVerifyThreshold !== undefined) {
if (typeof normalizedConfig.autoVerifyThreshold !== 'number' ||
normalizedConfig.autoVerifyThreshold < 0 ||
normalizedConfig.autoVerifyThreshold > 1) {
errors.push({
field: 'autoVerifyThreshold',
message: 'Must be a number between 0 and 1',
value: normalizedConfig.autoVerifyThreshold,
});
normalizedConfig.autoVerifyThreshold =
DEFAULT_COLLABORATION_CONFIG.autoVerifyThreshold;
}
}
if (normalizedConfig.consensusThreshold !== undefined) {
if (typeof normalizedConfig.consensusThreshold !== 'number' ||
normalizedConfig.consensusThreshold < 0 ||
normalizedConfig.consensusThreshold > 1) {
errors.push({
field: 'consensusThreshold',
message: 'Must be a number between 0 and 1',
value: normalizedConfig.consensusThreshold,
});
normalizedConfig.consensusThreshold =
DEFAULT_COLLABORATION_CONFIG.consensusThreshold;
}
}
if (normalizedConfig.minConfidenceScore !== undefined) {
if (typeof normalizedConfig.minConfidenceScore !== 'number' ||
normalizedConfig.minConfidenceScore < 0 ||
normalizedConfig.minConfidenceScore > 1) {
errors.push({
field: 'minConfidenceScore',
message: 'Must be a number between 0 and 1',
value: normalizedConfig.minConfidenceScore,
});
normalizedConfig.minConfidenceScore =
DEFAULT_COLLABORATION_CONFIG.minConfidenceScore;
}
}
// Validate cost constraints
if (normalizedConfig.maxCostPerQuery !== undefined) {
if (typeof normalizedConfig.maxCostPerQuery !== 'number' ||
normalizedConfig.maxCostPerQuery < 0) {
errors.push({
field: 'maxCostPerQuery',
message: 'Must be a positive number',
value: normalizedConfig.maxCostPerQuery,
});
normalizedConfig.maxCostPerQuery =
DEFAULT_COLLABORATION_CONFIG.maxCostPerQuery;
}
}
// Validate provider limits
if (normalizedConfig.maxProviders !== undefined) {
if (!Number.isInteger(normalizedConfig.maxProviders) ||
normalizedConfig.maxProviders < 1) {
errors.push({
field: 'maxProviders',
message: 'Must be a positive integer',
value: normalizedConfig.maxProviders,
});
normalizedConfig.maxProviders =
DEFAULT_COLLABORATION_CONFIG.maxProviders;
}
}
// Validate latency settings
if (normalizedConfig.maxLatency !== undefined) {
if (!Number.isInteger(normalizedConfig.maxLatency) ||
normalizedConfig.maxLatency < 1000) {
errors.push({
field: 'maxLatency',
message: 'Must be an integer >= 1000 (milliseconds)',
value: normalizedConfig.maxLatency,
});
normalizedConfig.maxLatency = DEFAULT_COLLABORATION_CONFIG.maxLatency;
}
}
// Validate verification mode
if (normalizedConfig.verificationMode !== undefined) {
const validModes = ['automatic', 'manual', 'smart'];
if (!validModes.includes(normalizedConfig.verificationMode)) {
errors.push({
field: 'verificationMode',
message: `Must be one of: ${validModes.join(', ')}`,
value: normalizedConfig.verificationMode,
});
normalizedConfig.verificationMode =
DEFAULT_COLLABORATION_CONFIG.verificationMode;
}
}
// Validate fallback behavior
if (normalizedConfig.fallbackBehavior !== undefined) {
const validBehaviors = ['primary', 'random', 'best'];
if (!validBehaviors.includes(normalizedConfig.fallbackBehavior)) {
errors.push({
field: 'fallbackBehavior',
message: `Must be one of: ${validBehaviors.join(', ')}`,
value: normalizedConfig.fallbackBehavior,
});
normalizedConfig.fallbackBehavior =
DEFAULT_COLLABORATION_CONFIG.fallbackBehavior;
}
}
// Validate providers array
if (normalizedConfig.providers) {
const validatedProviders = [];
const seenIds = new Set();
normalizedConfig.providers.forEach((provider, index) => {
const providerErrors = validateProviderConfig(provider, index);
errors.push(...providerErrors);
// Check for duplicate IDs
if (seenIds.has(provider.id)) {
errors.push({
field: `providers[${index}].id`,
message: 'Provider ID must be unique',
value: provider.id,
});
}
else {
seenIds.add(provider.id);
validatedProviders.push(provider);
}
});
normalizedConfig.providers = validatedProviders;
}
return {
valid: errors.length === 0,
errors,
config: normalizedConfig,
};
}
/**
* Validates a single provider configuration.
*/
function validateProviderConfig(provider, index) {
const errors = [];
// Required fields
if (!provider.id || typeof provider.id !== 'string') {
errors.push({
field: `providers[${index}].id`,
message: 'Provider ID is required and must be a string',
value: provider.id,
});
}
if (!provider.name || typeof provider.name !== 'string') {
errors.push({
field: `providers[${index}].name`,
message: 'Provider name is required and must be a string',
value: provider.name,
});
}
if (!provider.type || typeof provider.type !== 'string') {
errors.push({
field: `providers[${index}].type`,
message: 'Provider type is required and must be a string',
value: provider.type,
});
}
// Optional numeric validations
if (provider.maxTokens !== undefined) {
if (!Number.isInteger(provider.maxTokens) || provider.maxTokens < 1) {
errors.push({
field: `providers[${index}].maxTokens`,
message: 'Must be a positive integer',
value: provider.maxTokens,
});
}
}
if (provider.temperature !== undefined) {
if (typeof provider.temperature !== 'number' ||
provider.temperature < 0 ||
provider.temperature > 2) {
errors.push({
field: `providers[${index}].temperature`,
message: 'Must be a number between 0 and 2',
value: provider.temperature,
});
}
}
if (provider.costPerToken !== undefined) {
if (typeof provider.costPerToken !== 'number' ||
provider.costPerToken < 0) {
errors.push({
field: `providers[${index}].costPerToken`,
message: 'Must be a non-negative number',
value: provider.costPerToken,
});
}
}
return errors;
}
/**
* Loads collaboration configuration from ~/.quantum/collaboration.json file
*/
export function loadCollaborationConfigFromFile() {
const configPath = join(homedir(), '.quantum', 'collaboration.json');
if (!existsSync(configPath)) {
return {};
}
try {
const configContent = readFileSync(configPath, 'utf-8');
const fileConfig = JSON.parse(configContent);
// Validate the loaded configuration
const validationResult = validateCollaborationConfig(fileConfig.collaboration || {});
if (!validationResult.valid) {
console.warn('Invalid collaboration configuration file:', validationResult.errors);
return {};
}
return validationResult.config;
}
catch (error) {
console.warn(`Failed to load collaboration config from ${configPath}:`, error);
return {};
}
}
/**
* Loads collaboration configuration from environment variables
*/
export function loadCollaborationConfigFromEnv() {
const envConfig = {};
// Main collaboration settings
if (process.env.ENABLE_COLLABORATION === 'true') {
envConfig.enabled = true;
}
if (process.env.COLLABORATION_AUTO_VERIFY_THRESHOLD) {
const threshold = parseFloat(process.env.COLLABORATION_AUTO_VERIFY_THRESHOLD);
if (!isNaN(threshold) && threshold >= 0 && threshold <= 1) {
envConfig.autoVerifyThreshold = threshold;
}
}
if (process.env.COLLABORATION_MAX_COST_PER_QUERY) {
const cost = parseFloat(process.env.COLLABORATION_MAX_COST_PER_QUERY);
if (!isNaN(cost) && cost >= 0) {
envConfig.maxCostPerQuery = cost;
}
}
if (process.env.COLLABORATION_VERIFICATION_MODE) {
const mode = process.env.COLLABORATION_VERIFICATION_MODE;
if (['automatic', 'manual', 'smart'].includes(mode)) {
envConfig.verificationMode = mode;
}
}
if (process.env.COLLABORATION_SHOW_CONFIDENCE === 'true') {
envConfig.showConfidenceScores = true;
}
// Provider configuration from environment
const providers = [];
// OpenAI Provider
if (process.env.OPENAI_API_KEY) {
providers.push({
id: 'openai-env',
name: 'OpenAI (Environment)',
type: 'openai',
apiKey: process.env.OPENAI_API_KEY,
modelName: process.env.OPENAI_MODEL || 'gpt-4',
enabled: process.env.OPENAI_ENABLED !== 'false',
temperature: 0.1,
maxTokens: 8192,
capabilities: ['text', 'code', 'reasoning'],
strengths: ['general', 'creative', 'reasoning'],
costPerToken: 0.00006,
});
}
// Anthropic Provider
if (process.env.ANTHROPIC_API_KEY) {
providers.push({
id: 'anthropic-env',
name: 'Anthropic (Environment)',
type: 'anthropic',
apiKey: process.env.ANTHROPIC_API_KEY,
modelName: process.env.ANTHROPIC_MODEL || 'claude-3-5-sonnet-20241022',
enabled: process.env.ANTHROPIC_ENABLED !== 'false',
temperature: 0.1,
maxTokens: 8192,
capabilities: ['text', 'code', 'reasoning', 'analysis'],
strengths: ['coding', 'analysis', 'safety'],
costPerToken: 0.000015,
});
}
if (providers.length > 0) {
envConfig.providers = providers;
}
return envConfig;
}
/**
* Creates an example collaboration configuration file
*/
export function createExampleCollaborationConfig() {
return {
$schema: 'https://quantum-cli.dev/schemas/collaboration.json',
version: '1.0',
collaboration: {
enabled: false,
autoVerifyThreshold: 0.7,
showConfidenceScores: true,
verificationMode: 'smart',
maxCostPerQuery: 0.05,
maxProviders: 3,
consensusThreshold: 0.8,
fallbackBehavior: 'primary',
maxLatency: 10000,
parallelExecution: true,
cacheResponses: true,
minConfidenceScore: 0.6,
requireConsensus: false,
diversityBonus: 0.1,
providers: [],
},
defaultProviders: DEFAULT_PROVIDERS,
};
}
/**
* Writes a default collaboration configuration file to ~/.quantum/collaboration.json
*/
export function writeDefaultCollaborationConfig() {
try {
const configDir = join(homedir(), '.quantum');
const configPath = join(configDir, 'collaboration.json');
// Create directory if it doesn't exist
const { mkdirSync, writeFileSync } = require('fs');
if (!existsSync(configDir)) {
mkdirSync(configDir, { recursive: true });
}
const exampleConfig = createExampleCollaborationConfig();
writeFileSync(configPath, JSON.stringify(exampleConfig, null, 2), 'utf-8');
console.log(`Created default collaboration config at ${configPath}`);
return true;
}
catch (error) {
console.error('Failed to create default collaboration config:', error);
return false;
}
}
/**
* Loads collaboration configuration from all sources with proper precedence.
* Precedence: Environment > File > Defaults
*/
export function loadAllCollaborationConfigs() {
const fileConfig = loadCollaborationConfigFromFile();
const envConfig = loadCollaborationConfigFromEnv();
return mergeCollaborationConfigs(DEFAULT_COLLABORATION_CONFIG, fileConfig, envConfig);
}
/**
* Merges multiple configuration sources with proper precedence.
* Environment variables have higher precedence than file configuration.
*/
export function mergeCollaborationConfigs(...configs) {
const merged = { ...DEFAULT_COLLABORATION_CONFIG };
for (const config of configs) {
if (config.providers && merged.providers) {
// Merge providers instead of replacing
const existingIds = new Set(merged.providers.map((p) => p.id));
const newProviders = config.providers.filter((p) => !existingIds.has(p.id));
merged.providers = [...merged.providers, ...newProviders];
// Apply the rest of the config without providers
const { providers, ...restConfig } = config;
Object.assign(merged, restConfig);
}
else {
Object.assign(merged, config);
}
}
return validateCollaborationConfig(merged).config;
}
//# sourceMappingURL=collaboration-config.js.map