Sourcegraph Cody
AI Tool
Sourcegraph Cody
Overview
Sourcegraph Cody is an AI coding assistant specialized in codebase understanding. Utilizing the latest LLMs including Claude Sonnet 4 and GPT-4o, it's available for VS Code, JetBrains, and web versions. With industry-leading whole-codebase understanding capabilities, it addresses high security requirements in enterprise environments through SOC2 Type II, GDPR, and CCPA compliance. Its zero data retention and no-training policy completely protects enterprise confidential code.
Details
Sourcegraph Cody is an AI assistant developed based on Sourcegraph's years of code search and analysis technology. The 2024 version enhanced enterprise-level whole-codebase understanding, advanced search and symbol analysis, and administrator permissions and access control features, optimizing it for use in large-scale development organizations. Compared to other AI tools, it stands out with unparalleled accuracy and depth in contextual awareness, dramatically improving development efficiency in complex codebases.
Key Technical Features
- Industry-Leading Codebase Understanding: Deep comprehension of relationships between files, classes, and functions
- Zero Data Retention Policy: No storage, training, or third-party sharing of user code
- End-to-End Encryption: Complete communication encryption for security assurance
- Latest LLM Integration: Support for Claude Sonnet 4, GPT-4o, Gemini Pro, and more
- Enterprise Governance: Detailed access control and administrator functionality
Latest Features (2024-2025 Edition)
- Enhanced Context Engine: Understanding relationships between codebase, documentation, and services
- Advanced Symbol Navigation: High-precision reference analysis for classes, functions, and variables
- Repository-wide Intelligence: Accurate suggestions with whole-project comprehension
- Custom LLM Integration: Support for organization-specific LLM model integration
- Compliance Monitoring: Real-time security and compliance monitoring
Advantages and Disadvantages
Advantages
- Strongest Codebase Understanding: Industry's deepest contextual awareness capabilities
- Complete Privacy Protection: Total code confidentiality through zero data retention
- Enterprise Ready: Comprehensive security with SOC2, GDPR, CCPA compliance
- Flexible LLM Selection: Choice of multiple latest LLMs based on use case
- Advanced Search Functionality: Efficient information search within codebases
- Management Features: Detailed access control and governance at organizational level
Disadvantages
- Enterprise-Focused Features: Limited individual developer features compared to other tools
- Learning Cost: Certain learning required to utilize advanced features effectively
- Pricing: Enterprise features at $15/month more expensive than alternatives
- Setup Complexity: Specialized knowledge required for large organization deployment
- Relatively New Service: Less market track record than GitHub Copilot and others
Reference Links
Code Examples
VS Code Setup
# Install VS Code extension
# 1. Open Extensions (Ctrl+Shift+X)
# 2. Search "Sourcegraph Cody" and install
# 3. Sign in with Sourcegraph account
# 4. Enterprise environments require administrator permission setup
# Command line installation
code --install-extension sourcegraph.cody-ai
JetBrains IDEs Setup
# Setup for IntelliJ IDEA, PyCharm, WebStorm, etc.
# 1. Open Preferences > Plugins
# 2. Search "Sourcegraph Cody" in Marketplace
# 3. Install and restart IDE
# 4. Login with Sourcegraph account
# 5. Verify enterprise settings
Enterprise Environment Initial Configuration
# sourcegraph-config.yaml
# Cody configuration example for enterprise environments
enterprise:
instance_url: "https://sourcegraph.company.com"
access_token: "${SOURCEGRAPH_TOKEN}"
security:
data_retention: "zero_day"
encryption: "end_to_end"
training_opt_out: true
audit_logging: true
permissions:
repository_access:
- "company/main-app"
- "company/api-service"
- "company/shared-libraries"
user_groups:
developers:
read_access: true
chat_enabled: true
autocomplete_enabled: true
senior_developers:
read_access: true
chat_enabled: true
autocomplete_enabled: true
admin_features: true
compliance:
frameworks: ["SOC2", "GDPR", "CCPA", "HIPAA"]
monitoring: true
reporting_enabled: true
Python Codebase Understanding Utilization
# Comprehensive codebase understanding example with Sourcegraph Cody
# High-precision suggestions in complex codebases
import asyncio
import aiohttp
import json
from typing import Dict, List, Optional, Union
from dataclasses import dataclass
from datetime import datetime, timedelta
@dataclass
class UserProfile:
"""User profile data class"""
user_id: str
username: str
email: str
created_at: datetime
last_login: Optional[datetime] = None
preferences: Dict[str, Union[str, bool, int]] = None
class DatabaseManager:
"""Class managing database connections and operations"""
def __init__(self, connection_string: str, pool_size: int = 10):
# Cody understands entire codebase and suggests appropriate initialization patterns
self.connection_string = connection_string
self.pool_size = pool_size
self.connection_pool = None
self.logger = self._setup_logging()
async def initialize_pool(self):
"""Initialize connection pool"""
# Cody understands existing DB configuration patterns and suggests
try:
import asyncpg
self.connection_pool = await asyncpg.create_pool(
self.connection_string,
min_size=1,
max_size=self.pool_size,
command_timeout=60,
server_settings={
'jit': 'off' # Performance optimization
}
)
self.logger.info("Database connection pool initialized")
except Exception as e:
self.logger.error(f"Failed to initialize connection pool: {e}")
raise
async def get_user_profile(self, user_id: str) -> Optional[UserProfile]:
"""Retrieve user profile"""
# Cody understands application-wide UserProfile usage patterns
if not self.connection_pool:
await self.initialize_pool()
async with self.connection_pool.acquire() as connection:
try:
query = """
SELECT user_id, username, email, created_at, last_login, preferences
FROM user_profiles
WHERE user_id = $1 AND active = true
"""
row = await connection.fetchrow(query, user_id)
if not row:
return None
# Cody suggests dataclass initialization patterns
return UserProfile(
user_id=row['user_id'],
username=row['username'],
email=row['email'],
created_at=row['created_at'],
last_login=row['last_login'],
preferences=json.loads(row['preferences']) if row['preferences'] else {}
)
except Exception as e:
self.logger.error(f"Error fetching user profile {user_id}: {e}")
return None
async def update_user_preferences(self, user_id: str, preferences: Dict) -> bool:
"""Update user preferences"""
# Cody learns and suggests existing update patterns
if not self.connection_pool:
await self.initialize_pool()
async with self.connection_pool.acquire() as connection:
try:
# Safe update within transaction
async with connection.transaction():
# Get current preferences
current_prefs = await connection.fetchval(
"SELECT preferences FROM user_profiles WHERE user_id = $1",
user_id
)
if current_prefs:
current_prefs = json.loads(current_prefs)
current_prefs.update(preferences)
else:
current_prefs = preferences
# Execute update
await connection.execute(
"""
UPDATE user_profiles
SET preferences = $2, updated_at = CURRENT_TIMESTAMP
WHERE user_id = $1
""",
user_id, json.dumps(current_prefs)
)
# Record audit log
await self._log_user_action(connection, user_id, "preferences_updated", preferences)
return True
except Exception as e:
self.logger.error(f"Error updating preferences for {user_id}: {e}")
return False
class NotificationService:
"""Notification service class"""
def __init__(self, db_manager: DatabaseManager):
# Cody understands dependency injection patterns
self.db_manager = db_manager
self.notification_channels = {
'email': self._send_email,
'push': self._send_push_notification,
'sms': self._send_sms
}
async def send_user_notification(self, user_id: str, message: str,
channels: List[str] = None) -> Dict[str, bool]:
"""Send notification to user"""
# Cody suggests notification logic based on user settings
user_profile = await self.db_manager.get_user_profile(user_id)
if not user_profile:
return {"error": "User not found"}
# Determine notification channels from user settings
if channels is None:
channels = user_profile.preferences.get('notification_channels', ['email'])
results = {}
# Send notification through each channel
for channel in channels:
if channel in self.notification_channels:
try:
success = await self.notification_channels[channel](user_profile, message)
results[channel] = success
except Exception as e:
self.logger.error(f"Failed to send {channel} notification to {user_id}: {e}")
results[channel] = False
else:
results[channel] = False
return results
async def _send_email(self, user_profile: UserProfile, message: str) -> bool:
"""Send email (private method)"""
# Cody learns email sending patterns from organization's libraries
try:
# Cody suggests organization-specific email library usage patterns
from company_libs.email import EmailSender
email_sender = EmailSender(
smtp_host=self.config['smtp_host'],
smtp_port=self.config['smtp_port'],
use_tls=True
)
await email_sender.send_async(
to_email=user_profile.email,
subject="Notification",
body=message,
template_name="default_notification"
)
return True
except Exception as e:
self.logger.error(f"Email sending failed: {e}")
return False
class APIController:
"""REST API controller"""
def __init__(self, db_manager: DatabaseManager, notification_service: NotificationService):
# Cody learns existing controller patterns
self.db_manager = db_manager
self.notification_service = notification_service
async def handle_user_settings_update(self, request_data: Dict) -> Dict:
"""User settings update API endpoint"""
# Cody suggests validation, authentication, response patterns
try:
# Request validation
user_id = request_data.get('user_id')
preferences = request_data.get('preferences', {})
if not user_id:
return {
"status": "error",
"message": "user_id is required",
"code": 400
}
# Execute settings update
success = await self.db_manager.update_user_preferences(user_id, preferences)
if success:
# Send update notification
await self.notification_service.send_user_notification(
user_id,
"Settings updated successfully",
channels=['email']
)
return {
"status": "success",
"message": "Preferences updated successfully",
"code": 200
}
else:
return {
"status": "error",
"message": "Failed to update preferences",
"code": 500
}
except Exception as e:
self.logger.error(f"Settings update error: {e}")
return {
"status": "error",
"message": "Internal server error",
"code": 500
}
# Usage example and testing
async def main():
"""Main execution function"""
# Cody understands application-wide initialization patterns
db_manager = DatabaseManager("postgresql://user:pass@localhost/mydb")
await db_manager.initialize_pool()
notification_service = NotificationService(db_manager)
api_controller = APIController(db_manager, notification_service)
# Execute with test data
test_request = {
"user_id": "user123",
"preferences": {
"notification_channels": ["email", "push"],
"language": "en",
"theme": "dark"
}
}
result = await api_controller.handle_user_settings_update(test_request)
print(f"Update result: {result}")
if __name__ == "__main__":
asyncio.run(main())
TypeScript Cross-Project Understanding
// TypeScript project Cody utilization example
// Deep understanding of relationships between multiple files and modules
// types/user.ts
export interface User {
id: string;
username: string;
email: string;
profile: UserProfile;
permissions: Permission[];
createdAt: Date;
updatedAt: Date;
}
export interface UserProfile {
firstName: string;
lastName: string;
avatar?: string;
bio?: string;
preferences: UserPreferences;
}
export interface UserPreferences {
theme: 'light' | 'dark' | 'auto';
language: string;
notifications: NotificationSettings;
privacy: PrivacySettings;
}
export interface Permission {
resource: string;
actions: string[];
conditions?: Record<string, any>;
}
// services/UserService.ts
import { User, UserProfile, UserPreferences } from '../types/user';
import { DatabaseService } from './DatabaseService';
import { CacheService } from './CacheService';
import { NotificationService } from './NotificationService';
export class UserService {
constructor(
private db: DatabaseService,
private cache: CacheService,
private notifications: NotificationService
) {}
async getUserById(userId: string): Promise<User | null> {
// Cody understands existing caching patterns and suggests
const cacheKey = `user:${userId}`;
// Check cache
let user = await this.cache.get<User>(cacheKey);
if (!user) {
// Retrieve from database
user = await this.db.users.findById(userId, {
include: ['profile', 'permissions']
});
if (user) {
// Save to cache (TTL: 1 hour)
await this.cache.set(cacheKey, user, 3600);
}
}
return user;
}
async updateUserPreferences(
userId: string,
preferences: Partial<UserPreferences>
): Promise<{ success: boolean; user?: User; error?: string }> {
try {
// Cody suggests transaction processing patterns
const result = await this.db.transaction(async (trx) => {
// Get current user
const currentUser = await trx.users.findById(userId);
if (!currentUser) {
throw new Error('User not found');
}
// Update preferences
const updatedPreferences = {
...currentUser.profile.preferences,
...preferences
};
// Database update
const updatedUser = await trx.users.update(userId, {
'profile.preferences': updatedPreferences,
updatedAt: new Date()
});
// Record audit log
await trx.auditLogs.create({
userId,
action: 'preferences_updated',
changes: preferences,
timestamp: new Date()
});
return updatedUser;
});
// Invalidate cache
await this.cache.delete(`user:${userId}`);
// Send notification (notify other devices of settings change)
await this.notifications.sendToUser(userId, {
type: 'preferences_updated',
data: preferences
});
return { success: true, user: result };
} catch (error) {
console.error('Failed to update user preferences:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
};
}
}
async getUsersByPermission(permission: string): Promise<User[]> {
// Cody understands permission system relationships and suggests efficient queries
const cacheKey = `users_by_permission:${permission}`;
let users = await this.cache.get<User[]>(cacheKey);
if (!users) {
users = await this.db.users.findMany({
where: {
permissions: {
some: {
resource: permission,
actions: {
hasAny: ['read', 'write', 'admin']
}
}
}
},
include: ['profile', 'permissions']
});
// Short-term cache (permission info may change frequently)
await this.cache.set(cacheKey, users, 300); // 5 minutes
}
return users;
}
}
// controllers/UserController.ts
import { Request, Response } from 'express';
import { UserService } from '../services/UserService';
import { validateUserPreferences } from '../validators/userValidators';
import { AuthMiddleware } from '../middleware/AuthMiddleware';
export class UserController {
constructor(private userService: UserService) {}
async updatePreferences(req: Request, res: Response): Promise<void> {
try {
// Cody understands authentication and authorization patterns
const userId = req.user?.id;
if (!userId) {
res.status(401).json({ error: 'Unauthorized' });
return;
}
// Request validation
const validationResult = validateUserPreferences(req.body);
if (!validationResult.isValid) {
res.status(400).json({
error: 'Invalid preferences data',
details: validationResult.errors
});
return;
}
// Execute settings update
const result = await this.userService.updateUserPreferences(
userId,
req.body
);
if (result.success) {
res.json({
message: 'Preferences updated successfully',
user: result.user
});
} else {
res.status(500).json({
error: 'Failed to update preferences',
details: result.error
});
}
} catch (error) {
console.error('Controller error:', error);
res.status(500).json({ error: 'Internal server error' });
}
}
async getProfile(req: Request, res: Response): Promise<void> {
try {
const userId = req.params.userId || req.user?.id;
if (!userId) {
res.status(400).json({ error: 'User ID required' });
return;
}
// Permission check (own profile or admin permission)
if (userId !== req.user?.id && !req.user?.permissions.includes('admin')) {
res.status(403).json({ error: 'Insufficient permissions' });
return;
}
const user = await this.userService.getUserById(userId);
if (!user) {
res.status(404).json({ error: 'User not found' });
return;
}
// Exclude sensitive information from response
const safeUser = {
id: user.id,
username: user.username,
email: user.email,
profile: user.profile,
// Show permission info only to admins
...(req.user?.permissions.includes('admin') && { permissions: user.permissions })
};
res.json(safeUser);
} catch (error) {
console.error('Get profile error:', error);
res.status(500).json({ error: 'Internal server error' });
}
}
}
React Hooks Component Interaction
// React + TypeScript Cody utilization example
// Deep understanding of state management and side effects between components
import React, { useState, useEffect, useCallback, useContext, createContext } from 'react';
import { User, UserPreferences } from '../types/user';
// Context: User state management
interface UserContextType {
user: User | null;
updatePreferences: (preferences: Partial<UserPreferences>) => Promise<void>;
loading: boolean;
error: string | null;
}
const UserContext = createContext<UserContextType | undefined>(undefined);
// Custom hook: User state management
export const useUser = (): UserContextType => {
const context = useContext(UserContext);
if (!context) {
throw new Error('useUser must be used within UserProvider');
}
return context;
};
// Provider component
export const UserProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
// Cody understands existing API call patterns and suggests
const fetchUser = useCallback(async () => {
try {
setLoading(true);
setError(null);
const response = await fetch('/api/user/profile', {
credentials: 'include',
headers: {
'Content-Type': 'application/json',
}
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const userData = await response.json();
setUser(userData);
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Unknown error';
setError(errorMessage);
console.error('Failed to fetch user:', err);
} finally {
setLoading(false);
}
}, []);
const updatePreferences = useCallback(async (preferences: Partial<UserPreferences>) => {
if (!user) {
throw new Error('No user loaded');
}
try {
setError(null);
const response = await fetch('/api/user/preferences', {
method: 'PUT',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(preferences)
});
if (!response.ok) {
throw new Error(`Failed to update preferences: ${response.status}`);
}
const updatedUser = await response.json();
setUser(updatedUser.user);
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Unknown error';
setError(errorMessage);
throw err;
}
}, [user]);
// Initial user loading
useEffect(() => {
fetchUser();
}, [fetchUser]);
const value: UserContextType = {
user,
updatePreferences,
loading,
error
};
return (
<UserContext.Provider value={value}>
{children}
</UserContext.Provider>
);
};
// Settings component
const UserPreferencesForm: React.FC = () => {
const { user, updatePreferences, loading, error } = useUser();
const [formData, setFormData] = useState<Partial<UserPreferences>>({});
const [saving, setSaving] = useState(false);
// Cody suggests form state management patterns
useEffect(() => {
if (user?.profile.preferences) {
setFormData(user.profile.preferences);
}
}, [user]);
const handleInputChange = useCallback((
field: keyof UserPreferences,
value: any
) => {
setFormData(prev => ({
...prev,
[field]: value
}));
}, []);
const handleSubmit = useCallback(async (e: React.FormEvent) => {
e.preventDefault();
try {
setSaving(true);
await updatePreferences(formData);
// Success notification
console.log('Preferences updated successfully');
} catch (err) {
console.error('Failed to save preferences:', err);
} finally {
setSaving(false);
}
}, [formData, updatePreferences]);
if (loading) {
return <div className="loading">Loading user information...</div>;
}
if (error) {
return <div className="error">Error: {error}</div>;
}
if (!user) {
return <div className="error">User information not found</div>;
}
return (
<form onSubmit={handleSubmit} className="preferences-form">
<h2>Settings</h2>
{/* Theme setting */}
<div className="form-group">
<label htmlFor="theme">Theme</label>
<select
id="theme"
value={formData.theme || 'light'}
onChange={(e) => handleInputChange('theme', e.target.value)}
>
<option value="light">Light</option>
<option value="dark">Dark</option>
<option value="auto">Auto</option>
</select>
</div>
{/* Language setting */}
<div className="form-group">
<label htmlFor="language">Language</label>
<select
id="language"
value={formData.language || 'en'}
onChange={(e) => handleInputChange('language', e.target.value)}
>
<option value="en">English</option>
<option value="ja">日本語</option>
<option value="zh">中文</option>
</select>
</div>
{/* Notification settings */}
<div className="form-group">
<h3>Notification Settings</h3>
<label>
<input
type="checkbox"
checked={formData.notifications?.email || false}
onChange={(e) => handleInputChange('notifications', {
...formData.notifications,
email: e.target.checked
})}
/>
Email notifications
</label>
<label>
<input
type="checkbox"
checked={formData.notifications?.push || false}
onChange={(e) => handleInputChange('notifications', {
...formData.notifications,
push: e.target.checked
})}
/>
Push notifications
</label>
</div>
{/* Save button */}
<button
type="submit"
disabled={saving}
className="save-button"
>
{saving ? 'Saving...' : 'Save Settings'}
</button>
</form>
);
};
// Main application
const App: React.FC = () => {
return (
<UserProvider>
<div className="app">
<header className="app-header">
<h1>User Settings App</h1>
</header>
<main className="app-main">
<UserPreferencesForm />
</main>
</div>
</UserProvider>
);
};
export default App;
Enterprise Configuration and Compliance
{
"sourcegraph_cody": {
"enterprise": {
"instance_url": "https://sourcegraph.company.com",
"authentication": {
"method": "sso",
"provider": "okta",
"auto_refresh": true
},
"repository_access": {
"allowed_repos": [
"company/main-application",
"company/shared-libraries",
"company/api-services"
],
"excluded_paths": [
"*/secrets/*",
"*.env",
"*/config/production/*"
]
}
},
"security": {
"data_retention": "zero_day",
"encryption": {
"in_transit": "tls_1_3",
"at_rest": "aes_256"
},
"audit_logging": {
"enabled": true,
"log_level": "comprehensive",
"retention_days": 90
},
"compliance": {
"frameworks": ["SOC2", "GDPR", "CCPA", "HIPAA"],
"data_processing_agreement": true,
"privacy_shield": true
}
},
"ai_models": {
"default": "claude-sonnet-4",
"alternatives": ["gpt-4o", "gemini-pro"],
"custom_models": {
"enabled": true,
"endpoints": [
{
"name": "company-internal-model",
"url": "https://ai.company.com/v1",
"auth_token": "${INTERNAL_AI_TOKEN}"
}
]
}
},
"permissions": {
"admin_users": [
"[email protected]",
"[email protected]"
],
"feature_access": {
"chat": ["all_users"],
"autocomplete": ["developers", "senior_developers"],
"repository_search": ["senior_developers", "architects"],
"admin_panel": ["admin_users"]
},
"rate_limits": {
"chat_requests_per_hour": 100,
"autocomplete_requests_per_minute": 60,
"search_requests_per_hour": 200
}
},
"monitoring": {
"usage_analytics": true,
"performance_monitoring": true,
"error_reporting": true,
"alerts": {
"high_error_rate": {
"threshold": "5%",
"notification": "[email protected]"
},
"quota_exceeded": {
"threshold": "90%",
"notification": "[email protected]"
}
}
}
}
}