rawi
Version:
Rawi (راوي) is the developer-friendly AI CLI that brings the power of 12 major AI providers directly to your terminal. With seamless shell integration, persistent conversations, and 200+ specialized prompt templates, Rawi transforms your command line into
1 lines • 20.7 kB
Source Map (JSON)
{"version":3,"sources":["/home/mkabumattar/withrawi/rawi/dist/chunk-JIQYHHMV.cjs","../src/core/configs/managers/config.manager.ts"],"names":["ConfigManager","BaseConfigManager","InteractiveConfigManager","ProviderConfigManager","ConfigDisplayManager","ConfigValidator","options","chalk","profile","spinnerManager","existingCredentials","provider","resolve"],"mappings":"AAAA;AACA,wDAAwC,wDAAyC,wDAAyC,wDAAyC,wDAAyC,wDAAyC,wDAAkD,4ECDrR,IA0BLA,CAAAA,WAAN,MAAA,QACGC,mBAEV,wMACmB,WAAA,CAAc,IAAIC,oBAAAA,gBAClB,cAAA,CAAiB,IAAIC,oBAAAA,gBACrB,OAAA,CAAU,IAAIC,oBAAAA,gBACd,SAAA,CAAY,IAAIC,oBAAAA,MAE3B,oBAAA,CAAqBC,CAAAA,CAA4B,CAAC,CAAA,CAAkB,CACxE,OAAA,CAAQ,GAAA,CAAIC,eAAAA,CAAM,IAAA,CAAK,IAAA,CAAK,+BAAwB,CAAC,CAAA,CACrD,OAAA,CAAQ,GAAA,CAAIA,eAAAA,CAAM,IAAA,CAAK,kDAAkD,CAAC,CAAA,CAE1E,GAAI,CACF,IAAMC,CAAAA,CAAU,MAAM,IAAA,CAAK,WAAA,CAAY,UAAA,CAAWF,CAAAA,CAAQ,OAAO,CAAA,CAEjEG,mBAAAA,CAAe,KAAA,CAAM,aAAA,CAAe,mCAAmC,CAAA,CACvE,IAAMC,CAAAA,CAAsB,IAAA,CAAK,cAAA,CAAeF,CAAO,CAAA,CAEnDE,CAAAA,CACFD,mBAAAA,CAAe,OAAA,CACb,aAAA,CACA,CAAA,0CAAA,EAA6CD,CAAO,CAAA,CAAA,CACtD,CAAA,CAEAC,mBAAAA,CAAe,OAAA,CACb,aAAA,CACA,oCACF,CAAA,CAGF,GAAI,CACF,IAAME,CAAAA,CAAW,MAAM,IAAA,CAAK,WAAA,CAAY,cAAA,CACtCL,CAAAA,CAAQ,QAAA,kBAAYI,CAAAA,2BAAqB,UAC3C,CAAA,CAEAD,mBAAAA,CAAe,KAAA,CACb,qBAAA,CACA,CAAA,WAAA,EAAcE,CAAQ,CAAA,0BAAA,CACxB,CAAA,CACA,MAAM,IAAI,OAAA,CAASC,CAAAA,EAAY,UAAA,CAAWA,CAAAA,CAAS,GAAG,CAAC,CAAA,CACvDH,mBAAAA,CAAe,OAAA,CACb,qBAAA,CACA,CAAA,EAAA;AAgdqB,SAAA;AAEG,aAAA;AAiCL,gBAAA;AAQ7B,aAAA;AD1jBkjC","file":"/home/mkabumattar/withrawi/rawi/dist/chunk-JIQYHHMV.cjs","sourcesContent":[null,"import chalk from 'chalk';\nimport {\n type AnthropicSettings,\n type AzureSettings,\n type BedrockSettings,\n type CerebrasSettings,\n type ConfigureOptions,\n DEFAULT_LANGUAGE,\n DEFAULT_MAX_TOKENS,\n DEFAULT_TEMPERATURE,\n type DeepSeekSettings,\n type GoogleSettings,\n type MistralSettings,\n type OpenAISettings,\n type QwenSettings,\n type RawiCredentials,\n spinnerManager,\n type XAISettings,\n} from '../../shared/index.js';\nimport type {IInteractiveConfigManager} from '../interfaces/config-manager.interface.js';\nimport {ConfigValidator} from '../validators/config.validator.js';\nimport {BaseConfigManager} from './base.manager.js';\nimport {ConfigDisplayManager} from './display.manager.js';\nimport {InteractiveConfigManager} from './interactive.manager.js';\nimport {ProviderConfigManager} from './provider-config.manager.js';\n\nexport class ConfigManager\n extends BaseConfigManager\n implements IInteractiveConfigManager\n{\n private readonly interactive = new InteractiveConfigManager();\n private readonly providerConfig = new ProviderConfigManager();\n private readonly display = new ConfigDisplayManager();\n private readonly validator = new ConfigValidator();\n\n async interactiveConfigure(options: ConfigureOptions = {}): Promise<void> {\n console.log(chalk.bold.blue('\\\\n🔧 Configuring Rawi'));\n console.log(chalk.gray('Please provide your AI service configuration:\\\\n'));\n\n try {\n const profile = await this.interactive.getProfile(options.profile);\n\n spinnerManager.start('config-load', 'Loading existing configuration...');\n const existingCredentials = this.getCredentials(profile);\n\n if (existingCredentials) {\n spinnerManager.succeed(\n 'config-load',\n `Found existing configuration for profile '${profile}'`,\n );\n } else {\n spinnerManager.succeed(\n 'config-load',\n 'Creating new configuration profile',\n );\n }\n\n try {\n const provider = await this.interactive.selectProvider(\n options.provider || existingCredentials?.provider,\n );\n\n spinnerManager.start(\n 'provider-validation',\n `Validating ${provider} provider configuration...`,\n );\n await new Promise((resolve) => setTimeout(resolve, 500));\n spinnerManager.succeed(\n 'provider-validation',\n `${provider} provider validated`,\n );\n\n const model = await this.interactive.selectModel(\n provider,\n options.model || existingCredentials?.model,\n );\n\n const credentials: RawiCredentials = {\n provider,\n model,\n temperature: await this.interactive.getTemperature(\n options.temperature ??\n existingCredentials?.temperature ??\n DEFAULT_TEMPERATURE,\n ),\n maxTokens: await this.interactive.getMaxTokens(\n options.maxTokens ??\n existingCredentials?.maxTokens ??\n DEFAULT_MAX_TOKENS,\n ),\n language: await this.interactive.getLanguage(\n options.language ??\n existingCredentials?.language ??\n DEFAULT_LANGUAGE,\n ),\n };\n\n await this.configureProviderSettings(\n credentials,\n provider,\n options,\n existingCredentials,\n );\n\n const validation = this.validator.validateCredentials(credentials);\n if (!validation.isValid) {\n this.display.displayError(\n 'Configuration validation failed:',\n validation.errors.join(', '),\n );\n throw new Error('Invalid configuration');\n }\n\n if (validation.warnings.length > 0) {\n for (const warning of validation.warnings) {\n this.display.displayWarning(warning);\n }\n }\n\n this.setCredentials(credentials, profile);\n\n spinnerManager.start('config-save', 'Saving configuration...');\n\n try {\n spinnerManager.succeed(\n 'config-save',\n 'Configuration saved successfully!',\n );\n\n console.log(chalk.gray(`Profile: ${profile}`));\n this.display.displayConfigurationSummary(credentials);\n console.log(chalk.gray(`\\\\nConfig file: ${this.configFile}`));\n\n this.display.displaySuccess('Configuration completed successfully!');\n } catch (error) {\n spinnerManager.fail('config-save', 'Failed to save configuration');\n throw error;\n }\n } catch (error) {\n if (error instanceof Error && error.name === 'ExitPromptError') {\n console.log(\n chalk.yellow('\\\\n👋 Configuration cancelled. Exiting...'),\n );\n return;\n }\n throw error;\n }\n } catch (error) {\n if (error === '') {\n console.log(chalk.yellow('\\\\n❌ Configuration cancelled.'));\n return;\n }\n\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n this.display.displayError('Configuration failed', errorMessage);\n throw error;\n }\n }\n\n private async configureProviderSettings(\n credentials: RawiCredentials,\n provider: string,\n options: ConfigureOptions,\n existingCredentials: RawiCredentials | null,\n ): Promise<void> {\n switch (provider) {\n case 'ollama':\n await this.configureOllama(credentials, options, existingCredentials);\n break;\n case 'lmstudio':\n await this.configureLMStudio(credentials, options, existingCredentials);\n break;\n case 'azure':\n await this.configureAzure(credentials, options, existingCredentials);\n break;\n case 'bedrock':\n await this.configureBedrock(credentials, options, existingCredentials);\n break;\n case 'qwen':\n await this.configureQwen(credentials, options, existingCredentials);\n break;\n case 'xai':\n await this.configureXAI(credentials, options, existingCredentials);\n break;\n case 'deepseek':\n await this.configureDeepSeek(credentials, options, existingCredentials);\n break;\n case 'mistral':\n await this.configureMistral(credentials, options, existingCredentials);\n break;\n case 'cerebras':\n await this.configureCerebras(credentials, options, existingCredentials);\n break;\n case 'openai':\n await this.configureOpenAI(credentials, options, existingCredentials);\n break;\n case 'anthropic':\n await this.configureAnthropic(\n credentials,\n options,\n existingCredentials,\n );\n break;\n case 'google':\n await this.configureGoogle(credentials, options, existingCredentials);\n break;\n default:\n credentials.apiKey = await this.interactive.getApiKey(\n options.apiKey || existingCredentials?.apiKey,\n provider as any,\n );\n break;\n }\n }\n\n private async configureOllama(\n credentials: RawiCredentials,\n options: ConfigureOptions,\n existingCredentials: RawiCredentials | null,\n ): Promise<void> {\n const baseURL = await this.providerConfig.getBaseURL(\n options.baseURL ||\n (existingCredentials?.providerSettings &&\n 'baseURL' in existingCredentials.providerSettings\n ? existingCredentials.providerSettings.baseURL\n : undefined),\n );\n\n if (baseURL) {\n credentials.providerSettings = {baseURL};\n }\n }\n\n private async configureLMStudio(\n credentials: RawiCredentials,\n options: ConfigureOptions,\n existingCredentials: RawiCredentials | null,\n ): Promise<void> {\n const baseURL = await this.providerConfig.getBaseURL(\n options.baseURL ||\n (existingCredentials?.providerSettings &&\n 'baseURL' in existingCredentials.providerSettings\n ? existingCredentials.providerSettings.baseURL\n : undefined),\n );\n\n if (baseURL) {\n credentials.providerSettings = {baseURL};\n }\n }\n\n private async configureAzure(\n credentials: RawiCredentials,\n options: ConfigureOptions,\n existingCredentials: RawiCredentials | null,\n ): Promise<void> {\n const apiKey = await this.interactive.getApiKey(\n options.apiKey || existingCredentials?.apiKey,\n 'azure',\n );\n\n const resourceName = await this.providerConfig.getAPIEndpoint(\n options.resourceName ||\n (existingCredentials?.providerSettings &&\n 'resourceName' in existingCredentials.providerSettings\n ? existingCredentials.providerSettings.resourceName\n : undefined),\n );\n\n credentials.apiKey = apiKey;\n\n if (resourceName) {\n const settings: AzureSettings = {resourceName};\n credentials.providerSettings = settings;\n }\n }\n\n private async configureBedrock(\n credentials: RawiCredentials,\n options: ConfigureOptions,\n existingCredentials: RawiCredentials | null,\n ): Promise<void> {\n const accessKeyId = await this.providerConfig.getAccessKey(\n options.accessKeyId ||\n (existingCredentials?.providerSettings &&\n 'accessKeyId' in existingCredentials.providerSettings\n ? existingCredentials.providerSettings.accessKeyId\n : undefined),\n );\n\n const secretAccessKey = await this.providerConfig.getSecretAccessKey(\n options.secretAccessKey ||\n (existingCredentials?.providerSettings &&\n 'secretAccessKey' in existingCredentials.providerSettings\n ? existingCredentials.providerSettings.secretAccessKey\n : undefined),\n );\n\n const region = await this.providerConfig.getRegion(\n options.region ||\n (existingCredentials?.providerSettings &&\n 'region' in existingCredentials.providerSettings\n ? existingCredentials.providerSettings.region\n : undefined),\n );\n\n const sessionToken = await this.providerConfig.getSessionToken(\n options.sessionToken ||\n (existingCredentials?.providerSettings &&\n 'sessionToken' in existingCredentials.providerSettings\n ? existingCredentials.providerSettings.sessionToken\n : undefined),\n );\n\n const settings: BedrockSettings = {};\n\n if (accessKeyId) settings.accessKeyId = accessKeyId;\n if (secretAccessKey) settings.secretAccessKey = secretAccessKey;\n if (region) settings.region = region;\n if (sessionToken) settings.sessionToken = sessionToken;\n\n credentials.providerSettings = settings;\n }\n\n private async configureQwen(\n credentials: RawiCredentials,\n options: ConfigureOptions,\n existingCredentials: RawiCredentials | null,\n ): Promise<void> {\n const apiKey = await this.interactive.getApiKey(\n options.apiKey || existingCredentials?.apiKey,\n 'qwen',\n );\n\n const settings: QwenSettings = {apiKey};\n credentials.apiKey = apiKey;\n credentials.providerSettings = settings;\n }\n\n private async configureXAI(\n credentials: RawiCredentials,\n options: ConfigureOptions,\n existingCredentials: RawiCredentials | null,\n ): Promise<void> {\n const apiKey = await this.interactive.getApiKey(\n options.apiKey || existingCredentials?.apiKey,\n 'xai',\n );\n\n const settings: XAISettings = {apiKey};\n credentials.apiKey = apiKey;\n credentials.providerSettings = settings;\n }\n\n private async configureDeepSeek(\n credentials: RawiCredentials,\n options: ConfigureOptions,\n existingCredentials: RawiCredentials | null,\n ): Promise<void> {\n const apiKey = await this.interactive.getApiKey(\n options.apiKey || existingCredentials?.apiKey,\n 'deepseek',\n );\n\n const settings: DeepSeekSettings = {apiKey};\n credentials.apiKey = apiKey;\n credentials.providerSettings = settings;\n }\n private async configureMistral(\n credentials: RawiCredentials,\n options: ConfigureOptions,\n existingCredentials: RawiCredentials | null,\n ): Promise<void> {\n // For Mistral, check for API key in provider settings first\n const existingApiKey =\n options.apiKey ||\n (existingCredentials?.providerSettings &&\n 'apiKey' in existingCredentials.providerSettings\n ? existingCredentials.providerSettings.apiKey\n : existingCredentials?.apiKey);\n\n const apiKey = await this.interactive.getApiKey(existingApiKey, 'mistral');\n\n const baseURL = await this.providerConfig.getBaseURL(\n options.baseURL ||\n (existingCredentials?.providerSettings &&\n 'baseURL' in existingCredentials.providerSettings\n ? existingCredentials.providerSettings.baseURL\n : undefined),\n );\n\n const settings: MistralSettings = {apiKey};\n\n if (baseURL) {\n settings.baseURL = baseURL;\n }\n\n // Only store API key in provider settings, not in top-level credentials\n credentials.providerSettings = settings;\n }\n\n private async configureCerebras(\n credentials: RawiCredentials,\n options: ConfigureOptions,\n existingCredentials: RawiCredentials | null,\n ): Promise<void> {\n // For Cerebras, check for API key in provider settings first\n const existingApiKey =\n options.apiKey ||\n (existingCredentials?.providerSettings &&\n 'apiKey' in existingCredentials.providerSettings\n ? existingCredentials.providerSettings.apiKey\n : existingCredentials?.apiKey);\n\n const apiKey = await this.interactive.getApiKey(existingApiKey, 'cerebras');\n\n const baseURL = await this.providerConfig.getBaseURL(\n options.baseURL ||\n (existingCredentials?.providerSettings &&\n 'baseURL' in existingCredentials.providerSettings\n ? existingCredentials.providerSettings.baseURL\n : undefined),\n );\n\n const settings: CerebrasSettings = {apiKey};\n\n if (baseURL) {\n settings.baseURL = baseURL;\n }\n\n // Only store API key in provider settings, not in top-level credentials\n credentials.providerSettings = settings;\n }\n\n private async configureOpenAI(\n credentials: RawiCredentials,\n options: ConfigureOptions,\n existingCredentials: RawiCredentials | null,\n ): Promise<void> {\n const apiKey = await this.interactive.getApiKey(\n options.apiKey || existingCredentials?.apiKey,\n 'openai',\n );\n\n const settings: OpenAISettings = {apiKey};\n credentials.apiKey = apiKey;\n credentials.providerSettings = settings;\n }\n\n private async configureAnthropic(\n credentials: RawiCredentials,\n options: ConfigureOptions,\n existingCredentials: RawiCredentials | null,\n ): Promise<void> {\n const apiKey = await this.interactive.getApiKey(\n options.apiKey || existingCredentials?.apiKey,\n 'anthropic',\n );\n\n const settings: AnthropicSettings = {apiKey};\n credentials.apiKey = apiKey;\n credentials.providerSettings = settings;\n }\n\n private async configureGoogle(\n credentials: RawiCredentials,\n options: ConfigureOptions,\n existingCredentials: RawiCredentials | null,\n ): Promise<void> {\n const apiKey = await this.interactive.getApiKey(\n options.apiKey || existingCredentials?.apiKey,\n 'google',\n );\n\n const baseURL = await this.providerConfig.getAPIEndpoint(\n options.baseURL ||\n (existingCredentials?.providerSettings &&\n 'baseURL' in existingCredentials.providerSettings\n ? existingCredentials.providerSettings.baseURL\n : undefined),\n );\n\n const settings: GoogleSettings = {apiKey};\n\n if (baseURL) {\n settings.baseURL = baseURL;\n }\n\n credentials.apiKey = apiKey;\n credentials.providerSettings = settings;\n }\n\n showConfig(profile?: string, showCredentials = false): void {\n this.showConfiguration(profile, showCredentials).catch((error) => {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n this.display.displayError('Error showing configuration', errorMessage);\n });\n }\n\n async showConfiguration(\n profile?: string,\n _showCredentials = false,\n ): Promise<void> {\n spinnerManager.start('config-show', 'Loading configuration...');\n\n try {\n const config = this.readConfig();\n const profiles = Object.keys(config);\n\n if (profiles.length === 0) {\n spinnerManager.stop('config-show');\n console.log(chalk.yellow('No configuration profiles found.'));\n console.log(\n chalk.gray('Use \"rawi configure\" to create your first profile.'),\n );\n return;\n }\n\n spinnerManager.succeed('config-show', 'Configuration loaded');\n\n if (profile) {\n if (!(profile in config)) {\n console.log(chalk.red(`Profile '${profile}' not found.`));\n console.log(chalk.gray('Available profiles:'));\n this.display.displayProfiles(profiles);\n return;\n }\n\n console.log(chalk.blue(`\\nProfile: ${profile}`));\n this.display.displayCredentials(config[profile]!);\n } else {\n console.log(chalk.blue('\\nAll Profiles:'));\n for (const profileName of profiles) {\n console.log(chalk.white(`\\n• Profile: ${profileName}`));\n this.display.displayCredentials(config[profileName]!);\n }\n }\n } catch (error) {\n spinnerManager.fail('config-show', 'Failed to load configuration');\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n this.display.displayError('Error reading configuration', errorMessage);\n }\n }\n\n manualConfigure(credentials: RawiCredentials, profile = 'default'): void {\n try {\n const validation = this.validator.validateCredentials(credentials);\n if (!validation.isValid) {\n this.display.displayError(\n 'Configuration validation failed:',\n validation.errors.join(', '),\n );\n throw new Error('Invalid configuration');\n }\n\n if (validation.warnings.length > 0) {\n for (const warning of validation.warnings) {\n this.display.displayWarning(warning);\n }\n }\n\n this.setCredentials(credentials, profile);\n this.display.displaySuccess('Configuration saved successfully!');\n console.log(chalk.gray(`Profile: ${profile}`));\n this.display.displayConfigurationSummary(credentials);\n console.log(chalk.gray(`\\nConfig file: ${this.configFile}`));\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n this.display.displayError('Manual configuration failed', errorMessage);\n throw error;\n }\n }\n}\n"]}