/** * @license * Copyright 2025 Vybestack LLC * SPDX-License-Identifier: Apache-2.0 */ import { useCallback } from 'react'; import { Box, Newline, Text } from 'ink'; import { Colors } from '../colors.js'; import { useKeypress } from '../hooks/useKeypress.js'; interface ProviderInfo { displayName: string; tosUrl: string; privacyUrl: string; keyPoints: string[]; } const PROVIDER_INFO: Record = { openai: { displayName: 'OpenAI', tosUrl: 'https://openai.com/policies/terms-of-use', privacyUrl: 'https://openai.com/policies/privacy-policy', keyPoints: [ 'API data is not used for training by default', '30-day data retention for abuse monitoring', ], }, anthropic: { displayName: 'Anthropic', tosUrl: 'https://www.anthropic.com/legal/terms', privacyUrl: 'https://www.anthropic.com/legal/privacy', keyPoints: [ 'API data is not used for training', 'Data retention for safety and legal compliance only', ], }, fireworks: { displayName: 'Fireworks', tosUrl: 'https://fireworks.ai/terms-of-service', privacyUrl: 'https://fireworks.ai/privacy-policy', keyPoints: [ 'Data used only for service provision', 'No model training on customer data', ], }, openrouter: { displayName: 'OpenRouter', tosUrl: 'https://openrouter.ai/terms', privacyUrl: 'https://openrouter.ai/privacy', keyPoints: [ 'Acts as a proxy to multiple model providers', 'Each underlying model may have additional terms', ], }, local: { displayName: 'Local Model', tosUrl: '', privacyUrl: '', keyPoints: [ 'No data leaves your machine', 'No external terms of service apply', 'You control all data and privacy', ], }, }; const PROVIDER_ALIASES: Record = { 'lm-studio': 'local', lmstudio: 'local', ollama: 'local', llamacpp: 'local', 'llama-cpp': 'local', 'llama.cpp': 'local', }; function getProviderInfo(providerName: string): ProviderInfo | null { const normalizedName = providerName.toLowerCase(); const aliasedName = PROVIDER_ALIASES[normalizedName] ?? normalizedName; return PROVIDER_INFO[aliasedName] ?? null; } function formatProviderName(providerName: string): string { const info = getProviderInfo(providerName); if (info) { return info.displayName; } return providerName.charAt(0).toUpperCase() + providerName.slice(1); } interface LocalProviderContentProps { providerInfo: ProviderInfo | null; } function LocalProviderContent({ providerInfo }: LocalProviderContentProps) { return ( Local models keep all data on your machine. {providerInfo?.keyPoints.map((point, index) => ( {' '}- {point} ))} ); } interface KnownProviderContentProps { providerInfo: ProviderInfo; } function KnownProviderContent({ providerInfo }: KnownProviderContentProps) { return ( [Terms] {providerInfo.tosUrl} [Privacy]{' '} {providerInfo.privacyUrl} Key points: {providerInfo.keyPoints.map((point, index) => ( {' '}- {point} ))} ); } interface UnknownProviderContentProps { displayName: string; } function UnknownProviderContent({ displayName }: UnknownProviderContentProps) { return ( Please refer to {displayName}'s terms of service and privacy policy for information about how your data is handled. ); } interface ProviderContentProps { providerInfo: ProviderInfo | null; isLocal: boolean; displayName: string; } function ProviderContent({ providerInfo, isLocal, displayName, }: ProviderContentProps) { if (isLocal) { return ; } if (providerInfo) { return ; } return ; } interface MultiProviderPrivacyNoticeProps { providerName: string; onExit: () => void; } export const MultiProviderPrivacyNotice = ({ providerName, onExit, }: MultiProviderPrivacyNoticeProps) => { const handleKeypress = useCallback( (key: { name?: string }) => { if (key.name === 'escape') { onExit(); } }, [onExit], ); useKeypress(handleKeypress, { isActive: true }); const providerInfo = getProviderInfo(providerName); const displayName = formatProviderName(providerName); const isLocal = providerInfo?.displayName === 'Local Model' || PROVIDER_ALIASES[providerName.toLowerCase()] === 'local'; return ( LLxprt Code Privacy Notice LLxprt Code does{' '} NOT {' '} collect any telemetry or usage data. All data handling is governed by your chosen AI provider's policies. Active Provider: {displayName} For full provider information, see: docs/tos-privacy.md Press Esc to exit. ); };